/***************************************************************** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF 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 org.apache.cayenne.dba; import org.apache.cayenne.CayenneRuntimeException; import org.apache.cayenne.access.DataNode; import org.apache.cayenne.access.translator.ParameterBinding; import org.apache.cayenne.access.translator.ejbql.EJBQLTranslatorFactory; import org.apache.cayenne.access.translator.select.QualifierTranslator; import org.apache.cayenne.access.translator.select.QueryAssembler; import org.apache.cayenne.access.translator.select.SelectTranslator; import org.apache.cayenne.access.types.ExtendedTypeMap; import org.apache.cayenne.di.Provider; import org.apache.cayenne.log.JdbcEventLogger; import org.apache.cayenne.map.DbAttribute; import org.apache.cayenne.map.DbEntity; import org.apache.cayenne.map.DbRelationship; import org.apache.cayenne.map.EntityResolver; import org.apache.cayenne.query.Query; import org.apache.cayenne.query.SQLAction; import org.apache.cayenne.query.SelectQuery; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Collection; /** * A DbAdapter that automatically detects the kind of database it is running on * and instantiates an appropriate DB-specific adapter, delegating all * subsequent method calls to this adapter. * * @since 1.2 */ public class AutoAdapter implements DbAdapter { protected Provider<DbAdapter> adapterProvider; protected PkGenerator pkGenerator; protected JdbcEventLogger logger; /** * The actual adapter that is delegated methods execution. */ volatile DbAdapter adapter; /** * Creates an {@link AutoAdapter} based on a delegate adapter obtained via * "adapterProvider". * * @since 3.1 */ public AutoAdapter(Provider<DbAdapter> adapterProvider, JdbcEventLogger logger) { if (adapterProvider == null) { throw new CayenneRuntimeException("Null adapterProvider"); } this.adapterProvider = adapterProvider; this.logger = logger; } /** * Returns a proxied DbAdapter, lazily creating it on first invocation. */ protected DbAdapter getAdapter() { if (adapter == null) { synchronized (this) { if (adapter == null) { this.adapter = loadAdapter(); } } } return adapter; } /** * Loads underlying DbAdapter delegate. */ protected DbAdapter loadAdapter() { return adapterProvider.get(); } /** * @since 4.0 */ @Override public SelectTranslator getSelectTranslator(SelectQuery<?> query, EntityResolver entityResolver) { return getAdapter().getSelectTranslator(query, entityResolver); } @Override public String getBatchTerminator() { return getAdapter().getBatchTerminator(); } @Override public QualifierTranslator getQualifierTranslator(QueryAssembler queryAssembler) { return getAdapter().getQualifierTranslator(queryAssembler); } @Override public SQLAction getAction(Query query, DataNode node) { return getAdapter().getAction(query, node); } @Override public boolean supportsUniqueConstraints() { return getAdapter().supportsUniqueConstraints(); } @Override public boolean supportsCatalogsOnReverseEngineering() { return getAdapter().supportsCatalogsOnReverseEngineering(); } @Override public boolean supportsGeneratedKeys() { return getAdapter().supportsGeneratedKeys(); } @Override public boolean supportsBatchUpdates() { return getAdapter().supportsBatchUpdates(); } @Override public boolean typeSupportsLength(int type) { return getAdapter().typeSupportsLength(type); } @Override public Collection<String> dropTableStatements(DbEntity table) { return getAdapter().dropTableStatements(table); } @Override public String createTable(DbEntity entity) { return getAdapter().createTable(entity); } @Override public String createUniqueConstraint(DbEntity source, Collection<DbAttribute> columns) { return getAdapter().createUniqueConstraint(source, columns); } @Override public String createFkConstraint(DbRelationship rel) { return getAdapter().createFkConstraint(rel); } @Override public String[] externalTypesForJdbcType(int type) { return getAdapter().externalTypesForJdbcType(type); } @Override public ExtendedTypeMap getExtendedTypes() { return getAdapter().getExtendedTypes(); } /** * Returns a primary key generator. */ @Override public PkGenerator getPkGenerator() { return (pkGenerator != null) ? pkGenerator : getAdapter().getPkGenerator(); } /** * Sets a PK generator override. If set to non-null value, such PK generator * will be used instead of the one provided by wrapped adapter. */ public void setPkGenerator(PkGenerator pkGenerator) { this.pkGenerator = pkGenerator; } @Override public DbAttribute buildAttribute(String name, String typeName, int type, int size, int precision, boolean allowNulls) { return getAdapter().buildAttribute(name, typeName, type, size, precision, allowNulls); } @Override public void bindParameter(PreparedStatement statement, ParameterBinding parameterBinding) throws SQLException, Exception { getAdapter().bindParameter(statement, parameterBinding); } @Override public String tableTypeForTable() { return getAdapter().tableTypeForTable(); } @Override public String tableTypeForView() { return getAdapter().tableTypeForView(); } @Override public void createTableAppendColumn(StringBuffer sqlBuffer, DbAttribute column) { getAdapter().createTableAppendColumn(sqlBuffer, column); } /** * @deprecated since 4.0 */ @Deprecated @Override public QuotingStrategy getQuotingStrategy(boolean isQuoteStrategy) { return getAdapter().getQuotingStrategy(isQuoteStrategy); } /** * @since 4.0 */ @Override public QuotingStrategy getQuotingStrategy() { return getAdapter().getQuotingStrategy(); } /** * @since 4.0 */ @Override public DbAdapter unwrap() { return getAdapter(); } /** * @since 4.0 */ @Override public EJBQLTranslatorFactory getEjbqlTranslatorFactory() { return getAdapter().getEjbqlTranslatorFactory(); } }