content: /**
   * Copyright 1999-2011 Alibaba Group
   *
   * 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.alibaba.cobar.client.router.config;
  
  import java.io.IOException;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  
  import org.springframework.beans.factory.FactoryBean;
  import org.springframework.beans.factory.InitializingBean;
  import org.springframework.core.io.Resource;
  import org.springframework.util.ObjectUtils;
  
  import com.alibaba.cobar.client.router.CobarClientInternalRouter;
  import com.alibaba.cobar.client.router.rules.IRoutingRule;
  import com.alibaba.cobar.client.router.support.IBatisRoutingFact;
  
  public abstract class AbstractCobarInternalRouterConfigurationFactoryBean implements FactoryBean,
          InitializingBean {
      private CobarClientInternalRouter router;
  
      private boolean                   enableCache;
      private int                       cacheSize;
  
      private Resource                  configLocation;
      private Resource[]                configLocations;
  
      private Map<String, Object>       functionsMap = new HashMap<String, Object>();
  
      public Object getObject() throws Exception {
          return this.router;
      }
  
      @SuppressWarnings("unchecked")
      public Class getObjectType() {
          return CobarClientInternalRouter.class;
      }
  
      public boolean isSingleton() {
          return true;
      }
  
      public void afterPropertiesSet() throws Exception {
          if (enableCache) {
              if (cacheSize <= 0) {
                  setCacheSize(10000);
              }
          }
          this.router = new CobarClientInternalRouter(enableCache, cacheSize);
  
          final Set<IRoutingRule<IBatisRoutingFact, List<String>>> sqlActionShardingRules = new HashSet<IRoutingRule<IBatisRoutingFact, List<String>>>();
          final Set<IRoutingRule<IBatisRoutingFact, List<String>>> sqlActionRules = new HashSet<IRoutingRule<IBatisRoutingFact, List<String>>>();
          final Set<IRoutingRule<IBatisRoutingFact, List<String>>> namespaceShardingRules = new HashSet<IRoutingRule<IBatisRoutingFact, List<String>>>();
          final Set<IRoutingRule<IBatisRoutingFact, List<String>>> namespaceRules = new HashSet<IRoutingRule<IBatisRoutingFact, List<String>>>();
  
          if (getConfigLocation() != null) {
              assembleRulesForRouter(this.router, getConfigLocation(), sqlActionShardingRules,
                      sqlActionRules, namespaceShardingRules, namespaceRules);
          }
  
          if (!ObjectUtils.isEmpty(getConfigLocations())) {
              for (Resource res : getConfigLocations()) {
                  assembleRulesForRouter(this.router, res, sqlActionShardingRules, sqlActionRules,
                          namespaceShardingRules, namespaceRules);
              }
          }
  
          List<Set<IRoutingRule<IBatisRoutingFact, List<String>>>> ruleSequences = new ArrayList<Set<IRoutingRule<IBatisRoutingFact, List<String>>>>() {
              private static final long serialVersionUID = 1493353938640646578L;
              {
                  add(sqlActionShardingRules);
                  add(sqlActionRules);
                  add(namespaceShardingRules);
                  add(namespaceRules);
              }
          };
  
          router.setRuleSequences(ruleSequences);
      }
  
      /**
       * Subclass just needs to read in rule configurations and assemble the
       * router with the rules read from configurations.
       * 
       * @param router
       * @param namespaceRules
       * @param namespaceShardingRules
       * @param sqlActionRules
       * @param sqlActionShardingRules
       */
      protected abstract void assembleRulesForRouter(
                                                     CobarClientInternalRouter router,
                                                     Resource configLocation,
                                                     Set<IRoutingRule<IBatisRoutingFact, List<String>>> sqlActionShardingRules,
                                                     Set<IRoutingRule<IBatisRoutingFact, List<String>>> sqlActionRules,
                                                     Set<IRoutingRule<IBatisRoutingFact, List<String>>> namespaceShardingRules,
                                                     Set<IRoutingRule<IBatisRoutingFact, List<String>>> namespaceRules)
              throws IOException;
  
      public void setConfigLocation(Resource configLocation) {
          this.configLocation = configLocation;
      }
  
      public Resource getConfigLocation() {
          return configLocation;
      }
  
      public void setConfigLocations(Resource[] configLocations) {
          this.configLocations = configLocations;
      }
  
      public Resource[] getConfigLocations() {
          return configLocations;
      }
  
      public void setEnableCache(boolean enableCache) {
          this.enableCache = enableCache;
      }
  
      public boolean isEnableCache() {
          return enableCache;
      }
  
      public void setCacheSize(int cacheSize) {
          this.cacheSize = cacheSize;
      }
  
      public int getCacheSize() {
          return cacheSize;
      }
  
      public void setFunctionsMap(Map<String, Object> functionMaps) {
          if (functionMaps == null) {
              return;
          }
          this.functionsMap = functionMaps;
      }
  
      public Map<String, Object> getFunctionsMap() {
          return functionsMap;
      }
  
  }
  