001 /*
002 * Copyright 2014-2017 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 * http://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 package org.codehaus.griffon.runtime.ebean;
017
018 import com.avaje.ebean.EbeanServer;
019 import com.avaje.ebean.config.ServerConfig;
020 import griffon.core.GriffonApplication;
021 import griffon.core.injection.Injector;
022 import griffon.plugins.datasource.DataSourceFactory;
023 import griffon.plugins.datasource.DataSourceStorage;
024 import griffon.plugins.ebean.EbeanBootstrap;
025 import griffon.plugins.ebean.EbeanServerFactory;
026 import griffon.util.GriffonClassUtils;
027 import org.codehaus.griffon.runtime.core.storage.AbstractObjectFactory;
028
029 import javax.annotation.Nonnull;
030 import javax.inject.Inject;
031 import javax.inject.Named;
032 import javax.sql.DataSource;
033 import java.util.Arrays;
034 import java.util.LinkedHashSet;
035 import java.util.Map;
036 import java.util.Set;
037
038 import static griffon.util.ConfigUtils.getConfigValue;
039 import static griffon.util.GriffonNameUtils.requireNonBlank;
040 import static java.util.Arrays.asList;
041 import static java.util.Objects.requireNonNull;
042
043 /**
044 * @author Andres Almiray
045 */
046 public class DefaultEbeanServerFactory extends AbstractObjectFactory<EbeanServer> implements EbeanServerFactory {
047 private static final String ERROR_SESSION_FACTORY_NAME_BLANK = "Argument 'ebeanServerName' must not be blank";
048 private final Set<String> ebeanServerNames = new LinkedHashSet<>();
049
050 private static final String[] CUSTOM_PROPERTIES = {
051 "connect_on_startup",
052 "schema"
053 };
054
055 @Inject
056 private DataSourceFactory dataSourceFactory;
057
058 @Inject
059 private DataSourceStorage dataSourceStorage;
060
061 @Inject
062 private Injector injector;
063
064 @Inject
065 public DefaultEbeanServerFactory(@Nonnull @Named("ebean") griffon.core.Configuration configuration, @Nonnull GriffonApplication application) {
066 super(configuration, application);
067 ebeanServerNames.add(KEY_DEFAULT);
068
069 if (configuration.containsKey(getPluralKey())) {
070 Map<String, Object> ebeanFactories = (Map<String, Object>) configuration.get(getPluralKey());
071 ebeanServerNames.addAll(ebeanFactories.keySet());
072 }
073 }
074
075 @Nonnull
076 @Override
077 public Set<String> getEbeanServerNames() {
078 return ebeanServerNames;
079 }
080
081 @Nonnull
082 @Override
083 public Map<String, Object> getConfigurationFor(@Nonnull String ebeanServerName) {
084 requireNonBlank(ebeanServerName, ERROR_SESSION_FACTORY_NAME_BLANK);
085 return narrowConfig(ebeanServerName);
086 }
087
088 @Nonnull
089 @Override
090 protected String getSingleKey() {
091 return "ebeanServer";
092 }
093
094 @Nonnull
095 @Override
096 protected String getPluralKey() {
097 return "ebeanServers";
098 }
099
100 @Nonnull
101 @Override
102 public EbeanServer create(@Nonnull String name) {
103 Map<String, Object> config = narrowConfig(name);
104 event("EbeanConnectStart", asList(name, config));
105
106 EbeanServer ebeanserver = createEbeanServer(config, name);
107 for (Object o : injector.getInstances(EbeanBootstrap.class)) {
108 ((EbeanBootstrap) o).init(name, ebeanserver);
109 }
110
111 event("EbeanConnectEnd", asList(name, config, ebeanserver));
112 return ebeanserver;
113 }
114
115 @Override
116 public void destroy(@Nonnull String name, @Nonnull EbeanServer instance) {
117 requireNonNull(instance, "Argument 'instance' must not be null");
118 Map<String, Object> config = narrowConfig(name);
119 event("EbeanDisconnectStart", asList(name, config, instance));
120
121 for (Object o : injector.getInstances(EbeanBootstrap.class)) {
122 ((EbeanBootstrap) o).destroy(name, instance);
123 }
124
125 closeDataSource(name);
126
127 event("EbeanDisconnectEnd", asList(name, config));
128 }
129
130 @Nonnull
131
132 protected EbeanServer createEbeanServer(@Nonnull Map<String, Object> config, @Nonnull String ebeanServerName) {
133 String schemaCreate = getConfigValue(config, "schema", "create");
134 boolean ddl = "create".equalsIgnoreCase(schemaCreate);
135
136 ServerConfig serverConfig = new ServerConfig();
137 serverConfig.setName(ebeanServerName);
138 serverConfig.setRegister(true);
139 serverConfig.setDefaultServer(KEY_DEFAULT.equals(ebeanServerName));
140 serverConfig.setDdlGenerate(ddl);
141 serverConfig.setDdlRun(ddl);
142 serverConfig.setDataSource(getDataSource(ebeanServerName));
143
144 for (Map.Entry<String, Object> e : config.entrySet()) {
145 if (Arrays.binarySearch(CUSTOM_PROPERTIES, e.getKey()) != -1) {
146 continue;
147 }
148 GriffonClassUtils.setPropertyValue(serverConfig, e.getKey(), e.getValue());
149 }
150
151 return com.avaje.ebean.EbeanServerFactory.create(serverConfig);
152 }
153
154 protected void closeDataSource(@Nonnull String dataSourceName) {
155 DataSource dataSource = dataSourceStorage.get(dataSourceName);
156 if (dataSource != null) {
157 dataSourceFactory.destroy(dataSourceName, dataSource);
158 dataSourceStorage.remove(dataSourceName);
159 }
160 }
161
162 @Nonnull
163 protected DataSource getDataSource(@Nonnull String dataSourceName) {
164 DataSource dataSource = dataSourceStorage.get(dataSourceName);
165 if (dataSource == null) {
166 dataSource = dataSourceFactory.create(dataSourceName);
167 dataSourceStorage.set(dataSourceName, dataSource);
168 }
169 return dataSource;
170 }
171 }
|