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