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 com.realtime.crossfire.jxclient.util.EventListenerList2;
00025 import java.util.ArrayList;
00026 import java.util.Collection;
00027 import java.util.Collections;
00028 import java.util.HashMap;
00029 import java.util.List;
00030 import java.util.Map;
00031 import org.jetbrains.annotations.NotNull;
00032 import org.jetbrains.annotations.Nullable;
00033
00039 public class MetaserverModel {
00040
00044 @NotNull
00045 private final List<MetaserverEntry> metaList = new ArrayList<MetaserverEntry>();
00046
00051 @NotNull
00052 private final Collection<MetaserverEntry> metaListPending = new ArrayList<MetaserverEntry>();
00053
00057 @NotNull
00058 private final Object sync = new Object();
00059
00063 @NotNull
00064 private final EventListenerList2<MetaserverListener> metaserverListeners = new EventListenerList2<MetaserverListener>(MetaserverListener.class);
00065
00070 @NotNull
00071 private final Map<Integer, EventListenerList2<MetaserverEntryListener>> metaserverEntryListeners = new HashMap<Integer, EventListenerList2<MetaserverEntryListener>>();
00072
00079 @Nullable
00080 public MetaserverEntry getEntry(final int index) {
00081 try {
00082 synchronized (sync) {
00083 return metaList.get(index);
00084 }
00085 } catch (final IndexOutOfBoundsException ignored) {
00086 return null;
00087 }
00088 }
00089
00095 public int getServerIndex(@NotNull final String serverName) {
00096 synchronized (sync) {
00097 int index = 0;
00098 for (final MetaserverEntry metaserverEntry : metaList) {
00099 if (metaserverEntry.getHostname().equals(serverName)) {
00100 return index;
00101 }
00102
00103 index++;
00104 }
00105 }
00106
00107 return -1;
00108 }
00109
00114 public int size() {
00115 synchronized (sync) {
00116 return metaList.size();
00117 }
00118 }
00119
00124 public void add(@NotNull final MetaserverEntry metaserverEntry) {
00125 synchronized (sync) {
00126 metaListPending.add(metaserverEntry);
00127 }
00128 }
00129
00133 public void begin() {
00134 metaListPending.clear();
00135 }
00136
00140 public void commit() {
00141 final int oldMetaListSize;
00142 final int newMetaListSize;
00143 synchronized (sync) {
00144 oldMetaListSize = metaList.size();
00145 metaList.clear();
00146 metaList.addAll(metaListPending);
00147 Collections.sort(metaList);
00148 newMetaListSize = metaList.size();
00149 }
00150 metaListPending.clear();
00151
00152 for (final MetaserverListener metaserverListener : metaserverListeners.getListeners()) {
00153 metaserverListener.numberOfEntriesChanged();
00154 }
00155
00156 for (int i = 0, iMax = Math.max(oldMetaListSize, newMetaListSize); i < iMax; i++) {
00157 for (final MetaserverEntryListener metaserverEntryListener : getMetaserverEntryListeners(i).getListeners()) {
00158 metaserverEntryListener.entryChanged();
00159 }
00160 }
00161 }
00162
00167 public void addMetaserverListener(@NotNull final MetaserverListener listener) {
00168 metaserverListeners.add(listener);
00169 }
00170
00175 public void removeMetaserverListener(@NotNull final MetaserverListener listener) {
00176 metaserverListeners.remove(listener);
00177 }
00178
00184 public void addMetaserverEntryListener(final int index, @NotNull final MetaserverEntryListener listener) {
00185 getMetaserverEntryListeners(index).add(listener);
00186 }
00187
00193 public void removeMetaserverEntryListener(final int index, @NotNull final MetaserverEntryListener listener) {
00194 getMetaserverEntryListeners(index).remove(listener);
00195 }
00196
00202 @NotNull
00203 private EventListenerList2<MetaserverEntryListener> getMetaserverEntryListeners(final int index) {
00204 synchronized (metaserverEntryListeners) {
00205 final EventListenerList2<MetaserverEntryListener> existingListeners = metaserverEntryListeners.get(index);
00206 if (existingListeners != null) {
00207 return existingListeners;
00208 }
00209
00210 final EventListenerList2<MetaserverEntryListener> newListeners = new EventListenerList2<MetaserverEntryListener>(MetaserverEntryListener.class);
00211 metaserverEntryListeners.put(index, newListeners);
00212 return newListeners;
00213 }
00214 }
00215
00216 }