1 18 package freecs.layout; 19 20 import freecs.Server; 21 import freecs.commands.AbstractCommand; 22 import freecs.commands.CommandSet; 23 import freecs.content.MessageState; 24 import freecs.core.*; 25 import freecs.util.FileMonitor; 26 import freecs.interfaces.IReloadable; 27 import freecs.interfaces.IRequest; 28 29 import java.io.*; 30 import java.util.*; 31 32 public class Template implements IReloadable { 33 private static final int DEPENDS_ON_NOTHING = 0; 34 private static final int DEPENDS_ON_SERVER_CONFIG = 1; 35 private static final int DEPENDS_ON_USER_COUNT = 2; 36 private static final int DEPENDS_ON_GROUP_COUNT = 4; 37 private static final int DEPENDS_ON_GROUP_LIST = 8; 38 private static final int DEPENDS_ON_SESSION =16; 39 private int dependsOn=DEPENDS_ON_NOTHING; 40 41 private volatile String eTag=null; 42 private volatile long modifiedSince=0; 43 44 private volatile String [] parts; 45 private String tsName; 46 private String name; 47 private boolean isRedirect; 48 private String destination; 49 private TemplateSet ts; 50 51 private File template; 52 private long lastModified; 53 private boolean tplPresent; 54 55 public String getDestination () { 56 return destination; 57 } 58 59 public boolean isRedirect () { 60 return isRedirect; 61 } 62 63 public String getTsName () { 64 return tsName; 65 } 66 67 public boolean hasToBeRendered (String eTag, long modifiedSince) { 68 if (eTag==null && modifiedSince==-1) 69 return true; 70 if (eTag != null) { 71 this.eTag = this.generateETag(); 72 if ((this.dependsOn & Template.DEPENDS_ON_SESSION)!=0 73 || !eTag.equals(this.eTag)) return true; 75 } else if (this.modifiedSince>modifiedSince) 76 return true; 77 return false; 78 } 79 80 public String render (IRequest req) { 81 83 StringBuffer retVal = new StringBuffer (); 84 for (int i = 0; i < parts.length; i++) { 85 String part = parts[i]; 86 if (!part.startsWith ("#")) { 87 retVal.append (part); 88 continue; 89 } 90 if (part.regionMatches 91 (true, 0, "#active_users", 0, "#active_users".length())) { 92 retVal.append (UserManager.mgr.getActiveUserCount ()); 93 } else if (part.regionMatches 94 (true, 0, "#active_user_list", 0, "#active_user_list".length())) { 95 retVal.append(generateUserList()); 96 } else if (part.regionMatches 97 (true, 0, "#users_in_group", 0, "#users_in_group".length())) { 98 retVal.append (generateUserList(req)); 99 } else if (part.regionMatches 100 (true, 0, "#open_groups", 0, "#open_groups".length())) { 101 retVal.append (GroupManager.mgr.openGroupsCount()); 102 } else if (part.regionMatches 103 (true, 0, "#selve", 0, "#selve".length())) { 104 retVal.append ("http://"); 105 retVal.append (Server.srv.getUrl ()); 106 } else if (part.regionMatches 107 (true, 0, "#token", 0, "#token".length())) { 108 StringBuffer c = new StringBuffer (); 109 while (c.length () < 16) { 110 char x = (char) Math.ceil(Math.random() * 34); 111 if (x < 10) x = (char) (x + 48); 112 else x = (char) (x + 87); 113 c.append(x); 114 } 115 retVal.append (c); 116 Server.srv.addToken(c.toString(), req.getCookie()); 117 } else if (part.regionMatches 118 (true, 0, "#config.", 0, "#config.".length())) { 119 retVal.append(Server.srv.props.getProperty(part.substring(8).trim())); 120 } 121 } 122 String [] arr = new String [2]; 123 return retVal.toString(); 124 } 125 126 private String generateETag() { 127 if ((this.dependsOn & Template.DEPENDS_ON_SESSION) != 0) 128 return null; 129 if (modifiedSince < this.lastModified) 130 modifiedSince = this.lastModified; 131 StringBuffer sb = new StringBuffer (); 132 sb.append (Long.toHexString(this.lastModified/500)); 133 if ((this.dependsOn & Template.DEPENDS_ON_SERVER_CONFIG) != 0) { 134 sb.append ("pc").append(Long.toHexString(Server.srv.lastModified()/500)); 135 if (modifiedSince < Server.srv.lastModified()) 136 modifiedSince = Server.srv.lastModified(); 137 } 138 if ((this.dependsOn & Template.DEPENDS_ON_USER_COUNT) != 0) { 139 sb.append ("puc").append(Long.toHexString(UserManager.mgr.lastModified()/500)); 140 if (modifiedSince < UserManager.mgr.lastModified()) 141 modifiedSince = UserManager.mgr.lastModified(); 142 } 143 if ((this.dependsOn & Template.DEPENDS_ON_GROUP_COUNT) != 0) { 144 sb.append ("pgc").append(Long.toHexString(GroupManager.mgr.lastModified()/500)); 145 if (modifiedSince < GroupManager.mgr.lastModified()) 146 modifiedSince = GroupManager.mgr.lastModified(); 147 } 148 if ((this.dependsOn & Template.DEPENDS_ON_GROUP_LIST) != 0) { 149 sb.append ("pgl").append(Long.toHexString(GroupManager.mgr.groupListLastModified()/500)); 150 if (modifiedSince < GroupManager.mgr.groupListLastModified()) 151 modifiedSince = GroupManager.mgr.groupListLastModified(); 152 } 153 return sb.toString(); 154 } 155 156 public String getName () { 157 return name; 158 } 159 160 public Template(File tpl, TemplateSet ts) throws IOException { 161 this.tsName = ts.getName(); 162 this.ts = ts; 163 template = tpl; 164 name = tpl.getName (); 165 int pos = name.indexOf ("."); 166 if (pos != -1) 167 name = name.substring (0, pos); 168 lastModified = tpl.lastModified (); 169 parts = parseFile(tpl); 170 tplPresent=true; 171 FileMonitor.getFileMonitor ().addReloadable (this); 172 } 173 174 public boolean isValide () { 175 return ((parts != null && parts.length > 0) || 176 (destination != null && destination.length() > 1 && isRedirect == true)); 177 } 178 179 private String [] parseFile(File tpl) throws IOException { 180 if (!tpl.canRead()) { 181 StringBuffer tsb = new StringBuffer ("Unable to read template '").append (tpl.getName()).append ("'"); 182 throw new IOException(tsb.toString ()); 183 } 184 this.dependsOn = Template.DEPENDS_ON_NOTHING; 185 186 Vector t = new Vector (); 187 FileReader fr = new FileReader(tpl); 188 char fcnt[] = new char[(int) tpl.length()]; 189 int read = fr.read(fcnt); 190 if (read<1) return null; 191 String raw = String.copyValueOf(fcnt); 192 if (raw.toLowerCase ().startsWith ("#redirect#")) { 193 this.isRedirect = true; 194 destination = raw.substring (raw.lastIndexOf("#") + 1).trim (); 195 if (destination.toLowerCase ().startsWith ("$selve$")) { 196 StringBuffer tsb = new StringBuffer ("http://").append (Server.srv.getUrl ()); 197 destination = tsb.toString (); 198 this.dependsOn = this.dependsOn | Template.DEPENDS_ON_SERVER_CONFIG; 199 } else if (!destination.toLowerCase ().startsWith ("http://")) { 200 StringBuffer tsb = new StringBuffer ("http://").append (destination); 201 destination = tsb.toString (); 202 } 203 } 204 205 boolean lt=false, placeholder=false; 206 StringTokenizer tok = new StringTokenizer (raw, "<%>", true); 207 StringBuffer currPlaceHolder = new StringBuffer (), 208 currPart = new StringBuffer (); 209 210 while (tok.hasMoreElements()) { 211 String curr = tok.nextToken(); 212 if (curr.equals("<")) { 213 if (lt) 214 currPart.append("<"); 215 else 216 lt=true; 217 } else if (lt && curr.equals("%")) { 218 placeholder=true; 219 currPlaceHolder.append("#"); 220 while (placeholder) { 221 curr=tok.nextToken(); 222 if (curr.equals("%")) { 223 curr = tok.nextToken(); 224 if (curr.equals(">")) { 225 placeholder=false; 226 lt=false; 227 } else { 228 currPlaceHolder.append("%"); 229 currPlaceHolder.append(curr); 230 } 231 } else { 232 currPlaceHolder.append(curr.trim()); 233 } 234 } 235 String cplh = currPlaceHolder.toString(); 236 lt=false; 237 currPlaceHolder = new StringBuffer (); 238 if (cplh.equals("#active_users")) { 239 this.dependsOn = this.dependsOn 240 | Template.DEPENDS_ON_USER_COUNT; 241 } else if (cplh.equals("#active_user_list")) { 242 this.dependsOn = this.dependsOn 243 | Template.DEPENDS_ON_GROUP_LIST; 244 } else if (cplh.startsWith("#users_in_group") 245 || cplh.equals("#token")) { 246 this.dependsOn = this.dependsOn 247 | Template.DEPENDS_ON_SESSION; 248 } else if (cplh.equals("#open_groups")) { 249 this.dependsOn = this.dependsOn 250 | Template.DEPENDS_ON_GROUP_COUNT; 251 } else if (cplh.equals("#selve")) { 252 this.dependsOn = this.dependsOn 253 | Template.DEPENDS_ON_SERVER_CONFIG; 254 } else if (cplh.startsWith("#config")) { 255 this.dependsOn = this.dependsOn 257 | Template.DEPENDS_ON_SERVER_CONFIG; 258 } 259 if (cplh.toLowerCase().equals("#version")) { 260 currPart.append(Server.getVersion()); 261 } else { 262 t.addElement(currPart.toString()); 263 t.addElement(cplh); 264 currPart = new StringBuffer (); 265 } 266 } else if (lt) { 267 currPart.append("<"); 268 currPart.append(curr); 269 lt = false; 270 } else { 271 currPart.append(curr); 272 } 273 } 274 if (currPart.length()>0) { 275 t.addElement(currPart.toString()); 276 } 277 if (currPlaceHolder.length()>0) { 278 t.addElement(currPlaceHolder.toString()); 279 } 280 297 return((String []) t.toArray(new String [0])); 298 } 299 300 public String generateUserList (IRequest req) { 301 String strg = req.getValue("user"); 302 Group g = null; 303 if (strg==null) 304 strg = req.getValue("group"); 305 else { 306 User u = UserManager.mgr.getUserByName(strg); 307 if (u==null) 308 return "no such user: " + strg; 309 } 310 MessageState msgState = new MessageState(null); 311 if (strg==null) { 312 strg = req.getCookie(); 313 if (strg == null) 314 return "no cookie to get a user for"; 315 User u = UserManager.mgr.getUserByCookie(strg); 316 if (u == null) 317 return "no user to generate userlist for"; 318 msgState.sender = u; 319 g = u.getGroup(); 320 } 321 if (g==null) { 322 g = GroupManager.mgr.getGroup(strg); 323 } 324 if (g==null) 325 return ("unable to determine group"); 326 msgState.message = generateUserList (msgState, g); 327 return MessageRenderer.renderTemplate(msgState, ts.getMessageTemplate("list.users")); 328 } 329 330 public String generateUserList (MessageState msgState, Group cg) { 331 msgState.sourceGroup=cg; 332 msgState.targetGroup=cg; 333 return ((AbstractCommand) CommandSet.getCommandSet().getCommand("/wc")).generateUserList(msgState, true, ts); 334 } 335 336 public String generateUserList () { 337 CommandSet cs = CommandSet.getCommandSet(); 338 MessageState msgState = new MessageState(null); 339 msgState.useRenderCache = false; 340 UserManager umgr = UserManager.mgr; 341 StringBuffer sb = new StringBuffer (); 342 Group[] grps = GroupManager.mgr.currentGroupList(); 343 for (int i = 0; i < grps.length; i++) { 344 Group g = grps[i]; 345 if (g.size() < 1 || !g.isValid()) 346 continue; 347 msgState.message = generateUserList(msgState, g); 348 sb.append (MessageRenderer.renderTemplate(msgState, ts.getMessageTemplate("list.users"))); 349 } 350 return sb.toString(); 351 } 352 353 354 public long lastModified () { 355 return lastModified; 356 } 357 358 public void changed () { 359 try { 360 parts = parseFile(template); 361 Server.log (this, "reload: reloaded template", Server.MSG_STATE, Server.LVL_MINOR); 362 lastModified = template.lastModified (); 363 } catch (Exception e) { 364 Server.debug (this, "reload: ", e, Server.MSG_ERROR, Server.LVL_MAJOR); 365 } 366 } 367 368 public void removed () { 369 ts.removeTemplate(this); 370 tplPresent=false; 371 } 372 373 public boolean filePresent () { 374 return tplPresent; 375 } 376 public void created() { 377 changed(); 378 ts.addTemplate(this); 379 tplPresent=true; 380 } 381 382 public File getFile () { 383 return template; 384 } 385 386 public String getEtag() { 387 return eTag; 388 } 389 390 private volatile String strgVal; 391 public String toString() { 392 if (strgVal==null) { 393 StringBuffer sb = new StringBuffer ("[Template: "); 394 sb.append (tsName); 395 sb.append ("/"); 396 sb.append (name); 397 sb.append ("]"); 398 strgVal = sb.toString(); 399 } 400 return strgVal; 401 } 402 403 406 public boolean notCacheable() { 407 if ((dependsOn & (DEPENDS_ON_SESSION 408 | DEPENDS_ON_GROUP_LIST)) != 0) 409 return true; 410 return false; 411 } 412 } | Popular Tags |