001: /*
002:
003: Derby - Class org.apache.derby.impl.drda.Session
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to You under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.drda;
023:
024: import java.io.IOException;
025: import java.io.InputStream;
026: import java.io.OutputStream;
027: import java.net.Socket;
028: import java.util.Enumeration;
029: import java.util.Hashtable;
030: import org.apache.derby.iapi.tools.i18n.LocalizedResource;
031: import java.sql.SQLException;
032:
033: /**
034: Session stores information about the current session
035: It is used so that a DRDAConnThread can work on any session.
036: */
037: class Session {
038:
039: // session states
040: protected static final int INIT = 1; // before exchange of server attributes
041: protected static final int ATTEXC = 2; // after first exchange of server attributes
042: protected static final int SECACC = 3; // after ACCSEC (Security Manager Accessed)
043: protected static final int CHKSEC = 4; // after SECCHK (Checked Security)
044: protected static final int CLOSED = 5; // session has ended
045:
046: // session types
047: protected static final int DRDA_SESSION = 1;
048: protected static final int CMD_SESSION = 2;
049:
050: // trace name prefix and suffix
051: private static final String TRACENAME_PREFIX = "Server";
052: private static final String TRACENAME_SUFFIX = ".trace";
053:
054: // session information
055: protected Socket clientSocket; // session socket
056: protected int connNum; // connection number
057: protected InputStream sessionInput; // session input stream
058: protected OutputStream sessionOutput; // session output stream
059: protected String traceFileName; // trace file name for session
060: protected boolean traceOn; // whether trace is currently on for the session
061: protected int state; // the current state of the session
062: protected int sessionType; // type of session - DRDA or NetworkServerControl command
063: protected String drdaID; // DRDA ID of the session
064: protected DssTrace dssTrace; // trace object associated with the session
065: protected AppRequester appRequester; // Application requester for this session
066: protected Database database; // current database
067: protected int qryinsid; // unique identifier for each query
068: protected LocalizedResource langUtil; // localization information for command session
069: // client
070:
071: private Hashtable dbtable; // Table of databases accessed in this session
072:
073: // constructor
074: /**
075: * Session constructor
076: *
077: * @param connNum connection number
078: * @param clientSocket communications socket for this session
079: * @param traceDirectory location for trace files
080: * @param traceOn whether to start tracing this connection
081: *
082: * @exception throws IOException
083: */
084: Session(int connNum, Socket clientSocket, String traceDirectory,
085: boolean traceOn) throws IOException {
086: this .connNum = connNum;
087: this .clientSocket = clientSocket;
088: this .traceOn = traceOn;
089: if (traceOn)
090: dssTrace = new DssTrace();
091: dbtable = new Hashtable();
092: initialize(traceDirectory);
093: }
094:
095: /**
096: * Close session - close connection sockets and set state to closed
097: *
098: */
099: protected void close() throws SQLException {
100:
101: try {
102: sessionInput.close();
103: sessionOutput.close();
104: clientSocket.close();
105: if (dbtable != null)
106: for (Enumeration e = dbtable.elements(); e
107: .hasMoreElements();) {
108: ((Database) e.nextElement()).close();
109: }
110:
111: } catch (IOException e) {
112: } // ignore IOException when we are shutting down
113: finally {
114: state = CLOSED;
115: dbtable = null;
116: database = null;
117: }
118: }
119:
120: /**
121: * initialize a server trace for the DRDA protocol
122: *
123: * @param traceDirectory - directory for trace file
124: */
125: protected void initTrace(String traceDirectory) {
126: if (traceDirectory != null)
127: traceFileName = traceDirectory + "/" + TRACENAME_PREFIX
128: + connNum + TRACENAME_SUFFIX;
129: else
130: traceFileName = TRACENAME_PREFIX + connNum
131: + TRACENAME_SUFFIX;
132: traceOn = true;
133: if (dssTrace == null)
134: dssTrace = new DssTrace();
135: dssTrace.startComBufferTrace(traceFileName);
136: }
137:
138: /**
139: * Set tracing on
140: *
141: * @param traceDirectory directory for trace files
142: */
143: protected void setTraceOn(String traceDirectory) {
144: if (traceOn)
145: return;
146: initTrace(traceDirectory);
147: }
148:
149: /**
150: * Get whether tracing is on
151: *
152: * @return true if tracing is on false otherwise
153: */
154: protected boolean isTraceOn() {
155: if (traceOn)
156: return true;
157: else
158: return false;
159: }
160:
161: /**
162: * Get connection number
163: *
164: * @return connection number
165: */
166: protected int getConnNum() {
167: return connNum;
168: }
169:
170: /**
171: * Set tracing off
172: *
173: */
174: protected void setTraceOff() {
175: if (!traceOn)
176: return;
177: traceOn = false;
178: if (traceFileName != null)
179: dssTrace.stopComBufferTrace();
180: }
181:
182: /**
183: * Add database to session table
184: */
185: protected void addDatabase(Database d) {
186: dbtable.put(d.dbName, d);
187: }
188:
189: /**
190: * Get database
191: */
192: protected Database getDatabase(String dbName) {
193: return (Database) dbtable.get(dbName);
194: }
195:
196: /**
197: * Get requried security checkpoint.
198: * Used to verify EXCSAT/ACCSEC/SECCHK order.
199: *
200: * @return next required Security checkpoint or -1 if
201: * neither ACCSEC or SECCHK are required at this time.
202: *
203: */
204: protected int getRequiredSecurityCodepoint() {
205: switch (state) {
206: case ATTEXC:
207: // On initial exchange of attributes we require ACCSEC
208: // to access security manager
209: return CodePoint.ACCSEC;
210: case SECACC:
211: // After security manager has been accessed successfully we
212: // require SECCHK to check security
213: return CodePoint.SECCHK;
214: default:
215: return -1;
216: }
217: }
218:
219: /**
220: * Check if a security codepoint is required
221: *
222: * @return true if ACCSEC or SECCHK are required at this time.
223: */
224: protected boolean requiresSecurityCodepoint() {
225: return (getRequiredSecurityCodepoint() != -1);
226: }
227:
228: /**
229: * Set Session state
230: *
231: */
232: protected void setState(int s) {
233: state = s;
234: }
235:
236: /**
237: * Get session into initial state
238: *
239: * @param traceDirectory - directory for trace files
240: */
241: private void initialize(String traceDirectory) throws IOException {
242: sessionInput = clientSocket.getInputStream();
243: sessionOutput = clientSocket.getOutputStream();
244: if (traceOn)
245: initTrace(traceDirectory);
246: state = INIT;
247: }
248:
249: protected String buildRuntimeInfo(String indent,
250: LocalizedResource localLangUtil) {
251: String s = "";
252: s += indent
253: + localLangUtil
254: .getTextMessage("DRDA_RuntimeInfoSessionNumber.I")
255: + connNum + "\n";
256: if (database == null)
257: return s;
258: s += database.buildRuntimeInfo(indent, localLangUtil);
259: s += "\n";
260: return s;
261: }
262: }
|