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