Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*-
   * See the file LICENSE for redistribution information.
   *
   * Copyright (c) 2002, 2013 Oracle and/or its affiliates.  All rights reserved.
   *
   */
  
  package com.sleepycat.persist.impl;
  
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
Format for all enum types. In this class we resort to using reflection to allocate arrays of enums. If there is a need for it, reflection could be avoided in the future by generating code as new array formats are encountered.

Author(s):
Mark Hayes
 
 public class EnumFormat extends Format {
 
     private static final long serialVersionUID = 1069833955604373538L;
 
     private String[] names;
     private transient Object[] values;
 
     EnumFormat(Catalog catalogClass type) {
         super(catalogtype);
          = type.getEnumConstants();
          = new String[.];
         for (int i = 0; i < .i += 1) {
             [i] = ((Enum[i]).name();
         }
     }

    
For use in a deserialized CompositeKeyFormat.
 
     EnumFormat(Catalog catalogClass typeString[] enumData) {
         super(catalogtype);
          = enumData;
     }

    
Returns data needed for serialization of a CompositeKeyFormat.
 
     String[] getFormatData() {
         return ;
     }
 
     @Override
     public boolean isEnum() {
         return true;
     }
 
     @Override
     public List<StringgetEnumConstants() {
         return Arrays.asList();
     }
 
     @Override
     void collectRelatedFormats(Catalog catalog,
                                Map<StringFormatnewFormats) {
     }
 
     @Override
     void initialize(Catalog catalogEntityModel modelint initVersion) {
         if ( == null) {
             initValues();
         }
     }
 
     private void initValues() {
         Class cls = getType();
         if (cls != null) {
              = new Object[.];
             for (int i = 0; i < .i += 1) {
                 try {
                     [i] = Enum.valueOf(cls[i]);
                 } catch (IllegalArgumentException e) {
                     throw new IllegalArgumentException
                         ("Deletion and renaming of enum values is not " +
                          "supported: " + [i], e);
                 }
             }
         }
     }
    @Override
    Object newArray(int len) {
        return Array.newInstance(getType(), len);
    }
    @Override
    public Object newInstance(EntityInput inputboolean rawAccess) {
        int index = input.readEnumConstant();
        if (rawAccess) {
            return new RawObject(this[index]);
        } else {
            return [index];
        }
    }
    @Override
    public Object readObject(Object oEntityInput inputboolean rawAccess) {
        /* newInstance reads the value -- do nothing here. */
        return o;
    }
    @Override
    void writeObject(Object oEntityOutput outputboolean rawAccess) {
        if (rawAccess) {
            String name = ((RawObjecto).getEnum();
            for (int i = 0; i < .i += 1) {
                if ([i].equals(name)) {
                    output.writeEnumConstant(i);
                    return;
                }
            }
        } else {
            for (int i = 0; i < .i += 1) {
                if (o == [i]) {
                    output.writeEnumConstant(i);
                    return;
                }
            }
        }
        throw DbCompat.unexpectedState("Bad enum: " + o);
    }
    @Override
                            boolean rawAccess,
                            RawObject rawObject,
                            IdentityHashMap converted) {
        String name = rawObject.getEnum();
        for (int i = 0; i < .i += 1) {
            if ([i].equals(name)) {
                Object o = [i];
                converted.put(rawObjecto);
                return o;
            }
        }
        throw new IllegalArgumentException
            ("Enum constant is not defined: " + name);
    }
    @Override
    void skipContents(RecordInput input) {
        input.skipFast(input.getPackedIntByteLength());
    }
    @Override
    void copySecKey(RecordInput inputRecordOutput output) {
        int len = input.getPackedIntByteLength();
        output.writeFast
            (input.getBufferBytes(), input.getBufferOffset(), len);
        input.skipFast(len);
    }
    @Override
    boolean evolve(Format newFormatParamEvolver evolver) {
        if (!(newFormatParam instanceof EnumFormat)) {
            evolver.addEvolveError
                (thisnewFormatParam,
                 "Incompatible enum type changed detected",
                 "An enum class may not be changed to a non-enum type");
            /* For future:
            evolver.addMissingMutation
                (this, newFormatParam,
                 "Converter is required when an enum class is changed to " +
                 "a non-enum type");
            */
            return false;
        }
        final EnumFormat newFormat = (EnumFormatnewFormatParam;
        /* Return quickly if the enum was not changed at all. */
        if (Arrays.equals(newFormat.names)) {
            evolver.useOldFormat(thisnewFormat);
            return true;
        }
        final List<StringnewNamesList = Arrays.asList(newFormat.names);
        final Set<StringnewNamesSet = new HashSet<String>(newNamesList);
        final List<StringoldNamesList = Arrays.asList();
        /* Deletion (or renaming, which appears as deletion) is not allowed. */
        if (!newNamesSet.containsAll(oldNamesList)) {
            final Set<StringoldNamesSet = new HashSet<String>(oldNamesList);
            oldNamesSet.removeAll(newNamesSet);
            evolver.addEvolveError
                (thisnewFormat,
                 "Incompatible enum type changed detected",
                 "Enum values may not be removed: " + oldNamesSet);
        }
        /* Use a List for additional names to preserve ordinal order. */
        final List<StringadditionalNamesList =
            new ArrayList<String>(newNamesList);
        additionalNamesList.removeAll(oldNamesList);
        final int nAdditionalNames = additionalNamesList.size();
        /*
         * If there are no aditional names, the new and old formats are
         * equivalent.  This is the case where only the declaration order was
         * changed.
         */
        if (nAdditionalNames == 0) {
            evolver.useOldFormat(thisnewFormat);
            return true;
        }
        /*
         * Evolve the new format.  It should use the old names array, but with
         * any additional names appended.  [#17140]
         */
        final int nOldNames = .;
        newFormat.names = new String[nOldNames + nAdditionalNames];
        System.arraycopy(, 0, newFormat.names, 0, nOldNames);
        for (int i = 0; i < nAdditionalNamesi += 1) {
            newFormat.names[nOldNames + i] = additionalNamesList.get(i);
        }
        newFormat.initValues();
        /*
         * Because we never change the array index (stored integer value) for
         * an enum value, the new format can read the values written by the old
         * format (newFormat is used as the Reader in the 2nd param below).
         */
        evolver.useEvolvedFormat(thisnewFormatnewFormat);
        return true;
    }
New to GrepCode? Check out our FAQ X