Package com.dianping.cat.config.app

Source Code of com.dianping.cat.config.app.AppConfigManager$ConfigReloadTask

package com.dianping.cat.config.app;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.unidal.dal.jdbc.DalException;
import org.unidal.dal.jdbc.DalNotFoundException;
import org.unidal.helper.Files;
import org.unidal.helper.Threads;
import org.unidal.helper.Threads.Task;
import org.unidal.lookup.annotation.Inject;
import org.unidal.tuple.Pair;
import org.xml.sax.SAXException;

import com.dianping.cat.Cat;
import com.dianping.cat.configuration.app.entity.AppConfig;
import com.dianping.cat.configuration.app.entity.Code;
import com.dianping.cat.configuration.app.entity.Command;
import com.dianping.cat.configuration.app.entity.ConfigItem;
import com.dianping.cat.configuration.app.entity.Item;
import com.dianping.cat.configuration.app.transform.DefaultSaxParser;
import com.dianping.cat.core.config.Config;
import com.dianping.cat.core.config.ConfigDao;
import com.dianping.cat.core.config.ConfigEntity;

public class AppConfigManager implements Initializable {
  @Inject
  protected ConfigDao m_configDao;

  private Map<String, Integer> m_commands = new HashMap<String, Integer>();

  private Map<String, Integer> m_cities = new HashMap<String, Integer>();

  private Map<String, Integer> m_operators = new HashMap<String, Integer>();

  private int m_configId;

  private static final String CONFIG_NAME = "app-config";

  private AppConfig m_config;

  private long m_modifyTime;

  public static String NETWORK = "网络类型";

  public static String OPERATOR = "运营商";

  public static String VERSION = "版本";

  public static String PLATFORM = "平台";

  public static String CITY = "城市";

  public static String CONNECT_TYPE = "连接类型";

  public static final String ACTIVITY_PREFIX = "http://tgapp.dianping.com/activity/";

  public Pair<Boolean, Integer> addCommand(String domain, String title, String name) throws Exception {
    Command command = new Command();

    command.setDomain(domain);
    command.setTitle(title);
    command.setName(name);

    boolean isActivityCommand = name.startsWith(ACTIVITY_PREFIX);
    int commandId;
    if (isActivityCommand) {
      commandId = findAvailableId(1000, 1500);
    } else {
      commandId = findAvailableId(1, 200);
    }
    command.setId(commandId);

    m_config.addCommand(command);
    return new Pair<Boolean, Integer>(storeConfig(), commandId);
  }

  public boolean updateCommand(int id, String domain, String name, String title) {
    Command command = m_config.findCommand(id);

    command.setDomain(domain);
    command.setName(name);
    command.setTitle(title);
    return storeConfig();
  }

  public boolean containCommand(int id) {
    Set<Integer> keys = m_config.getCommands().keySet();

    if (keys.contains(id)) {
      return true;
    } else {
      return false;
    }
  }

  public Pair<Boolean, List<Integer>> deleteCommand(String domain, String name) {
    Collection<Command> commands = m_config.getCommands().values();
    List<Integer> needDeleteIds = new ArrayList<Integer>();

    for (Command command : commands) {
      if (name.equals(command.getName())) {
        if (domain == null || (domain != null && domain.equals(command.getDomain()))) {
          needDeleteIds.add(command.getId());
        }
      }
    }
    for (int id : needDeleteIds) {
      m_config.removeCommand(id);
    }
    return new Pair<Boolean, List<Integer>>(storeConfig(), needDeleteIds);
  }

  public boolean deleteCommand(int id) {
    m_config.removeCommand(id);
    return storeConfig();
  }

  private int findAvailableId(int startIndex, int endIndex) throws Exception {
    Set<Integer> keys = m_config.getCommands().keySet();
    int maxKey = 0;

    for (int key : keys) {
      if (key >= startIndex && key <= endIndex && key > maxKey) {
        maxKey = key;
      }
    }
    if (maxKey < endIndex && maxKey >= startIndex) {
      return maxKey + 1;
    } else {
      for (int i = startIndex; i <= endIndex; i++) {
        if (!keys.contains(i)) {
          return i;
        }
      }

      Exception ex = new RuntimeException();
      Cat.logError("app config range is full: " + startIndex + " - " + endIndex, ex);
      throw ex;
    }
  }

  public Map<String, Integer> getCities() {
    return m_cities;
  }

  public Map<String, Integer> getCommands() {
    return m_commands;
  }

  public AppConfig getConfig() {
    return m_config;
  }

  public Map<String, Integer> getOperators() {
    return m_operators;
  }

  public Map<Integer, Command> getRawCommands() {
    return m_config.getCommands();
  }

  @Override
  public void initialize() {
    try {
      Config config = m_configDao.findByName(CONFIG_NAME, ConfigEntity.READSET_FULL);
      String content = config.getContent();

      m_configId = config.getId();
      m_config = DefaultSaxParser.parse(content);
      m_modifyTime = config.getModifyDate().getTime();
      refreshData();
    } catch (DalNotFoundException e) {
      try {
        String content = Files.forIO().readFrom(
              this.getClass().getResourceAsStream("/config/default-app-config.xml"), "utf-8");
        Config config = m_configDao.createLocal();

        config.setName(CONFIG_NAME);
        config.setContent(content);
        m_configDao.insert(config);
        m_configId = config.getId();
        m_config = DefaultSaxParser.parse(content);
      } catch (Exception ex) {
        Cat.logError(ex);
      }
    } catch (Exception e) {
      Cat.logError(e);
    }
    if (m_config == null) {
      m_config = new AppConfig();
    }
    Threads.forGroup("cat").start(new ConfigReloadTask());
  }

  public boolean insert(String xml) {
    try {
      m_config = DefaultSaxParser.parse(xml);

      return storeConfig();
    } catch (Exception e) {
      Cat.logError(e);
      return false;
    }
  }

  public Map<Integer, Code> queryCodeByCommand(int command) {
    Command c = m_config.findCommand(command);

    if (c != null) {
      Map<Integer, Code> values = c.getCodes();
      Map<Integer, Code> result = new HashMap<Integer, Code>(values);

      result.putAll(m_config.getCodes());
      return result;
    } else {
      return Collections.emptyMap();
    }
  }

  public List<Command> queryCommands() {
    try {
      String xml = m_config.toString();
      AppConfig config = DefaultSaxParser.parse(xml);

      Map<Integer, Command> commands = config.getCommands();

      for (Entry<Integer, Command> entry : commands.entrySet()) {
        entry.getValue().getCodes().putAll(m_config.getCodes());
      }
      return new ArrayList<Command>(commands.values());
    } catch (Exception e) {
      return new ArrayList<Command>();
    }
  }

  public Map<Integer, Item> queryConfigItem(String name) {
    ConfigItem config = m_config.findConfigItem(name);

    if (config != null) {
      return config.getItems();
    } else {
      return new LinkedHashMap<Integer, Item>();
    }
  }

  public Collection<Item> queryConfigItems(String key) {
    ConfigItem configs = m_config.findConfigItem(key);

    if (configs != null) {
      return configs.getItems().values();
    } else {
      return new ArrayList<Item>();
    }
  }

  public void refreshAppConfigConfig() throws DalException, SAXException, IOException {
    Config config = m_configDao.findByName(CONFIG_NAME, ConfigEntity.READSET_FULL);
    long modifyTime = config.getModifyDate().getTime();

    synchronized (this) {
      if (modifyTime > m_modifyTime) {
        String content = config.getContent();
        AppConfig appConfig = DefaultSaxParser.parse(content);

        m_config = appConfig;
        m_modifyTime = modifyTime;
        refreshData();
      }
    }
  }

  private void refreshData() {
    Collection<Command> commands = m_config.getCommands().values();
    Map<String, Integer> commandMap = new HashMap<String, Integer>();

    for (Command c : commands) {
      commandMap.put(c.getName(), c.getId());
    }
    m_commands = commandMap;

    Map<String, Integer> cityMap = new HashMap<String, Integer>();
    ConfigItem cities = m_config.findConfigItem(CITY);

    for (Item item : cities.getItems().values()) {
      cityMap.put(item.getName(), item.getId());
    }
    m_cities = cityMap;

    Map<String, Integer> operatorMap = new HashMap<String, Integer>();
    ConfigItem operations = m_config.findConfigItem(OPERATOR);

    for (Item item : operations.getItems().values()) {
      operatorMap.put(item.getName(), item.getId());
    }
    m_operators = operatorMap;
  }

  private boolean storeConfig() {
    try {
      Config config = m_configDao.createLocal();

      config.setId(m_configId);
      config.setKeyId(m_configId);
      config.setName(CONFIG_NAME);
      config.setContent(m_config.toString());
      m_configDao.updateByPK(config, ConfigEntity.UPDATESET_FULL);

      refreshData();
    } catch (Exception e) {
      Cat.logError(e);
      return false;
    }
    return true;
  }

  public class ConfigReloadTask implements Task {

    @Override
    public String getName() {
      return "AppConfig-Config-Reload";
    }

    @Override
    public void run() {
      boolean active = true;
      while (active) {
        try {
          refreshAppConfigConfig();
        } catch (Exception e) {
          Cat.logError(e);
        }
        try {
          Thread.sleep(60 * 1000L);
        } catch (InterruptedException e) {
          active = false;
        }
      }
    }

    @Override
    public void shutdown() {
    }
  }

}
TOP

Related Classes of com.dianping.cat.config.app.AppConfigManager$ConfigReloadTask

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.