1 /*
   2  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.sql.rowset.serial;
  27 
  28 import java.sql.*;
  29 import javax.sql.*;
  30 import java.io.*;
  31 import java.math.*;
  32 import java.util.Map;
  33 import java.util.Vector;
  34 
  35 import javax.sql.rowset.*;
  36 
  37 /**
  38  * A serialized mapping in the Java programming language of an SQL
  39  * structured type. Each attribute that is not already serialized
  40  * is mapped to a serialized form, and if an attribute is itself
  41  * a structured type, each of its attributes that is not already
  42  * serialized is mapped to a serialized form.
  43  * <P>
  44  * In addition, the structured type is custom mapped to a class in the
  45  * Java programming language if there is such a mapping, as are
  46  * its attributes, if appropriate.
  47  * <P>
  48  * The <code>SerialStruct</code> class provides a constructor for creating
  49  * an instance from a <code>Struct</code> object, a method for retrieving
  50  * the SQL type name of the SQL structured type in the database, and methods
  51  * for retrieving its attribute values.
  52  */
  53 public class SerialStruct implements Struct, Serializable, Cloneable {
  54 
  55 
  56     /**
  57      * The SQL type name for the structured type that this
  58      * <code>SerialStruct</code> object represents.  This is the name
  59      * used in the SQL definition of the SQL structured type.
  60      *
  61      * @serial
  62      */
  63     private String SQLTypeName;
  64 
  65     /**
  66      * An array of <code>Object</code> instances in  which each
  67      * element is an attribute of the SQL structured type that this
  68      * <code>SerialStruct</code> object represents.  The attributes are
  69      * ordered according to their order in the definition of the
  70      * SQL structured type.
  71      *
  72      * @serial
  73      */
  74     private Object attribs[];
  75 
  76     /**
  77      * Constructs a <code>SerialStruct</code> object from the given
  78      * <code>Struct</code> object, using the given <code>java.util.Map</code>
  79      * object for custom mapping the SQL structured type or any of its
  80      * attributes that are SQL structured types.
  81      *
  82      * @param map a <code>java.util.Map</code> object in which
  83      *        each entry consists of 1) a <code>String</code> object
  84      *        giving the fully qualified name of a UDT and 2) the
  85      *        <code>Class</code> object for the <code>SQLData</code> implementation
  86      *        that defines how the UDT is to be mapped
  87      * @throws SerialException if an error occurs
  88      * @see java.sql.Struct
  89      */
  90      public SerialStruct(Struct in, Map<String,Class<?>> map)
  91          throws SerialException
  92      {
  93 
  94         try {
  95 
  96         // get the type name
  97         SQLTypeName = in.getSQLTypeName();
  98         System.out.println("SQLTypeName: " + SQLTypeName);
  99 
 100         // get the attributes of the struct
 101         attribs = in.getAttributes(map);
 102 
 103         /*
 104          * the array may contain further Structs
 105          * and/or classes that have been mapped,
 106          * other types that we have to serialize
 107          */
 108         mapToSerial(map);
 109 
 110         } catch (SQLException e) {
 111             throw new SerialException(e.getMessage());
 112         }
 113     }
 114 
 115      /**
 116       * Constructs a <code>SerialStruct</code> object from the
 117       * given <code>SQLData</code> object, using the given type
 118       * map to custom map it to a class in the Java programming
 119       * language.  The type map gives the SQL type and the class
 120       * to which it is mapped.  The <code>SQLData</code> object
 121       * defines the class to which the SQL type will be mapped.
 122       *
 123       * @param in an instance of the <code>SQLData</code> class
 124       *           that defines the mapping of the SQL structured
 125       *           type to one or more objects in the Java programming language
 126       * @param map a <code>java.util.Map</code> object in which
 127       *        each entry consists of 1) a <code>String</code> object
 128       *        giving the fully qualified name of a UDT and 2) the
 129       *        <code>Class</code> object for the <code>SQLData</code> implementation
 130       *        that defines how the UDT is to be mapped
 131       * @throws SerialException if an error occurs
 132       */
 133     public SerialStruct(SQLData in, Map<String,Class<?>> map)
 134         throws SerialException
 135     {
 136 
 137         try {
 138 
 139         //set the type name
 140         SQLTypeName = in.getSQLTypeName();
 141 
 142         Vector tmp = new Vector();
 143         in.writeSQL(new SQLOutputImpl(tmp, map));
 144         attribs = tmp.toArray();
 145 
 146         } catch (SQLException e) {
 147             throw new SerialException(e.getMessage());
 148         }
 149     }
 150 
 151 
 152     /**
 153      * Retrieves the SQL type name for this <code>SerialStruct</code>
 154      * object. This is the name used in the SQL definition of the
 155      * structured type
 156      *
 157      * @return a <code>String</code> object representing the SQL
 158      *         type name for the SQL structured type that this
 159      *         <code>SerialStruct</code> object represents
 160      * @throws SerialException if an error occurs
 161      */
 162     public String getSQLTypeName() throws SerialException {
 163         return SQLTypeName;
 164     }
 165 
 166     /**
 167      * Retrieves an array of <code>Object</code> values containing the
 168      * attributes of the SQL structured type that this
 169      * <code>SerialStruct</code> object represents.
 170      *
 171      * @return an array of <code>Object</code> values, with each
 172      *         element being an attribute of the SQL structured type
 173      *         that this <code>SerialStruct</code> object represents
 174      * @throws SerialException if an error occurs
 175      */
 176     public Object[]  getAttributes() throws SerialException {
 177         return attribs;
 178     }
 179 
 180     /**
 181      * Retrieves the attributes for the SQL structured type that
 182      * this <code>SerialStruct</code> represents as an array of
 183      * <code>Object</code> values, using the given type map for
 184      * custom mapping if appropriate.
 185      *
 186      * @param map a <code>java.util.Map</code> object in which
 187      *        each entry consists of 1) a <code>String</code> object
 188      *        giving the fully qualified name of a UDT and 2) the
 189      *        <code>Class</code> object for the <code>SQLData</code> implementation
 190      *        that defines how the UDT is to be mapped
 191      * @return an array of <code>Object</code> values, with each
 192      *         element being an attribute of the SQL structured
 193      *         type that this <code>SerialStruct</code> object
 194      *         represents
 195      * @throws SerialException if an error occurs
 196      */
 197     public Object[] getAttributes(Map<String,Class<?>> map)
 198         throws SerialException
 199     {
 200        return attribs;
 201     }
 202 
 203 
 204     /**
 205      * Maps attributes of an SQL structured type that are not
 206      * serialized to a serialized form, using the given type map
 207      * for custom mapping when appropriate.  The following types
 208      * in the Java programming language are mapped to their
 209      * serialized forms:  <code>Struct</code>, <code>SQLData</code>,
 210      * <code>Ref</code>, <code>Blob</code>, <code>Clob</code>, and
 211      * <code>Array</code>.
 212      * <P>
 213      * This method is called internally and is not used by an
 214      * application programmer.
 215      *
 216      * @param map a <code>java.util.Map</code> object in which
 217      *        each entry consists of 1) a <code>String</code> object
 218      *        giving the fully qualified name of a UDT and 2) the
 219      *        <code>Class</code> object for the <code>SQLData</code> implementation
 220      *        that defines how the UDT is to be mapped
 221      * @throws SerialException if an error occurs
 222      */
 223     private void mapToSerial(Map map) throws SerialException {
 224 
 225         try {
 226 
 227         for (int i = 0; i < attribs.length; i++) {
 228             if (attribs[i] instanceof Struct) {
 229                 attribs[i] = new SerialStruct((Struct)attribs[i], map);
 230             } else if (attribs[i] instanceof SQLData) {
 231                 attribs[i] = new SerialStruct((SQLData)attribs[i], map);
 232             } else if (attribs[i] instanceof Blob) {
 233                 attribs[i] = new SerialBlob((Blob)attribs[i]);
 234             } else if (attribs[i] instanceof Clob) {
 235                 attribs[i] = new SerialClob((Clob)attribs[i]);
 236             } else if (attribs[i] instanceof Ref) {
 237                 attribs[i] = new SerialRef((Ref)attribs[i]);
 238             } else if (attribs[i] instanceof java.sql.Array) {
 239                 attribs[i] = new SerialArray((java.sql.Array)attribs[i], map);
 240             }
 241         }
 242 
 243         } catch (SQLException e) {
 244             throw new SerialException(e.getMessage());
 245         }
 246         return;
 247     }
 248 
 249     /**
 250      * The identifier that assists in the serialization of this
 251      * <code>SerialStruct</code> object.
 252      */
 253     static final long serialVersionUID = -8322445504027483372L;
 254 }