1 18 package freecs.core; 19 20 import freecs.*; 21 import freecs.interfaces.*; 22 import java.io.File ; 23 import java.io.FileInputStream ; 24 import java.io.FileNotFoundException ; 25 import java.io.IOException ; 26 import java.lang.reflect.Method ; 27 import java.util.HashMap ; 28 import java.util.Map ; 29 import java.util.Properties ; 30 import java.util.Vector ; 31 import java.util.Enumeration ; 32 import java.util.Iterator ; 33 38 public class GroupManager implements IGroupState { 39 public static final GroupManager mgr = new GroupManager (); 40 public static final HashMap pluginStore = new HashMap (); 41 private Map grps = new HashMap (); 42 private Group[] grpsArr = new Group[0]; 43 private int highWaterMark=0; 44 private Vector moderatedGroups=new Vector (), startGroups=new Vector (); 45 private volatile long lastModified=0; 46 private volatile long groupListLastChange=0; 47 public HashMap startGroupThemes=new HashMap (); 48 49 private GroupManager () { 50 } 51 52 56 private synchronized void addGroup (Group g) { 57 grps.put (g.getKey (), g); 58 lastModified=System.currentTimeMillis(); 59 grpsArr=null; 60 if (grps.size () > highWaterMark) 61 highWaterMark = grps.size(); 62 } 63 64 public int getHighWaterMark () { 65 return highWaterMark; 66 } 67 68 72 public synchronized void removeGroup (Group g) { 73 if (g == null) 74 return; 75 lastModified=System.currentTimeMillis(); 76 g.invalidate(); 77 grps.remove (g.getKey ()); 78 IGroupPlugin[] plugins = g.getPlugins(); 79 if (plugins!=null) { 80 for (int i = 0; i<plugins.length; i++) { 81 try { 82 plugins[i].remove(); 83 } catch (Exception e) { 84 Server.debug(plugins[i], "catched exception from extension while removing: ", e, Server.MSG_ERROR, Server.LVL_MAJOR); 85 } 86 } 87 } 88 grpsArr=null; 89 } 90 91 96 public Group getGroup (String gName) { 97 if (gName==null) 98 return null; 99 return (Group) grps.get (gName.toLowerCase ().trim()); 100 } 101 102 107 public Group getStartingGroup (String gName) { 108 Group g; 109 g = (Group) grps.get (gName.toLowerCase ().trim()); 110 if (g == null) return null; 111 if (!g.hasState(IGroupState.ENTRANCE)) { 112 return null; 113 } 114 return g; 115 } 116 117 124 public Group openGroup (String groupname, String topic, User opener) { 125 return openGroup (groupname, topic, opener, opener); 126 } 127 128 136 public synchronized Group openGroup (String groupname, String topic, User opener, User rUser) { 137 if (Server.srv.MAX_GROUPNAME_LENGTH > 0 && groupname.length() > Server.srv.MAX_GROUPNAME_LENGTH) 138 return null; 139 if (isStartingGroup(groupname) 140 && (!opener.hasRight(IUserStates.ROLE_VIP) 141 || topic==null)) 142 topic = (String ) startGroupThemes.get(groupname.trim().toLowerCase()); 143 boolean moderated = moderatedGroups.contains(groupname.trim().toLowerCase()); 144 if (moderated && !rUser.hasRight(IUserStates.MAY_OPEN_MODERATED_GROUP)) 145 return null; 146 Group g = getGroup(groupname); 147 if (g != null) { 150 return g.addUser(opener, rUser) ? g : null; 151 } 152 if (!rUser.hasRight (IUserStates.MAY_OPEN_GROUP)) 153 return null; 154 g = new Group (groupname, topic); 155 if (isStartingGroup(g.getRawName())) 156 g.setState(IGroupState.ENTRANCE); 157 if (moderated) 158 g.setState(IGroupState.MODERATED); 159 StringBuffer sb = new StringBuffer (Server.BASE_PATH); 160 sb.append ("/grouppolicies/"); 161 sb.append (groupname.toLowerCase()); 162 sb.append (".properties"); 163 File f = new File (sb.toString()); 164 if (f.exists()) { 165 g = checkProperties (f, g, rUser); 166 if (g == null) 167 return null; 168 } 169 if (!g.addUser (opener)) 170 return null; 171 addGroup (g); 172 return g; 173 } 174 175 private Group checkProperties (File f, Group g, User rUser) { 176 Properties props = new Properties (); 177 try { 178 FileInputStream in = new FileInputStream (f); 179 props.load(in); 180 in.close(); 181 } catch (FileNotFoundException fnfe) { 182 return g; 183 } catch (IOException ioe) { 184 Server.debug(this, "crateByProperties:", ioe, Server.MSG_ERROR, Server.LVL_HALT); 185 return g; 186 } 187 HashMap map = new HashMap (); 188 for (Iterator i = props.keySet().iterator(); i.hasNext(); ) { 189 String key = i.next().toString(); 190 String low = key.toLowerCase(); 191 String val = props.getProperty(key); 192 if ("moderated".equals(low) 193 && "true".equals(val)) { 194 if (!rUser.hasRight(IUserStates.MAY_OPEN_MODERATED_GROUP)) 195 return null; 196 g.setState(IGroupState.MODERATED); 197 } else if ("timelock".equals(low)) { 198 if (!g.hasState(IGroupState.MODERATED)) 199 return null; 200 try { 201 int sec = Integer.parseInt(val); 202 g.setTimelockSec(sec); 203 } catch (NumberFormatException nfe) { 204 Server.log(g, "Timelock value isn't a number", Server.MSG_ERROR, Server.LVL_MINOR); 205 } 206 } else if ("minuserrole".equals(low)) { 207 int r = 0; 208 if ("vip".equals(val)) 209 r = IUserStates.ROLE_VIP; 210 else if ("moderator".equals(val)) 211 r = IUserStates.IS_MODERATOR; 212 else if ("admin".equals(val)) 213 r = IUserStates.ROLE_GOD; 214 if (!rUser.hasRight(r)) 215 return null; 216 g.setMinRight(r); 217 } else if ("autosulist".equals(low)) { 218 g.setAutoSu (val.split(",")); 219 } else if ("lockprotected".equals(low) 220 && "true".equals(val)) { 221 if (!g.hasState(IGroupState.OPEN)) 222 g.setState (IGroupState.OPEN); 223 g.setState (IGroupState.LOCKPROTECTED); 224 } else if ("autosu".equals(low) 225 && "false".equals(val)) { 226 g.unsetState (IGroupState.AUTO_SU_FIRST); 227 } else if ("allowsu".equals(low) 228 && "false".equals(val)) { 229 g.unsetState (IGroupState.ALLOW_SU); 230 } else if ("nosufirst".equals(low) 231 && "true".equals(val)) { 232 g.setState (IGroupState.NO_SU_FIRST); 233 } else if ("minuserrolesu".equals(low)) { 234 if ("vip".equals(val)) 235 g.setMinRightSu(IUserStates.ROLE_VIP); 236 else if ("moderator".equals(val)) 237 g.setMinRightSu(IUserStates.IS_MODERATOR); 238 else if ("admin".equals(val)) 239 g.setMinRightSu(IUserStates.ROLE_GOD); 240 else 241 Server.log (this, "minuserrolesu has wrong value '" + val + "' for group " + g.getRawName(), Server.MSG_STATE, Server.LVL_MINOR); 242 } else if ("soundprooffor".equals(low)) { 243 String [] roles = val.toLowerCase().split(","); 244 for (int j = 0; j < roles.length; j++) { 245 String curr = roles[j].trim(); 246 if ("vip".equals(curr)) 247 g.setState(IGroupState.SND_PRF_VIP); 248 else if ("guest".equals(curr)) 249 g.setState(IGroupState.SND_PRF_GUEST); 250 else if ("moderator".equals(curr)) 251 g.setState(IGroupState.SND_PRF_MODERATOR); 252 else if ("admin".equals(curr)) 253 g.setState(IGroupState.SND_PRF_GOD); 254 else if ("user".equals(curr)) 255 g.setState(IGroupState.SND_PRF_USER); 256 } 257 } else if ("suforbidden".equals(low)) { 258 g.setSuForbiddenMembership(val); 259 } else if ("memberroom".equals(low)) { 260 String [] memberships = val.toLowerCase().split(","); 261 Vector msObjects = new Vector (); 262 for (int j = 0; j < memberships.length; j++) { 263 Membership cms = MembershipManager.instance.getMembership(memberships[j]); 264 if (cms == null) 265 continue; 266 msObjects.add(cms); 267 } 268 g.setMemberRoom ((Membership[]) msObjects.toArray(new Membership[0])); 269 } else if ("deactivatehitdice".equals(low) && "true".equals(val)){ 270 g.setState (IGroupState.DEACTIVATE_HITDICE); 271 } else if (low.startsWith("extension.")) { 272 String namespace = low.substring(10); 273 int idx = namespace.indexOf("."); 274 if (idx == -1) { 275 Server.log (this, "invalid GroupPolicy for extension: " + low, Server.MSG_ERROR, Server.LVL_MINOR); 276 continue; 277 } 278 String propName = namespace.substring(idx+1); 279 namespace = namespace.substring(0,idx); 280 Properties p = (Properties ) map.get(namespace); 281 if (p==null) { 282 p = new Properties (); 283 map.put(namespace, p); 284 } 285 p.setProperty(propName, val); 286 } 287 } 288 if (map.size() > 0) { 289 Vector plugins = new Vector (); 290 for (Iterator i = map.keySet().iterator(); i.hasNext(); ) { 291 String namespace = (String ) i.next(); 292 Properties p = (Properties ) map.get(namespace); 293 String url = p.getProperty("url"); 294 Object o; 295 synchronized (pluginStore) { 296 o = pluginStore.get(url); 297 if (o == null) { 298 try { 299 Class piClass = Class.forName(url); 300 Method getInstance = piClass.getMethod("getMasterInstance", null); 301 if (getInstance==null) 302 throw new Exception ("Specified plugin-object doesn't implement static getMasterInstance"); 303 o = getInstance.invoke(null, null); 304 if (!(o instanceof IGroupPlugin)) 305 throw new Exception ("Specified plugin-object doesn't implement interface IGroupPlugin"); 306 pluginStore.put(url, o); 307 } catch (Exception e) { 308 Server.log (this, "invalid url for extension: " + url, Server.MSG_ERROR, Server.LVL_MINOR); 309 continue; 310 } 311 } 312 } 313 try { 314 plugins.add(((IGroupPlugin) o).instanceForGroup(namespace, g, p)); 315 } catch (Exception e) { 316 Server.debug(this, "catched exception while getting GroupPlugin-instance", e, Server.MSG_STATE, Server.LVL_MAJOR); 317 } 318 } 319 g.setPlugins((IGroupPlugin[]) plugins.toArray(new IGroupPlugin[0])); 320 } 321 return g; 322 } 323 324 public int openGroupsCount() { 325 return grps.size(); 326 } 327 328 public synchronized Group[] currentGroupList () { 329 if (grpsArr==null) 330 grpsArr=(Group[]) grps.values().toArray(new Group[0]); 331 return grpsArr; 332 } 333 334 public void updateStartingGroups (String [] sgNames) { 335 Vector curr = (Vector ) startGroups.clone(); 336 Vector updt = new Vector (); 337 for (int i = 0; i < sgNames.length; i++) { 338 String [] c = sgNames[i].split("/"); 339 String key = c[0].trim().toLowerCase(); 340 updt.add(key); 341 if (c.length>1) 342 startGroupThemes.put(key, c[1]); 343 else 344 startGroupThemes.remove(key); 345 } 346 curr.removeAll(updt); 347 updt.removeAll(startGroups); 348 startGroups.addAll(updt); 349 startGroups.removeAll(curr); 350 synchronized (GroupManager.mgr) { 351 for (Iterator i = updt.iterator(); i.hasNext(); ) { 352 String cName = (String ) i.next(); 353 Group g = (Group) grps.get(cName); 354 if (g==null) 355 continue; 356 g.setState(IGroupState.ENTRANCE); 357 } 358 for (Iterator i = curr.iterator(); i.hasNext(); ) { 359 String cName = (String ) i.next(); 360 Group g = (Group) grps.get(cName); 361 if (g==null) 362 continue; 363 g.unsetState(IGroupState.ENTRANCE); 364 } 365 } 366 } 367 368 public void updateModeratedGroups (Vector mg) { 369 Vector removed = (Vector ) moderatedGroups.clone(); 370 removed.removeAll(mg); 371 Vector added = (Vector ) mg.clone(); 372 added.removeAll(moderatedGroups); 373 for (Enumeration e = removed.elements(); e.hasMoreElements(); ) { 374 Group g = getGroup ((String ) e.nextElement()); 375 if (g==null) 376 continue; 377 while (moderatedGroups.contains(g)) 378 moderatedGroups.remove(g); 379 g.unsetState (IGroupState.MODERATED); 380 g.setState(IGroupState.OPEN); 381 } 382 for (Enumeration e = added.elements(); e.hasMoreElements(); ) { 383 String gName = (String ) e.nextElement(); 384 moderatedGroups.add(gName); 385 Group g = getGroup (gName); 386 moderatedGroups.add(g); 387 if (g==null) 388 continue; 389 g.setState(IGroupState.MODERATED); 390 g.unsetState (IGroupState.OPEN); 391 392 } 393 } 394 395 399 public boolean isStartingGroup(String grp) { 400 return startGroups.contains(grp.trim().toLowerCase()); 401 } 402 403 406 public void updateGroupListLastModified () { 407 groupListLastChange=System.currentTimeMillis(); 408 } 409 412 public long groupListLastModified() { 413 return groupListLastChange; 414 } 415 416 419 public long lastModified() { 420 return lastModified; 421 } 422 } | Popular Tags |