1 /*
   2  * Copyright (c) 2000, 2004, 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 com.sun.corba.se.spi.ior.iiop ;
  27 
  28 import com.sun.corba.se.spi.ior.IOR ;
  29 import com.sun.corba.se.spi.ior.iiop.IIOPProfile;
  30 import com.sun.corba.se.spi.orb.ORB;
  31 import com.sun.corba.se.spi.orb.ORBVersion;
  32 import com.sun.corba.se.spi.orb.ORBVersionFactory;
  33 
  34 import com.sun.corba.se.impl.orbutil.ORBUtility;
  35 import com.sun.corba.se.impl.protocol.giopmsgheaders.Message;
  36 
  37 public class GIOPVersion {
  38 
  39     // Static fields
  40 
  41     public static final GIOPVersion V1_0 = new GIOPVersion((byte)1, (byte)0);
  42     public static final GIOPVersion V1_1 = new GIOPVersion((byte)1, (byte)1);
  43     public static final GIOPVersion V1_2 = new GIOPVersion((byte)1, (byte)2);
  44     public static final GIOPVersion V1_3 = new GIOPVersion((byte)1, (byte)3);
  45 
  46     // Major version 13 indicates Java serialization,
  47     // Minor version [00-FF] is the version number.
  48     public static final GIOPVersion V13_XX =
  49         new GIOPVersion((byte)13, (byte)Message.JAVA_ENC_VERSION);
  50 
  51     public static final GIOPVersion DEFAULT_VERSION = V1_2;
  52 
  53     public static final int VERSION_1_0 = 0x0100;
  54     public static final int VERSION_1_1 = 0x0101;
  55     public static final int VERSION_1_2 = 0x0102;
  56     public static final int VERSION_1_3 = 0x0103;
  57     public static final int VERSION_13_XX =
  58         ((0x0D << 8) & 0x0000FF00) | Message.JAVA_ENC_VERSION;
  59 
  60     // Instance variables
  61 
  62     private byte major = (byte) 0;
  63     private byte minor = (byte) 0;
  64 
  65     // Constructor
  66 
  67     public GIOPVersion() {}
  68 
  69     public GIOPVersion(byte majorB, byte minorB) {
  70         this.major = majorB;
  71         this.minor = minorB;
  72     }
  73 
  74     public GIOPVersion(int major, int minor) {
  75         this.major = (byte)major;
  76         this.minor = (byte)minor;
  77     }
  78 
  79     // Accessor methods
  80 
  81     public byte getMajor() {
  82         return this.major;
  83     }
  84 
  85     public byte getMinor() {
  86         return this.minor;
  87     }
  88 
  89     // General methods
  90 
  91     public boolean equals(GIOPVersion gv){
  92         return gv.major == this.major && gv.minor == this.minor ;
  93     }
  94 
  95     public boolean equals(Object obj) {
  96         if (obj != null && (obj instanceof GIOPVersion))
  97             return equals((GIOPVersion)obj);
  98         else
  99             return false;
 100     }
 101 
 102     public int hashCode()
 103     {
 104         return 37*major + minor ;
 105     }
 106 
 107     public boolean lessThan(GIOPVersion gv) {
 108         if (this.major < gv.major) {
 109             return true;
 110         } else if (this.major == gv.major) {
 111             if (this.minor < gv.minor) {
 112                 return true;
 113             }
 114         }
 115 
 116         return false;
 117     }
 118 
 119     public int intValue()
 120     {
 121         return (major << 8 | minor);
 122     }
 123 
 124     public String toString()
 125     {
 126         return major + "." + minor;
 127     }
 128 
 129     public static GIOPVersion getInstance(byte major, byte minor)
 130     {
 131         switch(((major << 8) | minor)) {
 132             case VERSION_1_0:
 133                 return GIOPVersion.V1_0;
 134             case VERSION_1_1:
 135                 return GIOPVersion.V1_1;
 136             case VERSION_1_2:
 137                 return GIOPVersion.V1_2;
 138             case VERSION_1_3:
 139                 return GIOPVersion.V1_3;
 140             case VERSION_13_XX:
 141                 return GIOPVersion.V13_XX;
 142             default:
 143                 return new GIOPVersion(major, minor);
 144         }
 145     }
 146 
 147     public static GIOPVersion parseVersion(String s)
 148     {
 149         int dotIdx = s.indexOf('.');
 150 
 151         if (dotIdx < 1 || dotIdx == s.length() - 1)
 152             throw new NumberFormatException("GIOP major, minor, and decimal point required: " + s);
 153 
 154         int major = Integer.parseInt(s.substring(0, dotIdx));
 155         int minor = Integer.parseInt(s.substring(dotIdx + 1, s.length()));
 156 
 157         return GIOPVersion.getInstance((byte)major, (byte)minor);
 158     }
 159 
 160     /**
 161      * This chooses the appropriate GIOP version.
 162      *
 163      * @return the GIOP version 13.00 if Java serialization is enabled, or
 164      *         smallest(profGIOPVersion, orbGIOPVersion)
 165      */
 166     public static GIOPVersion chooseRequestVersion(ORB orb, IOR ior ) {
 167 
 168         GIOPVersion orbVersion = orb.getORBData().getGIOPVersion();
 169         IIOPProfile prof = ior.getProfile() ;
 170         GIOPVersion profVersion = prof.getGIOPVersion();
 171 
 172         // Check if the profile is from a legacy Sun ORB.
 173 
 174         ORBVersion targetOrbVersion = prof.getORBVersion();
 175         if (!(targetOrbVersion.equals(ORBVersionFactory.getFOREIGN())) &&
 176                 targetOrbVersion.lessThan(ORBVersionFactory.getNEWER())) {
 177             // we are dealing with a SUN legacy orb which emits 1.1 IORs,
 178             // in spite of being able to handle only GIOP 1.0 messages.
 179             return V1_0;
 180         }
 181 
 182         // Now the target has to be (FOREIGN | NEWER*)
 183 
 184         byte prof_major = profVersion.getMajor();
 185         byte prof_minor = profVersion.getMinor();
 186 
 187         byte orb_major = orbVersion.getMajor();
 188         byte orb_minor = orbVersion.getMinor();
 189 
 190         if (orb_major < prof_major) {
 191             return orbVersion;
 192         } else if (orb_major > prof_major) {
 193             return profVersion;
 194         } else { // both major version are the same
 195             if (orb_minor <= prof_minor) {
 196                 return orbVersion;
 197             } else {
 198                 return profVersion;
 199             }
 200         }
 201     }
 202 
 203     public boolean supportsIORIIOPProfileComponents()
 204     {
 205         return getMinor() > 0 || getMajor() > 1;
 206     }
 207 
 208     // IO methods
 209 
 210     public void read(org.omg.CORBA.portable.InputStream istream) {
 211         this.major = istream.read_octet();
 212         this.minor = istream.read_octet();
 213     }
 214 
 215     public void write(org.omg.CORBA.portable.OutputStream ostream) {
 216         ostream.write_octet(this.major);
 217         ostream.write_octet(this.minor);
 218     }
 219 }