Home » openjdk-7 » java » io » [javadoc | source]

    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   package java.io;
   19   
   20   /**
   21    * An EmulatedFields is an object that represents a set of emulated fields for
   22    * an object being dumped or loaded. It allows objects to be dumped with a shape
   23    * different than the fields they were declared to have.
   24    * 
   25    * @see ObjectInputStream.GetField
   26    * @see ObjectOutputStream.PutField
   27    * @see EmulatedFieldsForLoading
   28    * @see EmulatedFieldsForDumping
   29    */
   30   class EmulatedFields {
   31   
   32       // A slot is a field plus its value
   33       static class ObjectSlot {
   34   
   35           // Field descriptor
   36           ObjectStreamField field;
   37   
   38           // Actual value this emulated field holds
   39           Object fieldValue;
   40   
   41           // If this field has a default value (true) or something has been
   42           // assigned (false)
   43           boolean defaulted = true;
   44   
   45           /**
   46            * Returns the descriptor for this emulated field.
   47            * 
   48            * @return the field descriptor
   49            */
   50           public ObjectStreamField getField() {
   51               return field;
   52           }
   53   
   54           /**
   55            * Returns the value held by this emulated field.
   56            * 
   57            * @return the field value
   58            */
   59           public Object getFieldValue() {
   60               return fieldValue;
   61           }
   62       }
   63   
   64       // The collection of slots the receiver represents
   65       private ObjectSlot[] slotsToSerialize;
   66   
   67       private ObjectStreamField[] declaredFields;
   68   
   69       /**
   70        * Constructs a new instance of EmulatedFields.
   71        * 
   72        * @param fields
   73        *            an array of ObjectStreamFields, which describe the fields to
   74        *            be emulated (names, types, etc).
   75        * @param declared
   76        *            an array of ObjectStreamFields, which describe the declared
   77        *            fields.
   78        */
   79       public EmulatedFields(ObjectStreamField[] fields,
   80               ObjectStreamField[] declared) {
   81           super();
   82           // We assume the slots are already sorted in the right shape for dumping
   83           buildSlots(fields);
   84           declaredFields = declared;
   85       }
   86   
   87       /**
   88        * Build emulated slots that correspond to emulated fields. A slot is a
   89        * field descriptor (ObjectStreamField) plus the actual value it holds.
   90        * 
   91        * @param fields
   92        *            an array of ObjectStreamField, which describe the fields to be
   93        *            emulated (names, types, etc).
   94        */
   95       private void buildSlots(ObjectStreamField[] fields) {
   96           slotsToSerialize = new ObjectSlot[fields.length];
   97           for (int i = 0; i < fields.length; i++) {
   98               ObjectSlot s = new ObjectSlot();
   99               slotsToSerialize[i] = s;
  100               s.field = fields[i];
  101           }
  102           // We assume the slots are already sorted in the right shape for dumping
  103       }
  104   
  105       /**
  106        * Returns {@code true} indicating the field called {@code name} has not had
  107        * a value explicitly assigned and that it still holds a default value for
  108        * its type, or {@code false} indicating that the field named has been
  109        * assigned a value explicitly.
  110        * 
  111        * @param name
  112        *            the name of the field to test.
  113        * @return {@code true} if {@code name} still holds its default value,
  114        *         {@code false} otherwise
  115        * 
  116        * @throws IllegalArgumentException
  117        *             if {@code name} is {@code null}
  118        */
  119       public boolean defaulted(String name) throws IllegalArgumentException {
  120           ObjectSlot slot = findSlot(name, null);
  121           if (slot == null) {
  122               throw new IllegalArgumentException();
  123           }
  124           return slot.defaulted;
  125       }
  126   
  127       /**
  128        * Finds and returns an ObjectSlot that corresponds to a field named {@code
  129        * fieldName} and type {@code fieldType}. If the field type {@code
  130        * fieldType} corresponds to a primitive type, the field type has to match
  131        * exactly or {@code null} is returned. If the field type {@code fieldType}
  132        * corresponds to an object type, the field type has to be compatible in
  133        * terms of assignment, or null is returned. If {@code fieldType} is {@code
  134        * null}, no such compatibility checking is performed and the slot is
  135        * returned.
  136        * 
  137        * @param fieldName
  138        *            the name of the field to find
  139        * @param fieldType
  140        *            the type of the field. This will be used to test
  141        *            compatibility. If {@code null}, no testing is done, the
  142        *            corresponding slot is returned.
  143        * @return the object slot, or {@code null} if there is no field with that
  144        *         name, or no compatible field (relative to {@code fieldType})
  145        */
  146       private ObjectSlot findSlot(String fieldName, Class<?> fieldType) {
  147           boolean isPrimitive = fieldType != null && fieldType.isPrimitive();
  148   
  149           for (int i = 0; i < slotsToSerialize.length; i++) {
  150               ObjectSlot slot = slotsToSerialize[i];
  151               if (slot.field.getName().equals(fieldName)) {
  152                   if (isPrimitive) {
  153                       // Looking for a primitive type field. Types must match
  154                       // *exactly*
  155                       if (slot.field.getType() == fieldType) {
  156                           return slot;
  157                       }
  158                   } else {
  159                       // Looking for a non-primitive type field.
  160                       if (fieldType == null) {
  161                           return slot; // Null means we take anything
  162                       }
  163                       // Types must be compatible (assignment)
  164                       if (slot.field.getType().isAssignableFrom(fieldType)) {
  165                           return slot;
  166                       }
  167                   }
  168               }
  169           }
  170   
  171           if (declaredFields != null) {
  172               for (int i = 0; i < declaredFields.length; i++) {
  173                   ObjectStreamField field = declaredFields[i];
  174                   if (field.getName().equals(fieldName)) {
  175                       if (isPrimitive ? field.getType() == fieldType
  176                               : fieldType == null
  177                                       || field.getType().isAssignableFrom(
  178                                               fieldType)) {
  179                           ObjectSlot slot = new ObjectSlot();
  180                           slot.field = field;
  181                           slot.defaulted = true;
  182                           return slot;
  183                       }
  184                   }
  185               }
  186           }
  187           return null;
  188       }
  189   
  190       /**
  191        * Finds and returns the byte value of a given field named {@code name}
  192        * in the receiver. If the field has not been assigned any value yet, the
  193        * default value {@code defaultValue} is returned instead.
  194        * 
  195        * @param name
  196        *            the name of the field to find.
  197        * @param defaultValue
  198        *            return value in case the field has not been assigned to yet.
  199        * @return the value of the given field if it has been assigned, the default
  200        *         value otherwise.
  201        * 
  202        * @throws IllegalArgumentException
  203        *             if the corresponding field can not be found.
  204        */
  205       public byte get(String name, byte defaultValue)
  206               throws IllegalArgumentException {
  207           ObjectSlot slot = findSlot(name, Byte.TYPE);
  208           // if not initialized yet, we give the default value
  209           if (slot == null) {
  210               throw new IllegalArgumentException();
  211           }
  212           return slot.defaulted ? defaultValue : ((Byte) slot.fieldValue)
  213                   .byteValue();
  214       }
  215   
  216       /**
  217        * Finds and returns the char value of a given field named {@code name} in the
  218        * receiver. If the field has not been assigned any value yet, the default
  219        * value {@code defaultValue} is returned instead.
  220        * 
  221        * @param name
  222        *            the name of the field to find.
  223        * @param defaultValue
  224        *            return value in case the field has not been assigned to yet.
  225        * @return the value of the given field if it has been assigned, the default
  226        *         value otherwise.
  227        * 
  228        * @throws IllegalArgumentException
  229        *             if the corresponding field can not be found.
  230        */
  231       public char get(String name, char defaultValue)
  232               throws IllegalArgumentException {
  233           ObjectSlot slot = findSlot(name, Character.TYPE);
  234           // if not initialized yet, we give the default value
  235           if (slot == null) {
  236               throw new IllegalArgumentException();
  237           }
  238           return slot.defaulted ? defaultValue : ((Character) slot.fieldValue)
  239                   .charValue();
  240       }
  241   
  242       /**
  243        * Finds and returns the double value of a given field named {@code name}
  244        * in the receiver. If the field has not been assigned any value yet, the
  245        * default value {@code defaultValue} is returned instead.
  246        * 
  247        * @param name
  248        *            the name of the field to find.
  249        * @param defaultValue
  250        *            return value in case the field has not been assigned to yet.
  251        * @return the value of the given field if it has been assigned, the default
  252        *         value otherwise.
  253        * 
  254        * @throws IllegalArgumentException
  255        *             if the corresponding field can not be found.
  256        */
  257       public double get(String name, double defaultValue)
  258               throws IllegalArgumentException {
  259           ObjectSlot slot = findSlot(name, Double.TYPE);
  260           // if not initialized yet, we give the default value
  261           if (slot == null) {
  262               throw new IllegalArgumentException();
  263           }
  264           return slot.defaulted ? defaultValue : ((Double) slot.fieldValue)
  265                   .doubleValue();
  266       }
  267   
  268       /**
  269        * Finds and returns the float value of a given field named {@code name} in
  270        * the receiver. If the field has not been assigned any value yet, the
  271        * default value {@code defaultValue} is returned instead.
  272        * 
  273        * @param name
  274        *            the name of the field to find.
  275        * @param defaultValue
  276        *            return value in case the field has not been assigned to yet.
  277        * @return the value of the given field if it has been assigned, the default
  278        *         value otherwise.
  279        * 
  280        * @throws IllegalArgumentException
  281        *             if the corresponding field can not be found.
  282        */
  283       public float get(String name, float defaultValue)
  284               throws IllegalArgumentException {
  285           ObjectSlot slot = findSlot(name, Float.TYPE);
  286           // if not initialized yet, we give the default value
  287           if (slot == null) {
  288               throw new IllegalArgumentException();
  289           }
  290           return slot.defaulted ? defaultValue : ((Float) slot.fieldValue)
  291                   .floatValue();
  292       }
  293   
  294       /**
  295        * Finds and returns the int value of a given field named {@code name} in the
  296        * receiver. If the field has not been assigned any value yet, the default
  297        * value {@code defaultValue} is returned instead.
  298        * 
  299        * @param name
  300        *            the name of the field to find.
  301        * @param defaultValue
  302        *            return value in case the field has not been assigned to yet.
  303        * @return the value of the given field if it has been assigned, the default
  304        *         value otherwise.
  305        * 
  306        * @throws IllegalArgumentException
  307        *             if the corresponding field can not be found.
  308        */
  309       public int get(String name, int defaultValue)
  310               throws IllegalArgumentException {
  311           ObjectSlot slot = findSlot(name, Integer.TYPE);
  312           // if not initialized yet, we give the default value
  313           if (slot == null) {
  314               throw new IllegalArgumentException();
  315           }
  316           return slot.defaulted ? defaultValue : ((Integer) slot.fieldValue)
  317                   .intValue();
  318       }
  319   
  320       /**
  321        * Finds and returns the long value of a given field named {@code name} in the
  322        * receiver. If the field has not been assigned any value yet, the default
  323        * value {@code defaultValue} is returned instead.
  324        * 
  325        * @param name
  326        *            the name of the field to find.
  327        * @param defaultValue
  328        *            return value in case the field has not been assigned to yet.
  329        * @return the value of the given field if it has been assigned, the default
  330        *         value otherwise.
  331        * 
  332        * @throws IllegalArgumentException
  333        *             if the corresponding field can not be found.
  334        */
  335       public long get(String name, long defaultValue)
  336               throws IllegalArgumentException {
  337           ObjectSlot slot = findSlot(name, Long.TYPE);
  338           // if not initialized yet, we give the default value
  339           if (slot == null) {
  340               throw new IllegalArgumentException();
  341           }
  342           return slot.defaulted ? defaultValue : ((Long) slot.fieldValue)
  343                   .longValue();
  344       }
  345   
  346       /**
  347        * Finds and returns the Object value of a given field named {@code name} in
  348        * the receiver. If the field has not been assigned any value yet, the
  349        * default value {@code defaultValue} is returned instead.
  350        * 
  351        * @param name
  352        *            the name of the field to find.
  353        * @param defaultValue
  354        *            return value in case the field has not been assigned to yet.
  355        * @return the value of the given field if it has been assigned, the default
  356        *         value otherwise.
  357        * 
  358        * @throws IllegalArgumentException
  359        *             if the corresponding field can not be found.
  360        */
  361       public Object get(String name, Object defaultValue)
  362               throws IllegalArgumentException {
  363           ObjectSlot slot = findSlot(name, null);
  364           // if not initialized yet, we give the default value
  365           if (slot == null || slot.field.getType().isPrimitive()) {
  366               throw new IllegalArgumentException();
  367           }
  368           return slot.defaulted ? defaultValue : slot.fieldValue;
  369       }
  370   
  371       /**
  372        * Finds and returns the short value of a given field named {@code name} in
  373        * the receiver. If the field has not been assigned any value yet, the
  374        * default value {@code defaultValue} is returned instead.
  375        * 
  376        * @param name
  377        *            the name of the field to find.
  378        * @param defaultValue
  379        *            return value in case the field has not been assigned to yet.
  380        * @return the value of the given field if it has been assigned, the default
  381        *         value otherwise.
  382        * 
  383        * @throws IllegalArgumentException
  384        *             if the corresponding field can not be found.
  385        */
  386       public short get(String name, short defaultValue)
  387               throws IllegalArgumentException {
  388           ObjectSlot slot = findSlot(name, Short.TYPE);
  389           // if not initialized yet, we give the default value
  390           if (slot == null) {
  391               throw new IllegalArgumentException();
  392           }
  393           return slot.defaulted ? defaultValue : ((Short) slot.fieldValue)
  394                   .shortValue();
  395       }
  396   
  397       /**
  398        * Finds and returns the boolean value of a given field named {@code name} in
  399        * the receiver. If the field has not been assigned any value yet, the
  400        * default value {@code defaultValue} is returned instead.
  401        * 
  402        * @param name
  403        *            the name of the field to find.
  404        * @param defaultValue
  405        *            return value in case the field has not been assigned to yet.
  406        * @return the value of the given field if it has been assigned, the default
  407        *         value otherwise.
  408        * 
  409        * @throws IllegalArgumentException
  410        *             if the corresponding field can not be found.
  411        */
  412       public boolean get(String name, boolean defaultValue)
  413               throws IllegalArgumentException {
  414           ObjectSlot slot = findSlot(name, Boolean.TYPE);
  415           // if not initialized yet, we give the default value
  416           if (slot == null) {
  417               throw new IllegalArgumentException();
  418           }
  419           return slot.defaulted ? defaultValue : ((Boolean) slot.fieldValue)
  420                   .booleanValue();
  421       }
  422   
  423       /**
  424        * Find and set the byte value of a given field named {@code name} in the
  425        * receiver.
  426        * 
  427        * @param name
  428        *            the name of the field to set.
  429        * @param value
  430        *            new value for the field.
  431        * 
  432        * @throws IllegalArgumentException
  433        *             if the corresponding field can not be found.
  434        */
  435       public void put(String name, byte value) throws IllegalArgumentException {
  436           ObjectSlot slot = findSlot(name, Byte.TYPE);
  437           if (slot == null) {
  438               throw new IllegalArgumentException();
  439           }
  440           slot.fieldValue = Byte.valueOf(value);
  441           slot.defaulted = false; // No longer default value
  442       }
  443   
  444       /**
  445        * Find and set the char value of a given field named {@code name} in the
  446        * receiver.
  447        * 
  448        * @param name
  449        *            the name of the field to set.
  450        * @param value
  451        *            new value for the field.
  452        * 
  453        * @throws IllegalArgumentException
  454        *             if the corresponding field can not be found.
  455        */
  456       public void put(String name, char value) throws IllegalArgumentException {
  457           ObjectSlot slot = findSlot(name, Character.TYPE);
  458           if (slot == null) {
  459               throw new IllegalArgumentException();
  460           }
  461           slot.fieldValue = Character.valueOf(value);
  462           slot.defaulted = false; // No longer default value
  463       }
  464   
  465       /**
  466        * Find and set the double value of a given field named {@code name} in the
  467        * receiver.
  468        * 
  469        * @param name
  470        *            the name of the field to set.
  471        * @param value
  472        *            new value for the field.
  473        * 
  474        * @throws IllegalArgumentException
  475        *             if the corresponding field can not be found.
  476        */
  477       public void put(String name, double value) throws IllegalArgumentException {
  478           ObjectSlot slot = findSlot(name, Double.TYPE);
  479           if (slot == null) {
  480               throw new IllegalArgumentException();
  481           }
  482           slot.fieldValue = Double.valueOf(value);
  483           slot.defaulted = false; // No longer default value
  484       }
  485   
  486       /**
  487        * Find and set the float value of a given field named {@code name} in the
  488        * receiver.
  489        * 
  490        * @param name
  491        *            the name of the field to set.
  492        * @param value
  493        *            new value for the field.
  494        * 
  495        * @throws IllegalArgumentException
  496        *             if the corresponding field can not be found.
  497        */
  498       public void put(String name, float value) throws IllegalArgumentException {
  499           ObjectSlot slot = findSlot(name, Float.TYPE);
  500           if (slot == null) {
  501               throw new IllegalArgumentException();
  502           }
  503           slot.fieldValue = Float.valueOf(value);
  504           slot.defaulted = false; // No longer default value
  505       }
  506   
  507       /**
  508        * Find and set the int value of a given field named {@code name} in the
  509        * receiver.
  510        * 
  511        * @param name
  512        *            the name of the field to set.
  513        * @param value
  514        *            new value for the field.
  515        * 
  516        * @throws IllegalArgumentException
  517        *             if the corresponding field can not be found.
  518        */
  519       public void put(String name, int value) throws IllegalArgumentException {
  520           ObjectSlot slot = findSlot(name, Integer.TYPE);
  521           if (slot == null) {
  522               throw new IllegalArgumentException();
  523           }
  524           slot.fieldValue = Integer.valueOf(value);
  525           slot.defaulted = false; // No longer default value
  526       }
  527   
  528       /**
  529        * Find and set the long value of a given field named {@code name} in the
  530        * receiver.
  531        * 
  532        * @param name
  533        *            the name of the field to set.
  534        * @param value
  535        *            new value for the field.
  536        * 
  537        * @throws IllegalArgumentException
  538        *             if the corresponding field can not be found.
  539        */
  540       public void put(String name, long value) throws IllegalArgumentException {
  541           ObjectSlot slot = findSlot(name, Long.TYPE);
  542           if (slot == null) {
  543               throw new IllegalArgumentException();
  544           }
  545           slot.fieldValue = Long.valueOf(value);
  546           slot.defaulted = false; // No longer default value
  547       }
  548   
  549       /**
  550        * Find and set the Object value of a given field named {@code name} in the
  551        * receiver.
  552        * 
  553        * @param name
  554        *            the name of the field to set.
  555        * @param value
  556        *            new value for the field.
  557        * 
  558        * @throws IllegalArgumentException
  559        *             if the corresponding field can not be found.
  560        */
  561       public void put(String name, Object value) throws IllegalArgumentException {
  562           Class<?> valueClass = null;
  563           if (value != null) {
  564               valueClass = value.getClass();
  565           }
  566           ObjectSlot slot = findSlot(name, valueClass);
  567           if (slot == null) {
  568               throw new IllegalArgumentException();
  569           }
  570           slot.fieldValue = value;
  571           slot.defaulted = false; // No longer default value
  572       }
  573   
  574       /**
  575        * Find and set the short value of a given field named {@code name} in the
  576        * receiver.
  577        * 
  578        * @param name
  579        *            the name of the field to set.
  580        * @param value
  581        *            new value for the field.
  582        * 
  583        * @throws IllegalArgumentException
  584        *             if the corresponding field can not be found.
  585        */
  586       public void put(String name, short value) throws IllegalArgumentException {
  587           ObjectSlot slot = findSlot(name, Short.TYPE);
  588           if (slot == null) {
  589               throw new IllegalArgumentException();
  590           }
  591           slot.fieldValue = Short.valueOf(value);
  592           slot.defaulted = false; // No longer default value
  593       }
  594   
  595       /**
  596        * Find and set the boolean value of a given field named {@code name} in the
  597        * receiver.
  598        * 
  599        * @param name
  600        *            the name of the field to set.
  601        * @param value
  602        *            new value for the field.
  603        * 
  604        * @throws IllegalArgumentException
  605        *             if the corresponding field can not be found.
  606        */
  607       public void put(String name, boolean value) throws IllegalArgumentException {
  608           ObjectSlot slot = findSlot(name, Boolean.TYPE);
  609           if (slot == null) {
  610               throw new IllegalArgumentException();
  611           }
  612           slot.fieldValue = Boolean.valueOf(value);
  613           slot.defaulted = false; // No longer default value
  614       }
  615   
  616       /**
  617        * Return the array of ObjectSlot the receiver represents.
  618        * 
  619        * @return array of ObjectSlot the receiver represents.
  620        */
  621       public ObjectSlot[] slots() {
  622           return slotsToSerialize;
  623       }
  624   }

Home » openjdk-7 » java » io » [javadoc | source]