1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.eclipse.jetty.server.session;
21
22 import java.io.ByteArrayInputStream;
23 import java.io.ByteArrayOutputStream;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.ObjectInputStream;
27 import java.io.ObjectOutputStream;
28 import java.sql.Connection;
29 import java.sql.PreparedStatement;
30 import java.sql.ResultSet;
31 import java.sql.SQLException;
32 import java.sql.Statement;
33 import java.util.HashMap;
34 import java.util.List;
35 import java.util.ListIterator;
36 import java.util.Map;
37 import java.util.concurrent.ConcurrentHashMap;
38 import java.util.concurrent.atomic.AtomicReference;
39
40 import javax.servlet.http.HttpServletRequest;
41 import javax.servlet.http.HttpSessionEvent;
42 import javax.servlet.http.HttpSessionListener;
43
44 import org.eclipse.jetty.server.SessionIdManager;
45 import org.eclipse.jetty.server.handler.ContextHandler;
46 import org.eclipse.jetty.util.log.Log;
47 import org.eclipse.jetty.util.log.Logger;
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 public class JDBCSessionManager extends AbstractSessionManager
74 {
75 private static final Logger LOG = Log.getLogger(JDBCSessionManager.class);
76
77 private ConcurrentHashMap<String, AbstractSession> _sessions;
78 protected JDBCSessionIdManager _jdbcSessionIdMgr = null;
79 protected long _saveIntervalSec = 60;
80
81
82
83
84
85
86 public class SessionData
87 {
88 private final String _id;
89 private String _rowId;
90 private long _accessed;
91 private long _lastAccessed;
92 private long _maxIdleMs=-1;
93 private long _cookieSet;
94 private long _created;
95 private Map<String,Object> _attributes;
96 private String _lastNode;
97 private String _canonicalContext;
98 private long _lastSaved;
99 private long _expiryTime;
100 private String _virtualHost;
101
102 public SessionData (String sessionId)
103 {
104 _id=sessionId;
105 _created=System.currentTimeMillis();
106 _accessed = _created;
107 _attributes = new HashMap<String,Object>();
108 _lastNode = getSessionIdManager().getWorkerName();
109 }
110
111 public SessionData (String sessionId,Map<String,Object> attributes)
112 {
113 _id=sessionId;
114 _created=System.currentTimeMillis();
115 _accessed = _created;
116 _attributes = attributes;
117 _lastNode = getSessionIdManager().getWorkerName();
118 }
119
120 public synchronized String getId ()
121 {
122 return _id;
123 }
124
125 public synchronized long getCreated ()
126 {
127 return _created;
128 }
129
130 protected synchronized void setCreated (long ms)
131 {
132 _created = ms;
133 }
134
135 public synchronized long getAccessed ()
136 {
137 return _accessed;
138 }
139
140 protected synchronized void setAccessed (long ms)
141 {
142 _accessed = ms;
143 }
144
145
146 public synchronized void setMaxIdleMs (long ms)
147 {
148 _maxIdleMs = ms;
149 }
150
151 public synchronized long getMaxIdleMs()
152 {
153 return _maxIdleMs;
154 }
155
156 public synchronized void setLastAccessed (long ms)
157 {
158 _lastAccessed = ms;
159 }
160
161 public synchronized long getLastAccessed()
162 {
163 return _lastAccessed;
164 }
165
166 public void setCookieSet (long ms)
167 {
168 _cookieSet = ms;
169 }
170
171 public synchronized long getCookieSet ()
172 {
173 return _cookieSet;
174 }
175
176 public synchronized void setRowId (String rowId)
177 {
178 _rowId=rowId;
179 }
180
181 protected synchronized String getRowId()
182 {
183 return _rowId;
184 }
185
186 protected synchronized Map<String,Object> getAttributeMap ()
187 {
188 return _attributes;
189 }
190
191 protected synchronized void setAttributeMap (Map<String,Object> map)
192 {
193 _attributes = map;
194 }
195
196 public synchronized void setLastNode (String node)
197 {
198 _lastNode=node;
199 }
200
201 public synchronized String getLastNode ()
202 {
203 return _lastNode;
204 }
205
206 public synchronized void setCanonicalContext(String str)
207 {
208 _canonicalContext=str;
209 }
210
211 public synchronized String getCanonicalContext ()
212 {
213 return _canonicalContext;
214 }
215
216 public synchronized long getLastSaved ()
217 {
218 return _lastSaved;
219 }
220
221 public synchronized void setLastSaved (long time)
222 {
223 _lastSaved=time;
224 }
225
226 public synchronized void setExpiryTime (long time)
227 {
228 _expiryTime=time;
229 }
230
231 public synchronized long getExpiryTime ()
232 {
233 return _expiryTime;
234 }
235
236 public synchronized void setVirtualHost (String vhost)
237 {
238 _virtualHost=vhost;
239 }
240
241 public synchronized String getVirtualHost ()
242 {
243 return _virtualHost;
244 }
245
246 @Override
247 public String toString ()
248 {
249 return "Session rowId="+_rowId+",id="+_id+",lastNode="+_lastNode+
250 ",created="+_created+",accessed="+_accessed+
251 ",lastAccessed="+_lastAccessed+",cookieSet="+_cookieSet+
252 "lastSaved="+_lastSaved;
253 }
254 }
255
256
257
258
259
260
261
262
263 public class Session extends AbstractSession
264 {
265 private static final long serialVersionUID = 5208464051134226143L;
266 private final SessionData _data;
267 private boolean _dirty=false;
268
269
270
271
272
273
274 protected Session (HttpServletRequest request)
275 {
276 super(JDBCSessionManager.this,request);
277 _data = new SessionData(getClusterId(),_jdbcAttributes);
278 if (_dftMaxIdleSecs>0)
279 _data.setMaxIdleMs(_dftMaxIdleSecs*1000L);
280 _data.setCanonicalContext(canonicalize(_context.getContextPath()));
281 _data.setVirtualHost(getVirtualHost(_context));
282 int maxInterval=getMaxInactiveInterval();
283 _data.setExpiryTime(maxInterval <= 0 ? 0 : (System.currentTimeMillis() + maxInterval*1000L));
284 }
285
286
287
288
289
290 protected Session (long accessed, SessionData data)
291 {
292 super(JDBCSessionManager.this,data.getCreated(), accessed, data.getId());
293 _data=data;
294 if (_dftMaxIdleSecs>0)
295 _data.setMaxIdleMs(_dftMaxIdleSecs*1000L);
296 _jdbcAttributes.putAll(_data.getAttributeMap());
297 _data.setAttributeMap(_jdbcAttributes);
298 }
299
300 @Override
301 public void setAttribute (String name, Object value)
302 {
303 super.setAttribute(name, value);
304 _dirty=true;
305 }
306
307 @Override
308 public void removeAttribute (String name)
309 {
310 super.removeAttribute(name);
311 _dirty=true;
312 }
313
314 @Override
315 protected void cookieSet()
316 {
317 _data.setCookieSet(_data.getAccessed());
318 }
319
320
321
322
323
324
325
326 @Override
327 protected boolean access(long time)
328 {
329 if (super.access(time))
330 {
331 _data.setLastAccessed(_data.getAccessed());
332 _data.setAccessed(time);
333
334 int maxInterval=getMaxInactiveInterval();
335 _data.setExpiryTime(maxInterval <= 0 ? 0 : (time + maxInterval*1000L));
336 return true;
337 }
338 return false;
339 }
340
341
342
343
344
345 @Override
346 protected void complete()
347 {
348 super.complete();
349 try
350 {
351 if (_dirty)
352 {
353
354
355 willPassivate();
356 updateSession(_data);
357 didActivate();
358 }
359 else if ((_data._accessed - _data._lastSaved) >= (getSaveInterval() * 1000L))
360 {
361 updateSessionAccessTime(_data);
362 }
363 }
364 catch (Exception e)
365 {
366 LOG.warn("Problem persisting changed session data id="+getId(), e);
367 }
368 finally
369 {
370 _dirty=false;
371 }
372 }
373
374 @Override
375 protected void timeout() throws IllegalStateException
376 {
377 if (LOG.isDebugEnabled())
378 LOG.debug("Timing out session id="+getClusterId());
379 super.timeout();
380 }
381 }
382
383
384
385
386
387
388
389
390
391 protected class ClassLoadingObjectInputStream extends ObjectInputStream
392 {
393 public ClassLoadingObjectInputStream(java.io.InputStream in) throws IOException
394 {
395 super(in);
396 }
397
398 public ClassLoadingObjectInputStream () throws IOException
399 {
400 super();
401 }
402
403 @Override
404 public Class<?> resolveClass (java.io.ObjectStreamClass cl) throws IOException, ClassNotFoundException
405 {
406 try
407 {
408 return Class.forName(cl.getName(), false, Thread.currentThread().getContextClassLoader());
409 }
410 catch (ClassNotFoundException e)
411 {
412 return super.resolveClass(cl);
413 }
414 }
415 }
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438 public void setSaveInterval (long sec)
439 {
440 _saveIntervalSec=sec;
441 }
442
443 public long getSaveInterval ()
444 {
445 return _saveIntervalSec;
446 }
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461 public void cacheInvalidate (Session session)
462 {
463
464 }
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483 @Override
484 public Session getSession(String idInCluster)
485 {
486 Session session = (Session)_sessions.get(idInCluster);
487
488 synchronized (this)
489 {
490 try
491 {
492
493
494
495
496
497
498
499
500 SessionData data = null;
501 long now = System.currentTimeMillis();
502 if (LOG.isDebugEnabled())
503 {
504 if (session==null)
505 LOG.debug("getSession("+idInCluster+"): not in session map,"+
506 " now="+now+
507 " lastSaved="+(session==null?0:session._data._lastSaved)+
508 " interval="+(_saveIntervalSec * 1000L));
509 else
510 LOG.debug("getSession("+idInCluster+"): in session map, "+
511 " now="+now+
512 " lastSaved="+(session==null?0:session._data._lastSaved)+
513 " interval="+(_saveIntervalSec * 1000L)+
514 " lastNode="+session._data.getLastNode()+
515 " thisNode="+getSessionIdManager().getWorkerName()+
516 " difference="+(now - session._data._lastSaved));
517 }
518
519 if (session==null || ((now - session._data._lastSaved) >= (_saveIntervalSec * 1000L)))
520 {
521 LOG.debug("getSession("+idInCluster+"): no session in session map or stale session. Reloading session data from db.");
522 data = loadSession(idInCluster, canonicalize(_context.getContextPath()), getVirtualHost(_context));
523 }
524 else if ((now - session._data._lastSaved) >= (_saveIntervalSec * 1000L))
525 {
526 LOG.debug("getSession("+idInCluster+"): stale session. Reloading session data from db.");
527 data = loadSession(idInCluster, canonicalize(_context.getContextPath()), getVirtualHost(_context));
528 }
529 else
530 {
531 LOG.debug("getSession("+idInCluster+"): session in session map");
532 data = session._data;
533 }
534
535 if (data != null)
536 {
537 if (!data.getLastNode().equals(getSessionIdManager().getWorkerName()) || session==null)
538 {
539
540 if (data._expiryTime <= 0 || data._expiryTime > now)
541 {
542 LOG.debug("getSession("+idInCluster+"): lastNode="+data.getLastNode()+" thisNode="+getSessionIdManager().getWorkerName());
543 data.setLastNode(getSessionIdManager().getWorkerName());
544
545 session = new Session(now,data);
546 _sessions.put(idInCluster, session);
547 session.didActivate();
548
549
550 updateSessionNode(data);
551 }
552 else
553 if (LOG.isDebugEnabled()) LOG.debug("getSession("+idInCluster+"): Session has expired");
554
555 }
556 else
557 if (LOG.isDebugEnabled()) LOG.debug("getSession("+idInCluster+"): Session not stale "+session._data);
558
559 }
560 else
561 {
562
563 session=null;
564 if (LOG.isDebugEnabled()) LOG.debug("getSession("+idInCluster+"): No session in database matching id="+idInCluster);
565 }
566
567 return session;
568 }
569 catch (Exception e)
570 {
571 LOG.warn("Unable to load session from database", e);
572 return null;
573 }
574 }
575 }
576
577
578
579
580
581
582 @Override
583 public int getSessions()
584 {
585 int size = 0;
586 synchronized (this)
587 {
588 size = _sessions.size();
589 }
590 return size;
591 }
592
593
594
595
596
597
598
599 @Override
600 public void doStart() throws Exception
601 {
602 if (_sessionIdManager==null)
603 throw new IllegalStateException("No session id manager defined");
604
605 _jdbcSessionIdMgr = (JDBCSessionIdManager)_sessionIdManager;
606
607 _sessions = new ConcurrentHashMap<String, AbstractSession>();
608 super.doStart();
609 }
610
611
612
613
614
615
616
617 @Override
618 public void doStop() throws Exception
619 {
620 _sessions.clear();
621 _sessions = null;
622
623 super.doStop();
624 }
625
626 @Override
627 protected void invalidateSessions()
628 {
629
630
631
632
633
634
635 }
636
637
638
639
640
641
642
643 protected void invalidateSession (String idInCluster)
644 {
645 Session session = null;
646 synchronized (this)
647 {
648 session = (Session)_sessions.get(idInCluster);
649 }
650
651 if (session != null)
652 {
653 session.invalidate();
654 }
655 }
656
657
658
659
660
661
662
663 @Override
664 protected boolean removeSession(String idInCluster)
665 {
666 synchronized (this)
667 {
668 Session session = (Session)_sessions.remove(idInCluster);
669 try
670 {
671 if (session != null)
672 deleteSession(session._data);
673 }
674 catch (Exception e)
675 {
676 LOG.warn("Problem deleting session id="+idInCluster, e);
677 }
678 return session!=null;
679 }
680 }
681
682
683
684
685
686
687
688 @Override
689 protected void addSession(AbstractSession session)
690 {
691 if (session==null)
692 return;
693
694 synchronized (this)
695 {
696 _sessions.put(session.getClusterId(), session);
697 }
698
699
700
701 try
702 {
703 session.willPassivate();
704 storeSession(((JDBCSessionManager.Session)session)._data);
705 session.didActivate();
706 }
707 catch (Exception e)
708 {
709 LOG.warn("Unable to store new session id="+session.getId() , e);
710 }
711 }
712
713
714
715
716
717
718
719 @Override
720 protected AbstractSession newSession(HttpServletRequest request)
721 {
722 return new Session(request);
723 }
724
725
726
727
728
729
730
731 @Override
732 public void removeSession(AbstractSession session, boolean invalidate)
733 {
734
735 boolean removed = false;
736
737 synchronized (this)
738 {
739
740 if (getSession(session.getClusterId()) != null)
741 {
742 removed = true;
743 removeSession(session.getClusterId());
744 }
745 }
746
747 if (removed)
748 {
749
750 _sessionIdManager.removeSession(session);
751
752 if (invalidate)
753 _sessionIdManager.invalidateAll(session.getClusterId());
754
755 if (invalidate && !_sessionListeners.isEmpty())
756 {
757 HttpSessionEvent event=new HttpSessionEvent(session);
758 for (HttpSessionListener l : _sessionListeners)
759 l.sessionDestroyed(event);
760 }
761 if (!invalidate)
762 {
763 session.willPassivate();
764 }
765 }
766 }
767
768
769
770
771
772
773
774
775 protected void expire (List<?> sessionIds)
776 {
777
778 if (isStopping() || isStopped())
779 return;
780
781
782 Thread thread=Thread.currentThread();
783 ClassLoader old_loader=thread.getContextClassLoader();
784 ListIterator<?> itor = sessionIds.listIterator();
785
786 try
787 {
788 while (itor.hasNext())
789 {
790 String sessionId = (String)itor.next();
791 if (LOG.isDebugEnabled())
792 LOG.debug("Expiring session id "+sessionId);
793
794 Session session = (Session)_sessions.get(sessionId);
795 if (session != null)
796 {
797 session.timeout();
798 itor.remove();
799 }
800 else
801 {
802 if (LOG.isDebugEnabled())
803 LOG.debug("Unrecognized session id="+sessionId);
804 }
805 }
806 }
807 catch (Throwable t)
808 {
809 LOG.warn("Problem expiring sessions", t);
810 }
811 finally
812 {
813 thread.setContextClassLoader(old_loader);
814 }
815 }
816
817
818
819
820
821
822
823
824 protected SessionData loadSession (final String id, final String canonicalContextPath, final String vhost)
825 throws Exception
826 {
827 final AtomicReference<SessionData> _reference = new AtomicReference<SessionData>();
828 final AtomicReference<Exception> _exception = new AtomicReference<Exception>();
829 Runnable load = new Runnable()
830 {
831 @SuppressWarnings("unchecked")
832 public void run()
833 {
834 SessionData data = null;
835 Connection connection=null;
836 PreparedStatement statement = null;
837 try
838 {
839 connection = getConnection();
840 statement = _jdbcSessionIdMgr._dbAdaptor.getLoadStatement(connection, id, canonicalContextPath, vhost);
841 ResultSet result = statement.executeQuery();
842 if (result.next())
843 {
844 data = new SessionData(id);
845 data.setRowId(result.getString(_jdbcSessionIdMgr._sessionTableRowId));
846 data.setCookieSet(result.getLong("cookieTime"));
847 data.setLastAccessed(result.getLong("lastAccessTime"));
848 data.setAccessed (result.getLong("accessTime"));
849 data.setCreated(result.getLong("createTime"));
850 data.setLastNode(result.getString("lastNode"));
851 data.setLastSaved(result.getLong("lastSavedTime"));
852 data.setExpiryTime(result.getLong("expiryTime"));
853 data.setCanonicalContext(result.getString("contextPath"));
854 data.setVirtualHost(result.getString("virtualHost"));
855
856 InputStream is = ((JDBCSessionIdManager)getSessionIdManager())._dbAdaptor.getBlobInputStream(result, "map");
857 ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream (is);
858 Object o = ois.readObject();
859 data.setAttributeMap((Map<String,Object>)o);
860 ois.close();
861
862 if (LOG.isDebugEnabled())
863 LOG.debug("LOADED session "+data);
864 }
865 _reference.set(data);
866 }
867 catch (Exception e)
868 {
869 _exception.set(e);
870 }
871 finally
872 {
873 if (connection!=null)
874 {
875 try { connection.close();}
876 catch(Exception e) { LOG.warn(e); }
877 }
878 }
879 }
880 };
881
882 if (_context==null)
883 load.run();
884 else
885 _context.getContextHandler().handle(load);
886
887 if (_exception.get()!=null)
888 throw _exception.get();
889
890 return _reference.get();
891 }
892
893
894
895
896
897
898
899 protected void storeSession (SessionData data)
900 throws Exception
901 {
902 if (data==null)
903 return;
904
905
906 Connection connection = getConnection();
907 PreparedStatement statement = null;
908 try
909 {
910 String rowId = calculateRowId(data);
911
912 long now = System.currentTimeMillis();
913 connection.setAutoCommit(true);
914 statement = connection.prepareStatement(_jdbcSessionIdMgr._insertSession);
915 statement.setString(1, rowId);
916 statement.setString(2, data.getId());
917 statement.setString(3, data.getCanonicalContext());
918 statement.setString(4, data.getVirtualHost());
919 statement.setString(5, getSessionIdManager().getWorkerName());
920 statement.setLong(6, data.getAccessed());
921 statement.setLong(7, data.getLastAccessed());
922 statement.setLong(8, data.getCreated());
923 statement.setLong(9, data.getCookieSet());
924 statement.setLong(10, now);
925 statement.setLong(11, data.getExpiryTime());
926
927 ByteArrayOutputStream baos = new ByteArrayOutputStream();
928 ObjectOutputStream oos = new ObjectOutputStream(baos);
929 oos.writeObject(data.getAttributeMap());
930 byte[] bytes = baos.toByteArray();
931
932 ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
933 statement.setBinaryStream(12, bais, bytes.length);
934
935 statement.executeUpdate();
936 data.setRowId(rowId);
937 data.setLastSaved(now);
938
939
940 if (LOG.isDebugEnabled())
941 LOG.debug("Stored session "+data);
942 }
943 finally
944 {
945 if (connection!=null)
946 connection.close();
947 }
948 }
949
950
951
952
953
954
955
956
957 protected void updateSession (SessionData data)
958 throws Exception
959 {
960 if (data==null)
961 return;
962
963 Connection connection = getConnection();
964 PreparedStatement statement = null;
965 try
966 {
967 long now = System.currentTimeMillis();
968 connection.setAutoCommit(true);
969 statement = connection.prepareStatement(_jdbcSessionIdMgr._updateSession);
970 statement.setString(1, getSessionIdManager().getWorkerName());
971 statement.setLong(2, data.getAccessed());
972 statement.setLong(3, data.getLastAccessed());
973 statement.setLong(4, now);
974 statement.setLong(5, data.getExpiryTime());
975
976 ByteArrayOutputStream baos = new ByteArrayOutputStream();
977 ObjectOutputStream oos = new ObjectOutputStream(baos);
978 oos.writeObject(data.getAttributeMap());
979 byte[] bytes = baos.toByteArray();
980 ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
981
982 statement.setBinaryStream(6, bais, bytes.length);
983 statement.setString(7, data.getRowId());
984 statement.executeUpdate();
985
986 data.setLastSaved(now);
987 if (LOG.isDebugEnabled())
988 LOG.debug("Updated session "+data);
989 }
990 finally
991 {
992 if (connection!=null)
993 connection.close();
994 }
995 }
996
997
998
999
1000
1001
1002
1003
1004 protected void updateSessionNode (SessionData data)
1005 throws Exception
1006 {
1007 String nodeId = getSessionIdManager().getWorkerName();
1008 Connection connection = getConnection();
1009 PreparedStatement statement = null;
1010 try
1011 {
1012 connection.setAutoCommit(true);
1013 statement = connection.prepareStatement(_jdbcSessionIdMgr._updateSessionNode);
1014 statement.setString(1, nodeId);
1015 statement.setString(2, data.getRowId());
1016 statement.executeUpdate();
1017 statement.close();
1018 if (LOG.isDebugEnabled())
1019 LOG.debug("Updated last node for session id="+data.getId()+", lastNode = "+nodeId);
1020 }
1021 finally
1022 {
1023 if (connection!=null)
1024 connection.close();
1025 }
1026 }
1027
1028
1029
1030
1031
1032
1033
1034 private void updateSessionAccessTime (SessionData data)
1035 throws Exception
1036 {
1037 Connection connection = getConnection();
1038 PreparedStatement statement = null;
1039 try
1040 {
1041 long now = System.currentTimeMillis();
1042 connection.setAutoCommit(true);
1043 statement = connection.prepareStatement(_jdbcSessionIdMgr._updateSessionAccessTime);
1044 statement.setString(1, getSessionIdManager().getWorkerName());
1045 statement.setLong(2, data.getAccessed());
1046 statement.setLong(3, data.getLastAccessed());
1047 statement.setLong(4, now);
1048 statement.setLong(5, data.getExpiryTime());
1049 statement.setString(6, data.getRowId());
1050 statement.executeUpdate();
1051 data.setLastSaved(now);
1052 statement.close();
1053 if (LOG.isDebugEnabled())
1054 LOG.debug("Updated access time session id="+data.getId());
1055 }
1056 finally
1057 {
1058 if (connection!=null)
1059 connection.close();
1060 }
1061 }
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073 protected void deleteSession (SessionData data)
1074 throws Exception
1075 {
1076 Connection connection = getConnection();
1077 PreparedStatement statement = null;
1078 try
1079 {
1080 connection.setAutoCommit(true);
1081 statement = connection.prepareStatement(_jdbcSessionIdMgr._deleteSession);
1082 statement.setString(1, data.getRowId());
1083 statement.executeUpdate();
1084 if (LOG.isDebugEnabled())
1085 LOG.debug("Deleted Session "+data);
1086 }
1087 finally
1088 {
1089 if (connection!=null)
1090 connection.close();
1091 }
1092 }
1093
1094
1095
1096
1097
1098
1099
1100
1101 private Connection getConnection ()
1102 throws SQLException
1103 {
1104 return ((JDBCSessionIdManager)getSessionIdManager()).getConnection();
1105 }
1106
1107
1108
1109
1110
1111
1112
1113
1114 private String calculateRowId (SessionData data)
1115 {
1116 String rowId = canonicalize(_context.getContextPath());
1117 rowId = rowId + "_" + getVirtualHost(_context);
1118 rowId = rowId+"_"+data.getId();
1119 return rowId;
1120 }
1121
1122
1123
1124
1125
1126
1127
1128
1129 private String getVirtualHost (ContextHandler.Context context)
1130 {
1131 String vhost = "0.0.0.0";
1132
1133 if (context==null)
1134 return vhost;
1135
1136 String [] vhosts = context.getContextHandler().getVirtualHosts();
1137 if (vhosts==null || vhosts.length==0 || vhosts[0]==null)
1138 return vhost;
1139
1140 return vhosts[0];
1141 }
1142
1143
1144
1145
1146
1147
1148
1149 private String canonicalize (String path)
1150 {
1151 if (path==null)
1152 return "";
1153
1154 return path.replace('/', '_').replace('.','_').replace('\\','_');
1155 }
1156 }