001: /*
002:
003: Derby - Class org.apache.derby.client.net.NetConnectionRequest
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.client.net;
023:
024: import javax.transaction.xa.Xid;
025:
026: import org.apache.derby.client.am.SqlException;
027: import org.apache.derby.client.am.ClientMessageId;
028: import org.apache.derby.client.am.Utils;
029: import org.apache.derby.shared.common.reference.SQLState;
030:
031: public class NetConnectionRequest extends Request implements
032: ConnectionRequestInterface {
033: NetConnectionRequest(NetAgent netAgent, CcsidManager ccsidManager,
034: int bufferSize) {
035: super (netAgent, ccsidManager, bufferSize);
036: }
037:
038: //----------------------------- entry points ---------------------------------
039:
040: void writeExchangeServerAttributes(String externalName,
041: int targetAgent, int targetSqlam, int targetRdb,
042: int targetSecmgr, int targetCmntcpip, int targetCmnappc,
043: int targetXamgr, int targetSyncptmgr, int targetRsyncmgr)
044: throws SqlException {
045: // send the exchange server attributes command to the server.
046: // no other commands will be chained to the excsat because
047: // the manager levels are needed before anything else is attempted.
048: buildEXCSAT(externalName, targetAgent, targetSqlam, targetRdb,
049: targetSecmgr, targetCmntcpip, targetCmnappc,
050: targetXamgr, targetSyncptmgr, targetRsyncmgr);
051:
052: }
053:
054: void writeDummyExchangeServerAttributes() throws SqlException {
055: // send the exchange server attributes command to the server,
056: // without any parameters
057: buildDummyEXCSAT();
058: }
059:
060: void writeAccessSecurity(int securityMechanism,
061: String databaseName, byte[] publicKey) throws SqlException {
062: buildACCSEC(securityMechanism, databaseName, publicKey);
063: }
064:
065: void writeSecurityCheck(int securityMechanism, String databaseName,
066: String userid, String password, byte[] encryptedUserid,
067: byte[] encryptedPassword) throws SqlException {
068: buildSECCHK(securityMechanism, databaseName, userid, password,
069: encryptedUserid, encryptedPassword);
070: }
071:
072: void writeAccessDatabase(String rdbnam, boolean readOnly,
073: byte[] correlationToken, byte[] productData, Typdef typdef)
074: throws SqlException {
075: buildACCRDB(rdbnam, readOnly, correlationToken, productData,
076: typdef);
077: }
078:
079: public void writeCommitSubstitute(NetConnection connection)
080: throws SqlException {
081: buildDummyEXCSAT();
082: }
083:
084: public void writeLocalCommit(NetConnection connection)
085: throws SqlException {
086: buildRDBCMM();
087: }
088:
089: public void writeLocalRollback(NetConnection connection)
090: throws SqlException {
091: buildRDBRLLBCK();
092: }
093:
094: public void writeLocalXAStart(NetConnection connection)
095: throws SqlException {
096: }
097:
098: //Build the SYNNCTL commit command
099: public void writeLocalXACommit(NetConnection conn)
100: throws SqlException {
101: }
102:
103: //Build the SYNNCTL rollback command
104: public void writeLocalXARollback(NetConnection conn)
105: throws SqlException {
106: }
107:
108: public void writeXaStartUnitOfWork(NetConnection conn)
109: throws SqlException {
110: }
111:
112: public void writeXaEndUnitOfWork(NetConnection conn)
113: throws SqlException {
114: }
115:
116: protected void writeXaPrepare(NetConnection conn)
117: throws SqlException {
118: }
119:
120: protected void writeXaCommit(NetConnection conn, Xid xid)
121: throws SqlException {
122: }
123:
124: protected void writeXaRollback(NetConnection conn, Xid xid)
125: throws SqlException {
126: }
127:
128: protected void writeXaRecover(NetConnection conn, int flag)
129: throws SqlException {
130: }
131:
132: protected void writeXaForget(NetConnection conn, Xid xid)
133: throws SqlException {
134: }
135:
136: public void writeSYNCType(int codepoint, int syncType) {
137: writeScalar1Byte(codepoint, syncType);
138: }
139:
140: public void writeForget(int codepoint, int value) {
141: }
142:
143: public void writeReleaseConversation(int codepoint, int value) {
144: }
145:
146: void writeNullXID(int codepoint) {
147: }
148:
149: void writeXID(int codepoint, Xid xid) throws SqlException {
150: }
151:
152: void writeXAFlags(int codepoint, int xaFlags) {
153: }
154:
155: //----------------------helper methods----------------------------------------
156: // These methods are "private protected", which is not a recognized java privilege,
157: // but means that these methods are private to this class and to subclasses,
158: // and should not be used as package-wide friendly methods.
159:
160: // RDB Commit Unit of Work (RDBCMM) Command commits all work performed
161: // for the current unit of work.
162: //
163: // The Relational Database Name (RDBNAM) is an optional parameter
164: // which will not be sent by this command to reduce size, building,
165: // and parsing.
166: void buildRDBCMM() throws SqlException {
167: createCommand();
168: writeLengthCodePoint(0x04, CodePoint.RDBCMM);
169: }
170:
171: // RDB Rollback Unit of Work(RDBRLLBCK) Command rolls back
172: // all work performed for the current unit of work.
173: //
174: // The Relational Database Name (RDBNAM) is an optional parameter
175: // which will not be sent by this command to reduce size, building,
176: // and parsing.
177: void buildRDBRLLBCK() throws SqlException {
178: createCommand();
179: writeLengthCodePoint(0x04, CodePoint.RDBRLLBCK);
180: }
181:
182: // build the Exchange Server Attributes Command.
183: // This command sends the following information to the server.
184: // - this driver's server class name
185: // - this driver's level of each of the manager's it supports
186: // - this driver's product release level
187: // - this driver's external name
188: // - this driver's server name
189: void buildEXCSAT(String externalName, int targetAgent,
190: int targetSqlam, int targetRdb, int targetSecmgr,
191: int targetCmntcpip, int targetCmnappc, int targetXamgr,
192: int targetSyncptmgr, int targetRsyncmgr)
193: throws SqlException {
194: createCommand();
195:
196: // begin excsat collection by placing the 4 byte llcp in the buffer.
197: // the length of this command will be computed later and "filled in"
198: // with the call to request.updateLengthBytes().
199: markLengthBytes(CodePoint.EXCSAT);
200:
201: // place the external name for the client into the buffer.
202: // the external name was previously calculated before the call to this method.
203: buildEXTNAM(externalName);
204:
205: // place the server name for the client into the buffer.
206: buildSRVNAM("Derby");
207:
208: // place the server release level for the client into the buffer.
209: // this is a hard coded value for the driver.
210: buildSRVRLSLV();
211:
212: // the managers supported by this driver and their levels will
213: // be sent to the server. the variables which store these values
214: // were initialized during object constrcution to the highest values
215: // supported by the driver.
216:
217: // for the case of the manager levels object, there is no
218: // need to have the length of the ddm object dynamically calculated
219: // because this method knows exactly how many will be sent and can set
220: // this now.
221: // each manager level class and level are 4 bytes long and
222: // right now 5 are being sent for a total of 20 bytes or 0x14 bytes.
223: // writeScalarHeader will be called to insert the llcp.
224: buildMGRLVLLS(targetAgent, targetSqlam, targetRdb,
225: targetSecmgr, targetXamgr, targetSyncptmgr,
226: targetRsyncmgr);
227:
228: // place the server class name into the buffer.
229: // this value is hard coded for the driver.
230: buildSRVCLSNM();
231:
232: // the excsat command is complete so the updateLengthBytes method
233: // is called to dynamically compute the length for this command and insert
234: // it into the buffer
235: updateLengthBytes();
236: }
237:
238: void buildDummyEXCSAT() throws SqlException {
239: createCommand();
240:
241: // begin excsat collection by placing the 4 byte llcp in the buffer.
242: // the length of this command will be computed later and "filled in"
243: // with the call to request.updateLengthBytes().
244: markLengthBytes(CodePoint.EXCSAT);
245:
246: // the excsat command is complete so the updateLengthBytes method
247: // is called to dynamically compute the length for this command and insert
248: // it into the buffer
249: updateLengthBytes();
250: }
251:
252: void buildACCSEC(int secmec, String rdbnam, byte[] sectkn)
253: throws SqlException {
254: createCommand();
255:
256: // place the llcp for the ACCSEC in the buffer. save the length bytes for
257: // later update
258: markLengthBytes(CodePoint.ACCSEC);
259:
260: // the security mechanism is a required instance variable. it will
261: // always be sent.
262: buildSECMEC(secmec);
263:
264: // the rdbnam will be built and sent. different sqlam levels support
265: // different lengths. at this point the length has been checked against
266: // the maximum allowable length. so write the bytes and padd up to the
267: // minimum length if needed.
268: buildRDBNAM(rdbnam);
269:
270: if (sectkn != null) {
271: buildSECTKN(sectkn);
272: }
273:
274: // the accsec command is complete so notify the the request object to
275: // update the ddm length and the dss header length.
276: updateLengthBytes();
277: }
278:
279: void buildSECCHK(int secmec, String rdbnam, String user,
280: String password, byte[] sectkn, byte[] sectkn2)
281: throws SqlException {
282: createCommand();
283: markLengthBytes(CodePoint.SECCHK);
284:
285: // always send the negotiated security mechanism for the connection.
286: buildSECMEC(secmec);
287:
288: // the rdbnam will be built and sent. different sqlam levels support
289: // different lengths. at this point the length has been checked against
290: // the maximum allowable length. so write the bytes and padd up to the
291: // minimum length if needed.
292: buildRDBNAM(rdbnam);
293: if (user != null) {
294: buildUSRID(user);
295: }
296: if (password != null) {
297: buildPASSWORD(password);
298: }
299: if (sectkn != null) {
300: buildSECTKN(sectkn);
301: }
302: if (sectkn2 != null) {
303: buildSECTKN(sectkn2);
304: }
305: updateLengthBytes();
306:
307: }
308:
309: // The Access RDB (ACCRDB) command makes a named relational database (RDB)
310: // available to a requester by creating an instance of an SQL application
311: // manager. The access RDB command then binds the created instance to the target
312: // agent and to the RDB. The RDB remains available (accessed) until
313: // the communications conversation is terminate.
314: void buildACCRDB(String rdbnam, boolean readOnly, byte[] crrtkn,
315: byte[] prddta, Typdef typdef) throws SqlException {
316: createCommand();
317:
318: markLengthBytes(CodePoint.ACCRDB);
319:
320: // the relational database name specifies the name of the rdb to
321: // be accessed. this can be different sizes depending on the level of
322: // support. the size will have ben previously checked so at this point just
323: // write the data and pad with the correct number of bytes as needed.
324: // this instance variable is always required.
325: buildRDBNAM(rdbnam);
326:
327: // the rdb access manager class specifies an instance of the SQLAM
328: // that accesses the RDB. the sqlam manager class codepoint
329: // is always used/required for this. this instance variable
330: // is always required.
331: buildRDBACCCL();
332:
333: // product specific identifier specifies the product release level
334: // of this driver. see the hard coded value in the NetConfiguration class.
335: // this instance variable is always required.
336: buildPRDID();
337:
338: // product specific data. this is an optional parameter which carries
339: // product specific information. although it is optional, it will be
340: // sent to the server. use the first byte to determine the number
341: // of the prddta bytes to write to the buffer. note: this length
342: // doesn't include itself so increment by it by 1 to get the actual
343: // length of this data.
344: buildPRDDTA(prddta);
345:
346: // the typdefnam parameter specifies the name of the data type to data representation
347: // mappings used when this driver sends command data objects.
348: buildTYPDEFNAM(typdef.getTypdefnam());
349:
350: if (crrtkn == null) {
351: netAgent_.netConnection_.constructCrrtkn();
352: }
353:
354: buildCRRTKN(netAgent_.netConnection_.crrtkn_);
355:
356: // This specifies the single-byte, double-byte
357: // and mixed-byte CCSIDs of the Scalar Data Arrays (SDAs) in the identified
358: // data type to the data representation mapping definitions. This can
359: // contain 3 CCSIDs. The driver will only send the ones which were set.
360: buildTYPDEFOVR(typdef.isCcsidSbcSet(), typdef.getCcsidSbc(),
361: typdef.isCcsidDbcSet(), typdef.getCcsidDbc(), typdef
362: .isCcsidMbcSet(), typdef.getCcsidMbc());
363:
364: // RDB allow update is an optional parameter which indicates
365: // whether the RDB allows the requester to perform update operations
366: // in the RDB. If update operations are not allowed, this connection
367: // is limited to read-only access of the RDB resources.
368: buildRDBALWUPD(readOnly);
369:
370: // the Statement Decimal Delimiter (STTDECDEL),
371: // Statement String Delimiter (STTSTRDEL),
372: // and Target Default Value Return (TRGDFTRT) are all optional
373: // instance variables which will not be sent to the server.
374:
375: // the command and the dss are complete so make the call to notify
376: // the request object.
377: updateLengthBytes();
378: }
379:
380: void buildSYNCCTLMigrate() throws SqlException {
381: }
382:
383: void buildSYNCCTLCommit(int xaFlags, Xid xid) throws SqlException {
384: }
385:
386: void buildSYNCCTLRollback(int xaFlags) throws SqlException {
387: }
388:
389: // The External Name is the name of the job, task, or process on a
390: // system for which a DDM server is active.
391: private void buildEXTNAM(String extnam) throws SqlException {
392: int extnamTruncateLength = Utils.min(extnam.length(),
393: NetConfiguration.EXTNAM_MAXSIZE);
394:
395: writeScalarString(CodePoint.EXTNAM, extnam.substring(0,
396: extnamTruncateLength));
397: }
398:
399: // Server Name is the name of the DDM server.
400: private void buildSRVNAM(String srvnam) throws SqlException {
401: int srvnamTruncateLength = Utils.min(srvnam.length(),
402: NetConfiguration.SRVNAM_MAXSIZE);
403: writeScalarString(CodePoint.SRVNAM, srvnam.substring(0,
404: srvnamTruncateLength));
405: }
406:
407: // Server Product Release Level String specifies the product
408: // release level of a DDM server.
409: private void buildSRVRLSLV() throws SqlException {
410: // Hard-coded to ClientDNC 1.0 for dnc 1.0.
411: writeScalarString(CodePoint.SRVRLSLV, NetConfiguration.SRVRLSLV);
412: }
413:
414: private void buildSRVCLSNM() throws SqlException {
415: // Server class name is hard-coded to QDERBY/JVM for dnc.
416: writeScalarString(CodePoint.SRVCLSNM,
417: NetConfiguration.SRVCLSNM_JVM);
418: }
419:
420: // Precondition: valid secmec is assumed.
421: private void buildSECMEC(int secmec) throws SqlException {
422: writeScalar2Bytes(CodePoint.SECMEC, secmec);
423: }
424:
425: // Relational Database Name specifies the name of a relational database
426: // of the server.
427: // if length of RDB name <= 18 characters, there is not change to the format
428: // of the RDB name. The length of the RDBNAM remains fixed at 18 which includes
429: // any right bland padding if necessary.
430: // if length of the RDB name is > 18 characters, the length of the RDB name is
431: // identical to the length of the RDB name. No right blank padding is required.
432: private void buildRDBNAM(String rdbnam) throws SqlException {
433: // since this gets built more than once on the connect flow,
434: // see if we can optimize
435:
436: int rdbnamLength = rdbnam.length();
437: if (rdbnamLength <= NetConfiguration.PKG_IDENTIFIER_FIXED_LEN) {
438: writeScalarPaddedString(CodePoint.RDBNAM, rdbnam,
439: NetConfiguration.PKG_IDENTIFIER_FIXED_LEN); // minimum length of RDBNAM
440: } else {
441: if (rdbnamLength <= NetConfiguration.PKG_IDENTIFIER_MAX_LEN) {
442: writeScalarString(CodePoint.RDBNAM, rdbnam);
443: } else {
444: throw new SqlException(netAgent_.logWriter_,
445: new ClientMessageId(
446: SQLState.NET_DBNAME_TOO_LONG), rdbnam);
447: }
448: //"at SQLAM level " + netAgent_.targetSqlam_);
449: }
450: }
451:
452: private void buildSECTKN(byte[] sectkn) throws SqlException {
453: if (sectkn.length > NetConfiguration.SECTKN_MAXSIZE) {
454: throw new SqlException(netAgent_.logWriter_,
455: new ClientMessageId(SQLState.NET_SECTKN_TOO_LONG));
456: }
457: writeScalarBytes(CodePoint.SECTKN, sectkn);
458: }
459:
460: private void buildUSRID(String usrid) throws SqlException {
461: int usridLength = usrid.length();
462: if ((usridLength == 0)
463: || (usridLength > NetConfiguration.USRID_MAXSIZE)) {
464: throw new SqlException(netAgent_.logWriter_,
465: new ClientMessageId(SQLState.NET_USERID_TOO_LONG));
466: }
467:
468: writeScalarString(CodePoint.USRID, usrid);
469: }
470:
471: private void buildPASSWORD(String password) throws SqlException {
472: int passwordLength = password.length();
473: if ((passwordLength == 0)
474: || (passwordLength > NetConfiguration.PASSWORD_MAXSIZE)) {
475: throw new SqlException(netAgent_.logWriter_,
476: new ClientMessageId(SQLState.NET_PASSWORD_TOO_LONG));
477: }
478: if (netAgent_.logWriter_ != null) {
479: // remember the position of password in order to
480: // mask it out in trace (see Request.sendBytes()).
481: passwordIncluded_ = true;
482: passwordStart_ = offset_ + 4;
483: passwordLength_ = passwordLength;
484: }
485: writeScalarString(CodePoint.PASSWORD, password);
486: }
487:
488: private void buildRDBACCCL() throws SqlException {
489: writeScalar2Bytes(CodePoint.RDBACCCL, CodePoint.SQLAM);
490: }
491:
492: private void buildPRDID() throws SqlException {
493: writeScalarString(CodePoint.PRDID, NetConfiguration.PRDID); // product id is hard-coded to DNC01000 for dnc 1.0.
494: }
495:
496: private void buildPRDDTA(byte[] prddta) throws SqlException {
497: int prddtaLength = (prddta[NetConfiguration.PRDDTA_LEN_BYTE] & 0xff) + 1;
498: writeScalarBytes(CodePoint.PRDDTA, prddta, 0, prddtaLength);
499: }
500:
501: private void buildTYPDEFNAM(String typdefnam) throws SqlException {
502: writeScalarString(CodePoint.TYPDEFNAM, typdefnam);
503: }
504:
505: void buildTYPDEFOVR(boolean sendCcsidSbc, int ccsidSbc,
506: boolean sendCcsidDbc, int ccsidDbc, boolean sendCcsidMbc,
507: int ccsidMbc) throws SqlException {
508: markLengthBytes(CodePoint.TYPDEFOVR);
509: // write the single-byte ccsid used by this driver.
510: if (sendCcsidSbc) {
511: writeScalar2Bytes(CodePoint.CCSIDSBC, ccsidSbc);
512: }
513:
514: // write the double-byte ccsid used by this driver.
515: if (sendCcsidDbc) {
516: writeScalar2Bytes(CodePoint.CCSIDDBC, ccsidDbc);
517: }
518:
519: // write the mixed-byte ccsid used by this driver
520: if (sendCcsidMbc) {
521: writeScalar2Bytes(CodePoint.CCSIDMBC, ccsidMbc);
522: }
523:
524: updateLengthBytes();
525:
526: }
527:
528: private void buildMGRLVLLS(int agent, int sqlam, int rdb,
529: int secmgr, int xamgr, int syncptmgr, int rsyncmgr)
530: throws SqlException {
531: markLengthBytes(CodePoint.MGRLVLLS);
532:
533: // place the managers and their levels in the buffer
534: writeCodePoint4Bytes(CodePoint.AGENT, agent);
535: writeCodePoint4Bytes(CodePoint.SQLAM, sqlam);
536: writeCodePoint4Bytes(CodePoint.RDB, rdb);
537: writeCodePoint4Bytes(CodePoint.SECMGR, secmgr);
538:
539: if (netAgent_.netConnection_.isXAConnection()) {
540: if (xamgr != NetConfiguration.MGRLVL_NA) {
541: writeCodePoint4Bytes(CodePoint.XAMGR, xamgr);
542: }
543: if (syncptmgr != NetConfiguration.MGRLVL_NA) {
544: writeCodePoint4Bytes(CodePoint.SYNCPTMGR, syncptmgr);
545: }
546: if (rsyncmgr != NetConfiguration.MGRLVL_NA) {
547: writeCodePoint4Bytes(CodePoint.RSYNCMGR, rsyncmgr);
548: }
549: }
550: updateLengthBytes();
551: }
552:
553: private void buildCRRTKN(byte[] crrtkn) throws SqlException {
554: writeScalarBytes(CodePoint.CRRTKN, crrtkn);
555: }
556:
557: private void buildRDBALWUPD(boolean readOnly) throws SqlException {
558: if (readOnly) {
559: writeScalar1Byte(CodePoint.RDBALWUPD, CodePoint.FALSE);
560: }
561: }
562:
563: }
|