View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17
    18  /*
    19   * ObjectIdentity.java
    20   *
    21   */
    22
    23  package javax.jdo.identity;
    24
    25  import java.io.IOException;
    26  import java.io.ObjectInput;
    27  import java.io.ObjectOutput;
    28
    29  import java.security.AccessController;
    30  import java.security.PrivilegedAction;
    31
    32  import javax.jdo.JDOUserException;
    33
    34  import javax.jdo.spi.JDOImplHelper;
    35
    36  /** This class is for identity with a single Object type field.
    37   * @version 2.0
    38   */
    39  public class ObjectIdentity extends SingleFieldIdentity {
    40
    41      /** The key is stored in the superclass field keyAsObject.
    42       */
    43
    44      /** The JDOImplHelper instance used for parsing the String to an Object.
    45       */
    46      private static JDOImplHelper helper = (JDOImplHelper)
    47          AccessController.doPrivileged(
    48              new PrivilegedAction<JDOImplHelper> () {
    49                  public JDOImplHelper run () {
    50                      return JDOImplHelper.getInstance();
    51                  }
    52              }
    53          );
    54
    55      /** The delimiter for String constructor.
    56       */
    57      private static final String STRING_DELIMITER = ":"; //NOI18N
    58
    59      /** Constructor with class and key.
    60       * @param pcClass the class
    61       * @param param the key
    62       */
    63      @SuppressWarnings("static-access")
    64      public ObjectIdentity (Class pcClass, Object param) {
    65          super (pcClass);
    66          assertKeyNotNull(param);
    67          String paramString = null;
    68          String keyString = null;
    69          String className = null;
    70          if (param instanceof String) {
    71              /* The paramString is of the form "<className>:<keyString>" */
    72              paramString = (String)param;
    73              if (paramString.length() < 3) {
    74                  throw new JDOUserException(
    75                      msg.msg("EXC_ObjectIdentityStringConstructionTooShort") + //NOI18N
    76                      msg.msg("EXC_ObjectIdentityStringConstructionUsage", //NOI18N
    77                          paramString));
    78              }
    79              int indexOfDelimiter = paramString.indexOf(STRING_DELIMITER);
    80              if (indexOfDelimiter < 0) {
    81                  throw new JDOUserException(
    82                      msg.msg("EXC_ObjectIdentityStringConstructionNoDelimiter") + //NOI18N
    83                      msg.msg("EXC_ObjectIdentityStringConstructionUsage", //NOI18N
    84                          paramString));
    85              }
    86              keyString = paramString.substring(indexOfDelimiter+1);
    87              className = paramString.substring(0, indexOfDelimiter);
    88              keyAsObject = helper.construct(className, keyString);
    89          } else {
    90              keyAsObject = param;
    91          }
    92          hashCode = hashClassName() ^ keyAsObject.hashCode();
    93      }
    94
    95      /** Constructor only for Externalizable.
    96       */
    97      public ObjectIdentity () {
    98      }
    99
    100     /** Return the key.
    101      * @return the key
    102      */
    103     public Object getKey () {
    104         return keyAsObject;
    105     }
    106
    107     /** Return the String form of the object id. The class of the
    108      * object id is written as the first part of the result so that
    109      * the class can be reconstructed later. Then the toString
    110      * of the key instance is appended. During construction,
    111      * this process is reversed. The class is extracted from
    112      * the first part of the String, and the String constructor
    113      * of the key is used to construct the key itself.
    114      * @return the String form of the key
    115      */
    116     @Override
    117     public String toString () {
    118         return keyAsObject.getClass().getName()
    119                 + STRING_DELIMITER
    120                 + keyAsObject.toString();
    121     }
    122
    123     /** Determine if the other object represents the same object id.
    124      * @param obj the other object
    125      * @return true if both objects represent the same object id
    126      */
    127     @Override
    128     public boolean equals (Object obj) {
    129         if (this == obj) {
    130             return true;
    131         } else if (!super.equals (obj)) {
    132             return false;
    133         } else {
    134             ObjectIdentity other = (ObjectIdentity) obj;
    135             return keyAsObject.equals(other.keyAsObject);
    136         }
    137     }
    138
    139     /** Provide the hash code for this instance. The hash code is the
    140      * hash code of the contained key.
    141      * @return the hash code
    142      */
    143     @Override
    144     public int hashCode() {
    145         return keyAsObject.hashCode();
    146     }
    147
    148     /** Determine the ordering of identity objects.
    149      * @param o Other identity
    150      * @return The relative ordering between the objects
    151      * @since 2.2
    152      */
    153     @SuppressWarnings("unchecked")
    154     public int compareTo(Object o) {
    155         if (o instanceof ObjectIdentity) {
    156         	ObjectIdentity other = (ObjectIdentity)o;
    157             int result = super.compare(other);
    158             if (result == 0) {
    159                 if (other.keyAsObject instanceof Comparable &&
    160                         keyAsObject instanceof Comparable) {
    161                     return ((Comparable)keyAsObject).compareTo(
    162                             (Comparable)other.keyAsObject);
    163                 }
    164                 else
    165                 {
    166                     throw new ClassCastException("The key class (" +
    167                             keyAsObject.getClass().getName() +
    168                             ") does not implement Comparable");
    169                 }
    170             } else {
    171                 return result;
    172             }
    173         }
    174         else if (o == null) {
    175             throw new ClassCastException("object is null");
    176         }
    177         throw new ClassCastException(this.getClass().getName() +
    178                 " != " + o.getClass().getName());
    179     }
    180
    181     /** Write this object. Write the superclass first.
    182      * @param out the output
    183      */
    184     @Override
    185     public void writeExternal(ObjectOutput out) throws IOException {
    186         super.writeExternal (out);
    187         out.writeObject(keyAsObject);
    188     }
    189
    190     /** Read this object. Read the superclass first.
    191      * @param in the input
    192      */
    193     @Override
    194     public void readExternal(ObjectInput in)
    195 		throws IOException, ClassNotFoundException {
    196         super.readExternal (in);
    197         keyAsObject = in.readObject();
    198     }
    199
    200 }