001/*
002 * Copyright 2002-2014 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.orm.jpa.vendor;
018
019import java.util.HashMap;
020import java.util.Map;
021import javax.persistence.EntityManager;
022import javax.persistence.EntityManagerFactory;
023import javax.persistence.spi.PersistenceProvider;
024
025import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
026import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
027import org.apache.openjpa.persistence.PersistenceProviderImpl;
028
029/**
030 * {@link org.springframework.orm.jpa.JpaVendorAdapter} implementation for Apache OpenJPA.
031 * Developed and tested against OpenJPA 2.2.
032 *
033 * <p>Exposes OpenJPA's persistence provider and EntityManager extension interface,
034 * and adapts {@link AbstractJpaVendorAdapter}'s common configuration settings.
035 * No support for the detection of annotated packages (through
036 * {@link org.springframework.orm.jpa.persistenceunit.SmartPersistenceUnitInfo#getManagedPackages()})
037 * since OpenJPA doesn't use package-level metadata.
038 *
039 * @author Juergen Hoeller
040 * @author Costin Leau
041 * @since 2.0
042 * @see OpenJpaDialect
043 * @see org.apache.openjpa.persistence.PersistenceProviderImpl
044 * @see org.apache.openjpa.persistence.OpenJPAEntityManager
045 */
046public class OpenJpaVendorAdapter extends AbstractJpaVendorAdapter {
047
048        private final PersistenceProvider persistenceProvider = new PersistenceProviderImpl();
049
050        private final OpenJpaDialect jpaDialect = new OpenJpaDialect();
051
052
053        @Override
054        public PersistenceProvider getPersistenceProvider() {
055                return this.persistenceProvider;
056        }
057
058        @Override
059        public String getPersistenceProviderRootPackage() {
060                return "org.apache.openjpa";
061        }
062
063        @Override
064        public Map<String, Object> getJpaPropertyMap() {
065                Map<String, Object> jpaProperties = new HashMap<String, Object>();
066
067                if (getDatabasePlatform() != null) {
068                        jpaProperties.put("openjpa.jdbc.DBDictionary", getDatabasePlatform());
069                }
070                else if (getDatabase() != null) {
071                        String databaseDictonary = determineDatabaseDictionary(getDatabase());
072                        if (databaseDictonary != null) {
073                                jpaProperties.put("openjpa.jdbc.DBDictionary", databaseDictonary);
074                        }
075                }
076
077                if (isGenerateDdl()) {
078                        jpaProperties.put("openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=true)");
079                }
080                if (isShowSql()) {
081                        // Taken from the OpenJPA 0.9.6 docs ("Standard OpenJPA Log Configuration + All SQL Statements")
082                        jpaProperties.put("openjpa.Log", "DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE");
083                }
084
085                return jpaProperties;
086        }
087
088        /**
089         * Determine the OpenJPA database dictionary name for the given database.
090         * @param database the specified database
091         * @return the OpenJPA database dictionary name, or {@code null} if none found
092         */
093        protected String determineDatabaseDictionary(Database database) {
094                switch (database) {
095                        case DB2: return "db2";
096                        case DERBY: return "derby";
097                        case HSQL: return "hsql(SimulateLocking=true)";
098                        case INFORMIX: return "informix";
099                        case MYSQL: return "mysql";
100                        case ORACLE: return "oracle";
101                        case POSTGRESQL: return "postgres";
102                        case SQL_SERVER: return "sqlserver";
103                        case SYBASE: return "sybase";
104                        default: return null;
105                }
106        }
107
108        @Override
109        public OpenJpaDialect getJpaDialect() {
110                return this.jpaDialect;
111        }
112
113        @Override
114        public Class<? extends EntityManagerFactory> getEntityManagerFactoryInterface() {
115                return OpenJPAEntityManagerFactorySPI.class;
116        }
117
118        @Override
119        public Class<? extends EntityManager> getEntityManagerInterface() {
120                return OpenJPAEntityManagerSPI.class;
121        }
122
123}