All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.com.ibm.as400.access.SQLXMLLocator Maven / Gradle / Ivy

There is a newer version: 11.1
Show newest version
///////////////////////////////////////////////////////////////////////////////
//                                                                             
// JTOpen (IBM Toolbox for Java - OSS version)                                 
//                                                                             
// Filename: SQLXMLLocator.java
//                                                                             
// The source code contained herein is licensed under the IBM Public License   
// Version 1.0, which has been approved by the Open Source Initiative.         
// Copyright (C) 2009-2017 International Business Machines Corporation and     
// others. All rights reserved.                                                
//                                                                             
///////////////////////////////////////////////////////////////////////////////

package com.ibm.as400.access;

import java.io.*;
import java.math.BigDecimal;
import java.sql.Array;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Date;
import java.sql.Types;
/* ifdef JDBC40 
import java.sql.NClob;
import java.sql.RowId;
endif */ 
import java.sql.SQLException;
/* ifdef JDBC40 
import java.sql.SQLXML;
endif */ 

import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;

//@xml3 new class
//sending xml to host, this class acts like BlobLocator
//reading xml from host, this class acts like ClobLocator
final class SQLXMLLocator extends SQLLocatorBase
{
    static final String copyright = "Copyright (C) 1997-2006 International Business Machines Corporation and others.";

    private AS400JDBCConnection     connection_;
    //writing to host, we let host do all the conversion
    //reading from host, we do all the conversion
    private ConvTable               converter_; //used when reading from host
    private ConvTable               unicodeConverter_; //1200 unicode to simulate no conversion //used when writing to host
    private ConvTable               unicodeUtf8Converter_; //1208 when no XML declaration  //@xmlutf8
    private int                     id_;
    private JDLobLocator            locator_;
    private int                     maxLength_;
    private SQLConversionSettings   settings_;
    private int                     truncated_;
    private boolean                 outOfBounds_; 
    private int                     columnIndex_;
    private byte[]                  valueBlob_; //@loch //Note that value_ is not used as the output for a ResultSet.getX() call.  We Get the value from a call to the JDLocator (not from value_) and not from the savedObject_, unless resultSet.updateX(obj1) is called followed by a obj2 = resultSet.getX()
    private String                  valueClob_; 
    private Object                  savedValue_; 
    private Object savedObject_; // This is the AS400JDBCXMLLocator or InputStream or whatever got set into us.
    private int scale_; // This is actually the length that got set into us.
    private boolean savedObjectWrittenToServer_ = false; 
    private int xmlType_; //@xml3 0=SB 1=DB 2=binary XML

    private boolean inputStreamRead_ = false;

    SQLXMLLocator(AS400JDBCConnection connection,
                   int id,
                   int maxLength, 
                   SQLConversionSettings settings,
                   ConvTable converter,
                   int columnIndex,
                   int xmlType) //@xml3 
    {
        connection_     = connection;
        maxLength = AS400JDBCDatabaseMetaData.MAX_LOB_LENGTH; //@xml3 //for xml, length is unknown. use max for single byte lobs since xml is returned via bloblocator
        id_             = id;
        if(xmlType == 1)
            locator_        = new JDLobLocator(connection, id, maxLength, false);   //DB //@xmlgraphic (xml is always sent with bytecount)
        else
            locator_        = new JDLobLocator(connection, id, maxLength, false);  //SB
        maxLength_      = maxLength; 
        settings_       = settings;
        truncated_ = 0; outOfBounds_ = false; 
        converter_      = converter;
        columnIndex_    = columnIndex;
        xmlType_       = xmlType; //@xml3  0=SB 1=DB 2=binary XML
        try{
            //Since we want to pass string's bytes as 1200 (java default for String) 
            //But if XML does not have a declaration then hostserver expects 1208
            unicodeConverter_ =  connection.getConverter(1200); 
            unicodeUtf8Converter_ =  connection.getConverter(1208); //@xmlutf8 
        }catch(SQLException e){
            unicodeConverter_ = connection.getConverter();//should never happen
        }
    }

    public Object clone()
    {
        return new SQLXMLLocator(connection_, id_, maxLength_, settings_, converter_, columnIndex_, xmlType_);  //@xml3
    }

    public void setHandle(int handle)      
    {
        locator_.setHandle(handle);   
        //  @T1A reset saved handle after setting new value
       savedObject_ = null;
       savedObjectWrittenToServer_ = false;    
      
    }                     
    
    public int getHandle()
    {
        return locator_.getHandle();
    }

    //---------------------------------------------------------//
    //                                                         //
    // CONVERSION TO AND FROM RAW BYTES                        //
    //                                                         //
    //---------------------------------------------------------//

    public void convertFromRawBytes(byte[] rawBytes, int offset,
        ConvTable converter) throws SQLException {
      convertFromRawBytes(rawBytes, offset, converter, false); 
    }

    public void convertFromRawBytes(byte[] rawBytes, int offset, ConvTable ccsidConverter, boolean ignoreConversionErrors)
    throws SQLException
    {
        int locatorHandle = BinaryConverter.byteArrayToInt(rawBytes, offset);
        locator_.setHandle(locatorHandle);
        locator_.setColumnIndex(columnIndex_);
        //  @T1A reset saved handle after setting new value
       savedObject_ = null;
       savedObjectWrittenToServer_ = false;
    }

    //This is only called from AS400JDBCPreparedStatement in one place.
    public void convertToRawBytes(byte[] rawBytes, int offset, ConvTable ccsidConverter)
    throws SQLException
    {
        BinaryConverter.intToByteArray(locator_.getHandle(), rawBytes, offset);

        // Now we write our saved data to the system, because the prepared statement is being executed.
        // We used to write the data to the system on the call to set(), but this messed up
        // batch executes, since the host server only reserves temporary space for locator handles one row at a time.
        // See the toObject() method in this class for more details.
        if((! savedObjectWrittenToServer_ ) && (savedObject_ != null)) writeToServer();
    }
    
    /**
    validates that raw truncated data is correct.  The data is corrected if is not correct. 
    This is only used when converting to MIXED CCSID and UTF-8. 
    @param  rawBytes         the raw bytes for the system.
    @param  offset           the offset into the byte array.
    @param  ccsidConverter   the converter.
     * @throws SQLException  If a database error occurs.
    **/ 
    public void validateRawTruncatedData(byte[] rawBytes, int offset, ConvTable ccsidConverter) {
      // Most data type do not need to validate truncated data.  Just return. 
    }


    //---------------------------------------------------------//
    //                                                         //
    // SET METHODS                                             //
    //                                                         //
    //---------------------------------------------------------//


    public void set(Object object, Calendar calendar, int scale)
    throws SQLException
    {
        //no need to check truncation since xml does not have size
        savedObject_ = object;
        if(object instanceof ConvTableReader) //@ascii
        {
            //set xml flag so ConvTableReader will trim off xml declaration since we will be transmitting in utf-8
            ((ConvTableReader)savedObject_).isXML_ = true; //@ascii
            scale_ = ALL_READER_BYTES;//@ascii flag -2 to read to end of stream (xml transmits in utf8 which may have 2-byte chars, which does not match length)
        }
        else if(scale != -1) 
            scale_ = scale; // Skip resetting it if we don't know the real length
    }

    //Method to temporary convert from object input to output before even going to host (writeToServer() does the conversion needed before writing to host)
    //This will only be used when resultSet.updateX(obj1) is called followed by a obj2 = resultSet.getX()
    //Purpose is to do a local type conversion from obj1 to obj2 like other non-locator lob types
    private void doConversion()
    throws SQLException
    {
      
        valueClob_ = null;
        valueBlob_ = null;
        int length = scale_;

        if( length == -1)
        {
            try{
                //try to get length from locator
                length = (int)locator_.getLength();        
            }catch(Exception e){ }
        }
        
        try
        {
           
            if(savedObject_ instanceof String)
            {
                valueClob_ = (String)savedObject_;
                
            }
            else if(savedObject_ instanceof Reader)
            {
              
              valueClob_ = SQLDataBase.getStringFromReader((Reader)savedObject_, length, this);
              // The Reader has been read, so adjust the savedObject to be the read string
              savedObject_ = valueClob_; 
            }
            else if( savedObject_ instanceof Clob)  
            {
              // Updateable locator path 
            	if(savedObject_ instanceof AS400JDBCClobLocator) 
              {
                  AS400JDBCClobLocator clob = (AS400JDBCClobLocator)savedObject_;

                  //Synchronize on a lock so that the user can't keep making updates
                  //to the clob while we are taking updates off the vectors.
                  synchronized(clob)
                  {
                      // See if we saved off our real object from earlier.
                      if(clob.savedObject_ != null)
                      {
                          savedObject_ = clob.savedObject_;
                          scale_ = clob.savedScale_;
                          clob.savedObject_ = null;
                          if ((savedObject_ != null) && (! ( savedObject_ instanceof AS400JDBCClobLocator))) {
                            doConversion(); 
                            return;
                          }
                      }
                  }
              }

                Clob clob = (Clob)savedObject_;
                valueClob_ = clob.getSubString(1, (int)clob.length());
            }
            else if(savedObject_ instanceof byte[])
            {
                valueBlob_ = (byte[]) savedObject_;
                int objectLength = valueBlob_.length;
                if(objectLength > maxLength_)
                {
                    byte[] newValue = new byte[maxLength_];
                    System.arraycopy(valueBlob_, 0, newValue, 0, maxLength_);
                    valueBlob_ = newValue;
                }
                //xml has no max size truncated_ = objectLength - valueBlob_.length;
            }
            else if(savedObject_ instanceof Blob)
            {
                Blob blob = (Blob) savedObject_;
                int blobLength = (int)blob.length();
                int lengthToUse = blobLength < 0 ? 0x7FFFFFFF : blobLength;
                if(lengthToUse > maxLength_) lengthToUse = maxLength_;
                valueBlob_ = blob.getBytes(1, lengthToUse);
              //xml has no max sizetruncated_ = blobLength - lengthToUse;
            }
            else if(savedObject_ instanceof InputStream)
            {
                length = scale_; 
                if(length >= 0)
                {
                    InputStream stream = (InputStream)savedObject_;
                    
                    valueBlob_ = readInputStream(stream, length, null, false);
                    inputStreamRead_ = true; 
                    if(valueBlob_.length < length)
                    {
                        // a length longer than the stream was specified
                        JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
                    }

                    int objectLength = valueBlob_.length;
                    if(objectLength > maxLength_)
                    {
                        byte[] newValue = new byte[maxLength_];
                        System.arraycopy(valueBlob_, 0, newValue, 0, maxLength_);
                        valueBlob_ = newValue;
                    }
                    // Input stream is no longer usable 
                    savedObject_ = valueBlob_; 
                  //xml has no max sizetruncated_ = objectLength - valueBlob_.length;
                }
                else if(length == ALL_READER_BYTES )//@readerlen new else-if block (read all data)
                {
                    InputStream stream = (InputStream)savedObject_;
                    valueBlob_ = readInputStream(stream, length, null, false);
                    inputStreamRead_ = true; 
                    
                    int objectLength = valueBlob_.length;
                    if(objectLength > maxLength_)
                    {
                        byte[] newValue = new byte[maxLength_];
                        System.arraycopy(valueBlob_, 0, newValue, 0, maxLength_);
                        valueBlob_ = newValue;
                    }
                    // Input stream is no longer usable 
                    savedObject_ = valueBlob_; 
                    
                  //xml has no max sizetruncated_ = objectLength - valueBlob_.length;
                }
                else
                {
                    JDError.throwSQLException(JDError.EXC_DATA_TYPE_MISMATCH);
                }
            }
            /* ifdef JDBC40 
            else if( savedObject_ instanceof SQLXML ) 
            {
                SQLXML xml = (SQLXML)savedObject_;
                valueClob_ = xml.getString();
            }
            endif */
            else
            {
                JDError.throwSQLException(JDError.EXC_DATA_TYPE_MISMATCH);
            }
        }
        finally
        {
            //nothing
        }
    }

    
    
    // This method actually writes the data to the system.
    private void writeToServer()
    throws SQLException
    {
        if (inputStreamRead_) {
          locator_.writeData(0, valueBlob_, true);   
        } else  if(savedObject_ instanceof byte[]) {
            byte[] bytes = (byte[])savedObject_;        
            locator_.writeData(0, bytes, true);   
        }
        else if(savedObject_ instanceof InputStream)
        {
            int length = scale_; // hack to get the length into the set method
            //if(xmlType_ == 1)   
            //    length *=2; //double-byte
            
            // Need to write even if there are 0 bytes in case we are batching and
            // the host server reuses the same handle for the previous locator; otherwise,
            // we'll have data in the current row from the previous row.
            if (length == 0)      {
              locator_.writeData(0, new byte[0], 0, 0, true);  
            }
            else if(length > 0)
            {
                InputStream stream = (InputStream)savedObject_;
                valueBlob_ = readInputStream(stream, length, locator_, false);
               inputStreamRead_ = true; 
                    if(valueBlob_.length < length)
                    {
                        // a length longer than the stream was specified
                        JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
                    }
                
                
            }
            else if(length == ALL_READER_BYTES) //@readerlen new else-if block (read all data)
            {
              InputStream stream = (InputStream)savedObject_;
              boolean doubleByteOffset = false; 
              if (xmlType_ == 1) { 
                doubleByteOffset = true; 
              }
              valueBlob_ = readInputStream(stream, length, locator_, doubleByteOffset);
              inputStreamRead_ = true; 
              
                         }
            else
            {
                JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
            }
        }
        else if (savedObject_ instanceof Blob)
        {
            //Start new code for updateable locator case to go through the Vectors 
            //and update the blob copy when ResultSet.updateBlob() is called.
            boolean set = false;
            if(savedObject_ instanceof AS400JDBCBlobLocator)
            {
                AS400JDBCBlobLocator blob = (AS400JDBCBlobLocator)savedObject_;

                //Synchronize on a lock so that the user can't keep making updates
                //to the blob while we are taking updates off the vectors.
                synchronized(blob)
                {
                    // See if we saved off our real object from earlier.
                    if(blob.savedObject_ != null)
                    {
                        savedObject_ = blob.savedObject_;
                        scale_ = blob.savedScale_;
                        blob.savedObject_ = null;
                        writeToServer();
                        return;
                    }
                }
            }

            //If the code for updateable lob locators did not run, then run old code.
            if(!set)
            {
                Blob blob = (Blob)savedObject_; 
                int length = (int)blob.length();
                byte[] data = blob.getBytes(1, length);
                locator_.writeData(0, data, 0, length, true); 
            }
        }
        else if(savedObject_ instanceof String)    {
                String string = (String)savedObject_;
                byte[] bytes;
                if(JDUtilities.hasXMLDeclaration(string))                                 //@xmlutf8
                {
                    string = JDUtilities.handleXMLDeclarationEncoding(string); //if encoding is non utf-16 then remove to match Java Strings  //@xmlutf16
                    bytes = unicodeConverter_.stringToByteArray(string); //just get bytes
                }
                else                                                          //@xmlutf8
                    bytes = unicodeUtf8Converter_.stringToByteArray(string);  //@xmlutf8
                locator_.writeData(0L, bytes, true); 
        } else if(savedObject_ instanceof Reader) {
            int length = scale_; // hack to get the length into the set method
            // Need to write even if there are 0 bytes in case we are batching and
            // the host server reuses the same handle for the previous locator; otherwise,
            // we'll have data in the current row from the previous row.
            if (length == 0)        {
              locator_.writeData(0, new byte[0], 0, 0, true);  
            }  else if(length > 0)      {
                           
              valueClob_ = SQLDataBase.getStringFromReader((Reader)savedObject_, length, this);
              String string = valueClob_; 
              savedObject_ = valueClob_; 
              byte[] bytes;
              if(JDUtilities.hasXMLDeclaration(valueClob_))   {                               //@xmlutf8              
                  string = JDUtilities.handleXMLDeclarationEncoding(string); //if encoding is non utf-16 then remove to match Java Strings  //@xmlutf16
                  bytes = unicodeConverter_.stringToByteArray(string); //just get bytes
              } else {                                                          //@xmlutf8
                  bytes = unicodeUtf8Converter_.stringToByteArray(string);  //@xmlutf8
              }
              locator_.writeData(0L, bytes, true); 

              if(bytes.length < length)        {
                  // a length longer than the stream was specified
                  JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
              }
              
            }
            else if(length == ALL_READER_BYTES) { //@readerlen new else-if block (read all data)
              valueClob_ = SQLDataBase.getStringFromReader((Reader)savedObject_, length, this);
              String string = valueClob_; 
              savedObject_ = valueClob_; 
              byte[] bytes;
              if(JDUtilities.hasXMLDeclaration(valueClob_))                                 //@xmlutf8
              {
                  string = JDUtilities.handleXMLDeclarationEncoding(string); //if encoding is non utf-16 then remove to match Java Strings  //@xmlutf16
                  bytes = unicodeConverter_.stringToByteArray(string); //just get bytes
              }
              else                                                          //@xmlutf8
                  bytes = unicodeUtf8Converter_.stringToByteArray(string);  //@xmlutf8
              locator_.writeData(0L, bytes, true); 

            }
        }
        else if( savedObject_ instanceof Clob) //jdbc40 NClob isa Clob
        {
            //@G5A Start new code for updateable locator case
            boolean set = false;
            if(savedObject_ instanceof AS400JDBCClobLocator) //@PDA jdbc40 comment: AS400JDBCNClobLocator isa AS400JDBCClobLocator
            {
                AS400JDBCClobLocator clob = (AS400JDBCClobLocator)savedObject_;

                //Synchronize on a lock so that the user can't keep making updates
                //to the clob while we are taking updates off the vectors.
                synchronized(clob)
                {
                    // See if we saved off our real object from earlier.
                    if(clob.savedObject_ != null)
                    {
                        savedObject_ = clob.savedObject_;
                        scale_ = clob.savedScale_;
                        clob.savedObject_ = null;
                        writeToServer();
                        return;
                    }
                }
            }

            //If the code for updateable lob locators did not run, then run old code.
            if(!set)
            {
                Clob clob = (Clob)savedObject_;
                int length = (int)clob.length();
                String substring = clob.getSubString(1, length);
                byte[] inputBytes;                                                            //@len2utf8
                if(JDUtilities.hasXMLDeclaration(substring))                                 //@xmlutf8
                    inputBytes = unicodeConverter_.stringToByteArray(JDUtilities.handleXMLDeclarationEncoding(substring));      //@len2utf8 //here, we have a string, so it has to be in utf-16, so just take out encoding and sq and detect encoding
                else
                    inputBytes = unicodeUtf8Converter_.stringToByteArray(substring); //@len2utf8
                    
               
                locator_.writeData(0L, inputBytes, 0, inputBytes.length, true);  //@xmlutf8
                set = true;
            }
            else
            {
                JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
            }
        }
/* ifdef JDBC40  
        else if( savedObject_ instanceof SQLXML ) //@olddesc
        {
           SQLXML xml = (SQLXML)savedObject_;
           
           boolean set = false;
           if(savedObject_ instanceof AS400JDBCSQLXMLLocator)
           {
               AS400JDBCSQLXMLLocator xmlLocator = (AS400JDBCSQLXMLLocator)savedObject_;

               //Synchronize on a lock so that the user can't keep making updates
               //to the xml while we are taking updates off the vectors.
               synchronized(xmlLocator)
               {
                   // See if we saved off our real object from earlier.
                   if(xmlLocator.clobLocatorValue_ != null && xmlLocator.clobLocatorValue_.savedObject_ != null)
                   {
                       savedObject_ = xmlLocator.clobLocatorValue_.savedObject_;
                       scale_ = xmlLocator.clobLocatorValue_.savedScale_;
                       xmlLocator.clobLocatorValue_.savedObject_ = null;
                       writeToServer();
                       return;
                   }
                   else if(xmlLocator.blobLocatorValue_ != null && xmlLocator.blobLocatorValue_.savedObject_ != null)
                   {
                       savedObject_ = xmlLocator.blobLocatorValue_.savedObject_;
                       scale_ = xmlLocator.blobLocatorValue_.savedScale_;
                       xmlLocator.blobLocatorValue_.savedObject_ = null;
                       writeToServer();
                       return;
                   }
               }
           }
                      
           if(!set)
           {
               
               //getString() handles internal representation of clob/dbclob/blob...
               String stringVal = xml.getString();
               byte[] inputBytes;                                                            //@len2utf8
               if(JDUtilities.hasXMLDeclaration(stringVal))                                 //@xmlutf8
                   inputBytes = unicodeConverter_.stringToByteArray(JDUtilities.handleXMLDeclarationEncoding(stringVal));      //@len2utf8 //here, we have a string, so it has to be in utf-16, so just take out encoding and sq and detect encoding
               else
                   inputBytes = unicodeUtf8Converter_.stringToByteArray(stringVal); //@len2utf8
                   
              
               locator_.writeData(0L, inputBytes, 0, inputBytes.length, true);  //@xmlutf8
           }
        }
endif */ 
        else
        {
            JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
        }
        savedObjectWrittenToServer_ = true; 
    }

    
    //---------------------------------------------------------//
    //                                                         //
    // DESCRIPTION OF SQL TYPE                                 //
    //                                                         //
    //---------------------------------------------------------//

    public int getSQLType()
    {
        return SQLData.XML_LOCATOR;
    }

    public String getCreateParameters()
    {
        return AS400JDBCDriver.getResource("MAXLENGTH",null); 
    }

    public int getDisplaySize()
    {
        return maxLength_;
    }

    public String getJavaClassName()
    {
        return "com.ibm.as400.access.AS400JDBCSQLXML";    
    }

    public String getLiteralPrefix()
    {
        return null;
    }

    public String getLiteralSuffix()
    {
        return null;
    }

    public String getLocalName()
    {
        return "XML"; 
    }

    public int getMaximumPrecision()
    {
/*ifdef JDBC40 
        return AS400JDBCSQLXML.MAX_XML_SIZE;  
endif */ 
/* ifndef JDBC40 */ 
        return AS400JDBCDatabaseMetaData.MAX_LOB_LENGTH;
/* endif */         
    }

    public int getMaximumScale()
    {
        return 0;
    }

    public int getMinimumScale()
    {
        return 0;
    }

    public int getNativeType()
    {
        return 2452;
    }

    public int getPrecision()
    {
        return maxLength_;
    }

    public int getRadix()
    {
        return 0;
    }

    public int getScale()
    {
        return 0;
    }

    public int getType()
    {
/*ifdef JDBC40 
        return Types.SQLXML;   
endif */ 
/* ifndef JDBC40 */ 
        return Types.CLOB;
/* endif */         
    }

    public String getTypeName()
    {
        return "XML";
         
    }

    public boolean isSigned()
    {
        return false;
    }

    public boolean isText()
    {
        return true;
    }

    public int getActualSize()
    {
        return maxLength_;
    }

    public int getTruncated()
    {
        return truncated_;
    }
    public boolean getOutOfBounds() {
      return outOfBounds_; 
    }

    public void clearTruncated() { 
      truncated_ = 0; 
    }
    public void clearOutOfBounds() {
      outOfBounds_ = false; 
    }

    //---------------------------------------------------------//
    //                                                         //
    // CONVERSIONS TO JAVA TYPES                               //
    //                                                         //
    //---------------------------------------------------------//

    public InputStream getAsciiStream()
    throws SQLException
    {
        truncated_ = 0; outOfBounds_ = false; 
        try
        {
            if(savedObject_ != null)//@loch
            {                       //@loch
                //get value from RS.updateX(value)
                doConversion();     //@loch
                truncated_ = 0; outOfBounds_ = false;      //@loch
                return new ByteArrayInputStream(ConvTable.getTable(819, null).stringToByteArray(valueClob_));//@loch
            }                       //@loch
            //remove xml declaration via ConvTableReader
            Reader tmpUnicodeReader = new ConvTableReader(new AS400JDBCInputStream(new JDLobLocator(locator_)), converter_.getCcsid(), true); 
           // tmpUnicodeReader.
            return new ReaderInputStream(tmpUnicodeReader, 819); // ISO-8859-1. //is xml type
        }
        catch(UnsupportedEncodingException e)
        {
            JDError.throwSQLException(this, JDError.EXC_INTERNAL, e);
            return null;
        }
    }

    public BigDecimal getBigDecimal(int scale)
    throws SQLException
    {
        JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
        return null;
    }

    public InputStream getBinaryStream()
    throws SQLException
    {
        truncated_ = 0; outOfBounds_ = false; 
        return new AS400JDBCInputStream(new JDLobLocator(locator_));
    }

    public Blob getBlob()
    throws SQLException
    {
        if(savedObject_ != null)//@loch
        {                       //@loch
            //get value from RS.updateX(value)
            doConversion();     //@loch
            truncated_ = 0; outOfBounds_ = false;      //@loch
            if (valueBlob_ != null) { 
               return new AS400JDBCBlob(valueBlob_, maxLength_); //@loch
            } else {
               try {
                return new AS400JDBCBlob(valueClob_.getBytes("UTF-8"), maxLength_);
              } catch (UnsupportedEncodingException e) {
                // Should never happen since UTF-8 is a valid encoding.
              } 
            }
        }                       //@loch
        
        // We don't want to give out our internal locator to the public,
        // otherwise when we go to change its handle on the next row, they'll
        // get confused.  So we have to clone it.
        truncated_ = 0; outOfBounds_ = false; 
        return new AS400JDBCBlobLocator(new JDLobLocator(locator_), savedObject_, scale_);
    }

    public boolean getBoolean()
    throws SQLException
    {
        JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
        return false;
    }

    public byte getByte()
    throws SQLException
    {
        JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
        return -1;
    }

    public byte[] getBytes()
    throws SQLException
    {
        if(savedObject_ != null)//@loch
        {                       //@loch
            //get value from RS.updateX(value)
            doConversion();     //@loch
            truncated_ = 0; outOfBounds_ = false;      //@loch
            if (valueBlob_ != null) {
              return valueBlob_;//@loch
            }
        }                       //@loch
        
        int locatorLength = (int)locator_.getLength();
        if(locatorLength == 0) return new byte[0];
        DBLobData data = locator_.retrieveData(0, locatorLength);
        int actualLength = data.getLength();
        byte[] bytes = new byte[actualLength];
        System.arraycopy(data.getRawBytes(), data.getOffset(), bytes, 0, actualLength);
        truncated_ = 0; outOfBounds_ = false; 
        return bytes;
    }

    public Reader getCharacterStream()
    throws SQLException
    {
        truncated_ = 0; outOfBounds_ = false; 
        try
        {
            if(savedObject_ != null)//@loch
            {                       //@loch
                //get value from RS.updateX(value)
                doConversion();     //@loch
                truncated_ = 0; outOfBounds_ = false;      //@loch
                return new StringReader(valueClob_); //@loch
            }                       //@loch
            //remove xml declaration via ConvTableReader
            return new ConvTableReader(new AS400JDBCInputStream(new JDLobLocator(locator_)), converter_.getCcsid(), true); //@xml4
        }
        catch(UnsupportedEncodingException e)
        {
            JDError.throwSQLException(this, JDError.EXC_INTERNAL, e);
            return null;
        }
    }

    public Clob getClob()
    throws SQLException
    {
        truncated_ = 0; outOfBounds_ = false; 
        if(savedObject_ != null)//@loch
        {                       //@loch
            //get value from RS.updateX(value)
            doConversion();     //@loch
            truncated_ = 0; outOfBounds_ = false;      //@loch
            return new AS400JDBCClob(valueClob_, maxLength_); //@loch
        }                       //@loch
        
        return new AS400JDBCClobLocator(new JDLobLocator(locator_), converter_, savedObject_, scale_, true);//@xml4     
    }

    public Date getDate(Calendar calendar)
    throws SQLException
    {
        JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
        return null;
    }

    public double getDouble()
    throws SQLException
    {
        JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
        return -1;
    }

    public float getFloat()
    throws SQLException
    {
        JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
        return -1;
    }

    public int getInt()
    throws SQLException
    {
        JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
        return -1;
    }

    public long getLong()
    throws SQLException
    {
        JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
        return -1;
    }

    public Object getObject()
    throws SQLException
    {
        // toObject is used by AS400JDBCPreparedStatement for batching, so we save off our InputStream
        // inside the AS400JDBCBlobLocator. Then, when convertToRawBytes() is called, the writeToServer()
        // code checks the AS400JDBCBlobLocator's saved InputStream... if it exists, then it writes the
        // data out of the InputStream to the system by calling writeToServer() again.

        // Since toObject could also be called from an external user's standpoint, we have
        // to clone our internal locator (because we reuse it internally).
        // This doesn't make much sense, since we technically can't reuse it because
        // the prepared statement is calling toObject() to store off the parameters,
        // but it's all we can do for now.
        truncated_ = 0; outOfBounds_ = false; 
        /* ifdef JDBC40 
        if(savedObject_ != null)//@xmlupdate //either return savedObject_ here, or add two iterations of getting savedObject_ in writeToServer if type is AS400JDBCSQLXML since it contains clob which contains savedObject_
            return savedObject_;    //@xmlupdate
        return new AS400JDBCSQLXMLLocator(new JDLobLocator(locator_), converter_, savedObject_, scale_, true);  //@xml4   

        endif */
        /* ifndef JDBC40  */ 
        return  getClob();  //@xml4   
        /* endif */ 
    }
     

    public Object getBatchableObject() throws SQLException {
      return getObject();
    }


    public short getShort()
    throws SQLException
    {
        JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
        return -1;
    }

    public String getString()
    throws SQLException
    {
        if(savedObject_ != null)//@loch
        {                       //@loch
            //get value from RS.updateX(value)
            doConversion();     //@loch
            truncated_ = 0; outOfBounds_ = false;      //@loch
            return valueClob_;      //@loch
        }                       //@loch
        
        DBLobData data = locator_.retrieveData(0, locator_.getMaxLength());
        String value = converter_.byteArrayToString(data.getRawBytes(),
                                                    data.getOffset(),
                                                    data.getLength());
        value = JDUtilities.stripXMLDeclaration(value);  //remove xml declaration 
        truncated_ = 0; outOfBounds_ = false;   
        return value;
    }

    public Time getTime(Calendar calendar)
    throws SQLException
    {
        JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
        return null;
    }

    public Timestamp getTimestamp(Calendar calendar)
    throws SQLException
    {
        JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
        return null;
    }

    public InputStream getUnicodeStream()
    throws SQLException
    {
        truncated_ = 0; outOfBounds_ = false; 
        try
        {
            if(savedObject_ != null)//@loch
            {                       //@loch
                //get value from RS.updateX(value)
                doConversion();     //@loch
                truncated_ = 0; outOfBounds_ = false;      //@loch
                return new ReaderInputStream(new StringReader(valueClob_), 13488); //@loch
            }                       //@loch
        
            //remove xml declaration via ConvTableReader
            return new ReaderInputStream(new ConvTableReader(new AS400JDBCInputStream(new JDLobLocator(locator_)), converter_.getCcsid(), true), 13488); //@xml4
        }
        catch(UnsupportedEncodingException e)
        {
            JDError.throwSQLException(JDError.EXC_INTERNAL, e);
            return null;
        }
    }
    
    //@PDA jdbc40
    public Reader getNCharacterStream() throws SQLException
    {
        truncated_ = 0; outOfBounds_ = false; 
        
        if(savedObject_ != null)//@loch
        {                       //@loch
            //get value from RS.updateX(value)
            doConversion();     //@loch
            truncated_ = 0; outOfBounds_ = false;      //@loch
            return new StringReader(valueClob_);  //@loch
        }                       //@loch
        
        try
        {
            //remove xml declaration via ConvTableReader
            return new ConvTableReader(new AS400JDBCInputStream(new JDLobLocator(locator_)), converter_.getCcsid(), true);   //@xml4
        }
        catch(UnsupportedEncodingException e)
        {
            JDError.throwSQLException(this, JDError.EXC_INTERNAL, e);
            return null;
        }
    }
    
    /* ifdef JDBC40 
    //@pda jdbc40
    public NClob getNClob() throws SQLException
    {
        truncated_ = 0; outOfBounds_ = false; 
        
        if(savedObject_ != null)//@loch
        {                       //@loch
            //get value from RS.updateX(value)
            doConversion();     //@loch
            truncated_ = 0; outOfBounds_ = false;      //@loch
            return new AS400JDBCNClob(valueClob_, maxLength_); //@loch
        }                       //@loch
        
        return new AS400JDBCNClobLocator(new JDLobLocator(locator_), converter_, savedObject_, scale_, true);   //@xml4    
 
    }
    endif */ 
    
    //@pda jdbc40
    public String getNString() throws SQLException
    {
        truncated_ = 0; outOfBounds_ = false; 
        
        if(savedObject_ != null)//@loch
        {                       //@loch
            //get value from RS.updateX(value)
            doConversion();     //@loch
            truncated_ = 0; outOfBounds_ = false;      //@loch
            return valueClob_;   //@loch
        }                       //@loch

        DBLobData data = locator_.retrieveData(0, locator_.getMaxLength());
        String value = converter_.byteArrayToString(data.getRawBytes(),
                                                    data.getOffset(),
                                                    data.getLength());
        value = JDUtilities.stripXMLDeclaration(value); //remove xml declaration 
        return value;  
    }

/* ifdef JDBC40 
    //@pda jdbc40
    public RowId getRowId() throws SQLException
    {
        JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
        return null;
    }

    //@PDA jdbc40
    public SQLXML getSQLXML() throws SQLException
    {
        truncated_ = 0; outOfBounds_ = false; 
        //xml data is always retrieved from host in binary 65535 format
        //may or maynot need converter depending on how user gets data from SQLXML
        //return xmllocator which will treat data as cloblocator and do conversion
        //@xml3 if xml column, remove xml declaration from within internal cloblocator inside of sqlxmllocator.
        return new AS400JDBCSQLXMLLocator(new JDLobLocator(locator_), converter_, savedObject_, scale_, true);   //@xml4   
    }
endif */ 

     
    // @array
    public Array getArray() throws SQLException
    {
        JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
        return null;
    }
    
    public void updateSettings(SQLConversionSettings settings) {
      settings_ = settings; 
    }

    
    public void saveValue() throws SQLException {
      if (valueClob_ == null && valueBlob_ == null   && savedObject_ != null ) {
        doConversion(); 
      }
      if (valueClob_ != null ) {
        savedValue_ = valueClob_; 
      } else {
        savedValue_ = valueBlob_; 
      }
      
   }

    public Object getSavedValue() {
      
      return savedValue_; 
    }
    
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy