00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 package com.realtime.crossfire.jxclient.metaserver;
00023
00024 import java.io.BufferedWriter;
00025 import java.io.File;
00026 import java.io.FileInputStream;
00027 import java.io.FileNotFoundException;
00028 import java.io.FileOutputStream;
00029 import java.io.IOException;
00030 import java.io.InputStreamReader;
00031 import java.io.LineNumberReader;
00032 import java.io.OutputStreamWriter;
00033 import java.util.HashMap;
00034 import java.util.Iterator;
00035 import java.util.Map;
00036 import org.jetbrains.annotations.NotNull;
00037 import org.jetbrains.annotations.Nullable;
00038
00043 public class ServerCache {
00044
00048 @NotNull
00049 public static final CharSequence DEFAULT_ENTRY_LOCALHOST = "0|localhost|0|--|Local server. Start server before you try to connect.|0|0|0|||";
00050
00055 @NotNull
00056 private final Map<String, Info> entries = new HashMap<String, Info>();
00057
00061 @Nullable
00062 private final File file;
00063
00068 public ServerCache(@Nullable final File file) {
00069 this.file = file;
00070
00071 load();
00072 }
00073
00079 public void put(@NotNull final MetaserverEntry metaserverEntry) {
00080 entries.put(makeKey(metaserverEntry), new Info(metaserverEntry));
00081 }
00082
00087 public void expire(final long timestamp) {
00088 final long now = System.currentTimeMillis();
00089
00090 final Iterator<Info> it = entries.values().iterator();
00091 while (it.hasNext()) {
00092 final Info info = it.next();
00093 if (now-info.getTimestamp() > timestamp) {
00094 it.remove();
00095 }
00096 }
00097 }
00098
00104 @NotNull
00105 public Map<String, MetaserverEntry> getAll() {
00106 final Map<String, MetaserverEntry> result = new HashMap<String, MetaserverEntry>();
00107 for (final Map.Entry<String, Info> entry : entries.entrySet()) {
00108 result.put(entry.getKey(), entry.getValue().getMetaserverEntry());
00109 }
00110 return result;
00111 }
00112
00118 @NotNull
00119 public static String makeKey(@NotNull final MetaserverEntry metaserverEntry) {
00120 return metaserverEntry.getHostname();
00121 }
00122
00126 private void load() {
00127 if (file == null) {
00128 return;
00129 }
00130
00131 try {
00132 final FileInputStream fis = new FileInputStream(file);
00133 try {
00134 final InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
00135 try {
00136 final LineNumberReader lnr = new LineNumberReader(isr);
00137 try {
00138 while (true) {
00139 final String line = lnr.readLine();
00140 if (line == null) {
00141 break;
00142 }
00143
00144 final String[] tmp = line.split(" ", 2);
00145 if (tmp.length != 2) {
00146 System.err.println(file+":"+lnr.getLineNumber()+": syntax error");
00147 continue;
00148 }
00149
00150 final long timestamp;
00151 try {
00152 timestamp = Long.parseLong(tmp[0]);
00153 } catch (final NumberFormatException ignored) {
00154 System.err.println(file+":"+lnr.getLineNumber()+": syntax error");
00155 continue;
00156 }
00157 if (!addEntry(tmp[1], timestamp)) {
00158 System.err.println(file+":"+lnr.getLineNumber()+": syntax error");
00159 continue;
00160 }
00161 }
00162 } finally {
00163 lnr.close();
00164 }
00165 } finally {
00166 isr.close();
00167 }
00168 } finally {
00169 fis.close();
00170 }
00171 } catch (final FileNotFoundException ignored) {
00172
00173 final long now = System.currentTimeMillis()-1;
00174 addEntry(DEFAULT_ENTRY_LOCALHOST, now);
00175 addEntry("0|crossfire.metalforge.net|0|--|Latest SVN 1.x branch.<br>Eden Prairie, MN US<br>4.65Mb link<br><a href=\"http://crossfire.real-time.com\">crossfire.real-time.com</a>|0|0|0|Standard|Standard|Standard", now);
00176 addEntry("0|invidious.meflin.net|0|--|<b>Welcome, we are testing 2.0 come on in the water is fine.</b>|0|0|0|Standard|Standard|Standard + Testing", now);
00177 } catch (final IOException ex) {
00178 System.err.println(file+": "+ex.getMessage());
00179 }
00180 }
00181
00188 private boolean addEntry(@NotNull final CharSequence metaserverEntryLine, final long timestamp) {
00189 final MetaserverEntry metaserverEntry = MetaserverEntryParser.parseEntry(metaserverEntryLine);
00190 if (metaserverEntry == null) {
00191 return false;
00192 }
00193
00194 entries.put(makeKey(metaserverEntry), new Info(metaserverEntry, timestamp));
00195 return true;
00196 }
00197
00201 public void save() {
00202 if (file == null) {
00203 return;
00204 }
00205
00206 try {
00207 final FileOutputStream fos = new FileOutputStream(file);
00208 try {
00209 final OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
00210 try {
00211 final BufferedWriter bw = new BufferedWriter(osw);
00212 try {
00213 for (final Info info : entries.values()) {
00214 bw.write(Long.toString(info.getTimestamp()));
00215 bw.write(' ');
00216 bw.write(MetaserverEntryParser.format(info.getMetaserverEntry()));
00217 bw.write('\n');
00218 }
00219 } finally {
00220 bw.close();
00221 }
00222 } finally {
00223 osw.close();
00224 }
00225 } finally {
00226 fos.close();
00227 }
00228 } catch (final IOException ex) {
00229 System.err.println(file+": "+ex.getMessage());
00230 }
00231 }
00232
00233 }