Package org.spoutcraft.launcher.util

Source Code of org.spoutcraft.launcher.util.MirrorUtils

/*
* This file is part of Spoutcraft Launcher.
*
* Copyright (c) 2011 Spout LLC <http://www.spout.org/>
* Spoutcraft Launcher is licensed under the Spout License Version 1.
*
* Spoutcraft Launcher is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition, 180 days after any changes are published, you can use the
* software, incorporating those changes, under the terms of the MIT license,
* as described in the Spout License Version 1.
*
* Spoutcraft Launcher is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License,
* the MIT license and the Spout License Version 1 along with this program.
* If not, see <http://www.gnu.org/licenses/> for the GNU Lesser General Public
* License and see <http://spout.in/licensev1> for the full license,
* including the MIT license.
*/
package org.spoutcraft.launcher.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;

import org.spoutcraft.launcher.Settings;
import org.spoutcraft.launcher.exceptions.NoMirrorsAvailableException;
import org.spoutcraft.launcher.util.Utils;
import org.spoutcraft.launcher.yml.YAMLProcessor;

public class MirrorUtils {
  private static boolean updated = false;
  private static File mirrorsYML = new File(Utils.getWorkingDirectory(), "config" + File.separator + "mirrors.yml");
  private static final String baseURL = "http://get.spout.org/";
  private static List<String> mirrors = null;

  public static String getMirrorUrl(String mirrorURI, String fallbackUrl) {
    updateMirrors();

    boolean debug = Settings.isDebugMode();
    if (debug) {
      System.out.println("Testing " + MirrorUtils.mirrors.size() + " for " + mirrorURI);
    }
    for (String mirror : MirrorUtils.mirrors) {
      String lookup = "http://" + mirror + "/" + mirrorURI;
      if (isAddressReachable(lookup, 1000)) {
        return lookup;
      }
    }

    return fallbackUrl;
  }

  public static String getMirrorUrl(String mirrorURI) throws NoMirrorsAvailableException {
    String url = getMirrorUrl(mirrorURI, null);
    if (url != null) {
      return url;
    }

    throw new NoMirrorsAvailableException("No mirrors available for " + mirrorURI + ", checked " + MirrorUtils.mirrors.size() + " mirrors");
  }

  private static void updateMirrors() {
    if (MirrorUtils.mirrors == null || MirrorUtils.mirrors.size() == 0) {
      Map<String, Integer> mirrors = getMirrors();
      Set<Entry<String, Integer>> set = mirrors.entrySet();

      ArrayList<String> goodMirrors = new ArrayList<String>(mirrors.size());
      Iterator<Entry<String, Integer>> iterator = set.iterator();
      while (iterator.hasNext()) {
        Entry<String, Integer> e = iterator.next();
        String mirror = "http://" + e.getKey();
        if (isAddressReachable(mirror, 3000)) {
          goodMirrors.add(e.getKey());
        }
      }

      Collections.sort(goodMirrors, new MirrorComparator(mirrors));
      for (String mirror : goodMirrors) {
        System.out.println("Mirror " + mirror + " value " + mirrors.get(mirror));
      }

      MirrorUtils.mirrors = goodMirrors;
    }
  }

  @SuppressWarnings("unchecked")
  public static Map<String, Integer> getMirrors() {
    YAMLProcessor config = getMirrorsYML();
    return (Map<String, Integer>) config.getProperty("mirrors");
  }

  public static boolean isAddressReachable(String url, int timeout) {
    try {
      URL test = new URL(url);
      HttpURLConnection.setFollowRedirects(false);
      HttpURLConnection urlConnect = (HttpURLConnection) test.openConnection();
      System.setProperty("http.agent", "");
      urlConnect.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.100 Safari/534.30");
      urlConnect.setRequestMethod("HEAD");
      urlConnect.setConnectTimeout(timeout);
      int response = urlConnect.getResponseCode();
      if (Settings.isDebugMode()) {
        System.out.println("Response for mirror " + url + " was " + response);
      }
      return (response == HttpURLConnection.HTTP_OK);
    } catch (Exception e) {
      return false;
    }
  }

  public static YAMLProcessor getMirrorsYML() {
    updateMirrorsYMLCache();
    YAMLProcessor config = new YAMLProcessor(mirrorsYML, false);
    try {
      config.load();
    } catch (IOException e) {
      e.printStackTrace();
    }
    return config;
  }

  public static void updateMirrorsYMLCache() {
    if (!updated) {
      try {
        URL url = new URL("http://get.spout.org/mirrors.yml");
        HttpURLConnection con = (HttpURLConnection) (url.openConnection());
        System.setProperty("http.agent", "");
        con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.100 Safari/534.30");
        Utils.copy(con.getInputStream(), new FileOutputStream(mirrorsYML));
      } catch (IOException e) {
        e.printStackTrace();
      }
      updated = true;
    }
  }

  public static String getBaseURL() {
    return baseURL;
  }
}

class MirrorComparator implements Comparator<String> {
  final Map<String, Integer> values = new HashMap<String, Integer>();
  final Random rand = new Random();
  final Map<String, Integer> mirrors;
  public MirrorComparator(Map<String, Integer> mirrors) {
    this.mirrors = mirrors;
  }
  public int compare(String o1, String o2) {
    return getValue(o2) - getValue(o1);
  }

  private int getValue(String mirror) {
    if (values.containsKey(mirror)) {
      return values.get(mirror);
    }
    int value = rand.nextInt(mirrors.get(mirror)) + 1;
    values.put(mirror, value);
    return value;
  }
}
TOP

Related Classes of org.spoutcraft.launcher.util.MirrorUtils

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.