// Copyright 2010 Google 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.google.enterprise.connector.spi; import java.sql.PreparedStatement; import java.text.MessageFormat; import java.util.PropertyResourceBundle; import java.util.ResourceBundle; /** * Supplies SQL language syntax variations for the various database * implementations. This mirrors {@code java.util.ResourceBundle} in form * and function, but is designed to supply SQL language translations * rather than spoken language translations. * <p> * Like {@code java.util.PropertyResourceBundle}, {@code DatabaseResourceBundle} * resources are specified in {@code Properties} files. Unlike * {@link PropertyResourceBundle}, {@code DatabaseResourceBundle} uses the * <a href="http://code.google.com/p/eproperties">EProperties</a> * enhanced Properties package, which extends the standard * {@code java.util.Properties} and syntax to include things like: * variable substitution, nesting, inclusion and lists. * For instance: * <ul><li>Variable substitution syntax that mirrors the syntax used in * shell scripts, ant, etc.: * <pre> * table.name = connector_instances * getvalue.query = "SELECT ${column.connector.name} FROM ${table.name} ..." * </pre> * Variables may be defined in the {@code DatabaseResourceBundle} in which they * are used, or any of the ancestor {@code DatabaseResourceBundles} (see below). * Variable substitution is done at the time of the call to * {@link #getString(String)} or {@link #getStringArray(String)}, so the * returned string(s) have all known substitutions resolved.</li> * <li>Lists that may be fetched as an array of Strings - great for potentially * multi-statement DDL. For instance, this table creation DDL resource * definition consists of three distinct SQL statements: * <pre> * create.table.ddl = ( "CREATE TABLE ...", "CREATE TRIGGER ...", "CREATE INDEX ..." ) * </pre> * which can be retrieved using {@link #getStringArray(String)}: * <pre> * String[] ddlStatements = bundle.getStringArray("create.table.ddl"); * </pre> * </li></ul> * <p> * These features allow the connector developer to write very powerful * resource property files. * <p> * Connectors must locate the DatabaseResourceBundle property files in their * {@code config} package. The properties files have a base name derived from * the ConnectorType name (with any instances of '.' replaced with '_') * concatenated with "_sql". * Vendor-specific SQL syntax variations are formed by adding the * product name, major and minor versions to the base name. So resource * property file names would look like: * <pre> * <ConnectorTypeName>_sql[_productName][_majorVersion][_minorVersion].properties * </pre> * For instance, suppose the ConnectorType name as defined in * {@code connectorType.xml} is "File.List", and the configured JDBC * {@code DataSource} is MySQL v5.1. The Connector Manager will attempt to * load {@code DatabaseResourceBundles} from the following resources: * <ol> * <li>config.File_List_sql_mysql_5_1.properties</li> * <li>config.File_List_sql_mysql_5.properties</li> * <li>config.File_List_sql_mysql.properties</li> * <li>config.File_List_sql.properties</li> * </ol> * * Resources are searched in that order, from most specific to least * specific. Variable substitution are also resolved from most specific * to least specific, so {@code File_List_sql_mysql.properties} * may refer to a property defined in {@code File_List_sql.properties}, * but not one defined in {@code File_List_sql_mysql_5_1.properties}. * * @since 2.8 */ public interface DatabaseResourceBundle { /** * Gets a resource that is specific to the active database implementation. * This API is modeled on {@link ResourceBundle#getString(String)} and is * intended to be used in a similar way. That is, it may return a String * (typically, SQL) into which parameter substitution may be done using * {@link MessageFormat#format(Object)}, JDBC {@link PreparedStatement} * and similar techniques. * <p> * The implementation will assure that the correct resource is returned for * this connector type and for the active database implementation. * <p> * If there is no resource defined for this key, {@code null} is returned * (unlike {@link ResourceBundle#getString(String)}, which throws an * exception). * * @param key as {@link ResourceBundle#getString(String)} * @return as {@link ResourceBundle#getString(String)} */ public String getString(String key); /** * The same comments apply as {{@link #getString(String)}, only this * API corresponds to {@link ResourceBundle#getStringArray(String)}. * <p> * If there is no resource defined for this key, an array of length zero is * returned (unlike {@link ResourceBundle#getString(String)}, which throws an * exception). * * @param key as {@link ResourceBundle#getStringArray(String)} * @return as {@link ResourceBundle#getStringArray(String)} */ public String[] getStringArray(String key); }