View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.shardingsphere.infra.datasource.pool.props.domain;
19  
20  import com.google.common.base.Objects;
21  import lombok.Getter;
22  import org.apache.shardingsphere.infra.datasource.pool.metadata.DataSourcePoolMetaData;
23  import org.apache.shardingsphere.infra.datasource.pool.props.domain.custom.CustomDataSourcePoolProperties;
24  import org.apache.shardingsphere.infra.datasource.pool.props.domain.synonym.ConnectionPropertySynonyms;
25  import org.apache.shardingsphere.infra.datasource.pool.props.domain.synonym.PoolPropertySynonyms;
26  import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
27  
28  import java.util.Collection;
29  import java.util.Collections;
30  import java.util.LinkedHashMap;
31  import java.util.LinkedList;
32  import java.util.Map;
33  import java.util.Map.Entry;
34  import java.util.Optional;
35  
36  /**
37   * Data source pool properties.
38   */
39  @Getter
40  public final class DataSourcePoolProperties {
41      
42      private final String poolClassName;
43      
44      private final ConnectionPropertySynonyms connectionPropertySynonyms;
45      
46      private final PoolPropertySynonyms poolPropertySynonyms;
47      
48      private final CustomDataSourcePoolProperties customProperties;
49      
50      public DataSourcePoolProperties(final String poolClassName, final Map<String, Object> props) {
51          Optional<DataSourcePoolMetaData> metaData = TypedSPILoader.findService(DataSourcePoolMetaData.class, poolClassName);
52          this.poolClassName = metaData.map(optional -> optional.getType().toString()).orElse(poolClassName);
53          Map<String, String> propertySynonyms = metaData.map(DataSourcePoolMetaData::getPropertySynonyms).orElse(Collections.emptyMap());
54          connectionPropertySynonyms = new ConnectionPropertySynonyms(props, propertySynonyms);
55          poolPropertySynonyms = new PoolPropertySynonyms(props, propertySynonyms);
56          Collection<String> transientFieldNames = metaData.map(DataSourcePoolMetaData::getTransientFieldNames).orElse(Collections.emptyList());
57          customProperties = new CustomDataSourcePoolProperties(props, getStandardPropertyKeys(), transientFieldNames, propertySynonyms);
58      }
59      
60      private Collection<String> getStandardPropertyKeys() {
61          Collection<String> result = new LinkedList<>(connectionPropertySynonyms.getStandardPropertyKeys());
62          result.addAll(poolPropertySynonyms.getStandardPropertyKeys());
63          return result;
64      }
65      
66      /**
67       * Get all standard properties.
68       * 
69       * @return all standard properties
70       */
71      public Map<String, Object> getAllStandardProperties() {
72          Map<String, Object> result = new LinkedHashMap<>(
73                  connectionPropertySynonyms.getStandardProperties().size() + poolPropertySynonyms.getStandardProperties().size() + customProperties.getProperties().size(), 1F);
74          result.putAll(connectionPropertySynonyms.getStandardProperties());
75          result.putAll(poolPropertySynonyms.getStandardProperties());
76          result.putAll(customProperties.getProperties());
77          return result;
78      }
79      
80      /**
81       * Get all local properties.
82       *
83       * @return all local properties
84       */
85      public Map<String, Object> getAllLocalProperties() {
86          Map<String, Object> result = new LinkedHashMap<>(
87                  connectionPropertySynonyms.getLocalProperties().size() + poolPropertySynonyms.getLocalProperties().size() + customProperties.getProperties().size(), 1F);
88          result.putAll(connectionPropertySynonyms.getLocalProperties());
89          result.putAll(poolPropertySynonyms.getLocalProperties());
90          result.putAll(customProperties.getProperties());
91          return result;
92      }
93      
94      @Override
95      public boolean equals(final Object obj) {
96          return this == obj || null != obj && getClass() == obj.getClass() && equalsByProperties((DataSourcePoolProperties) obj);
97      }
98      
99      private boolean equalsByProperties(final DataSourcePoolProperties props) {
100         return poolClassName.equals(props.poolClassName) && equalsByLocalProperties(props.getAllLocalProperties());
101     }
102     
103     private boolean equalsByLocalProperties(final Map<String, Object> localProps) {
104         for (Entry<String, Object> entry : getAllLocalProperties().entrySet()) {
105             if (!localProps.containsKey(entry.getKey())) {
106                 continue;
107             }
108             if (entry.getValue() instanceof Map) {
109                 return entry.getValue().equals(localProps.get(entry.getKey()));
110             }
111             if (!String.valueOf(entry.getValue()).equals(String.valueOf(localProps.get(entry.getKey())))) {
112                 return false;
113             }
114         }
115         return true;
116     }
117     
118     @Override
119     public int hashCode() {
120         StringBuilder stringBuilder = new StringBuilder();
121         for (Entry<String, Object> entry : getAllLocalProperties().entrySet()) {
122             stringBuilder.append(entry.getKey()).append(entry.getValue());
123         }
124         return Objects.hashCode(poolClassName, stringBuilder.toString());
125     }
126 }