/*
 * Copyright 2006-2010 Amazon Technologies, Inc. or its affiliates.
 * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks
 * of Amazon Technologies, Inc. or its affiliates.  All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.amazon.carbonado;

/**
 * A CorruptEncodingException is caused when decoding an encoded record fails.
 *
 * @author Brian S O'Neill
 */
public class CorruptEncodingException extends FetchException {

    private static final long serialVersionUID = 4543503149683482362L;

    private transient Storable mStorable;

    public CorruptEncodingException() {
        super();
    }

    public CorruptEncodingException(String message) {
        super(message);
    }

    public CorruptEncodingException(String message, Throwable cause) {
        super(message, cause);
    }

    public CorruptEncodingException(Throwable cause) {
        super(cause);
    }

    /**
     * @param expectedGeneration expected layout generation of decoded storable
     * @param actualGeneration actual layout generation of decoded storable
     */
    public CorruptEncodingException(int expectedGeneration, int actualGeneration) {
        super("Expected layout generation of " + expectedGeneration +
              ", but actual layout generation was " + actualGeneration);
    }

    /**
     * If the decoder can at least extract the primary key, it should set it here.
     */
    public void setStorableWithPrimaryKey(Storable s) {
        if (s != null) {
            // Do this to ensure that primary key is known to be defined.
            s.markAllPropertiesClean();
        }
        mStorable = s;
    }

    /**
     * If the decoder was able to extract the primary key, it will be available
     * in the returned Storable.
     *
     * @return partial Storable with primary key defined, or null if unable to
     * decode the key
     */
    public Storable getStorableWithPrimaryKey() {
        return mStorable;
    }

    @Override
    public String getMessage() {
        String message = super.getMessage();
        
        if (mStorable != null) {
            message = message + "; " + mStorable.toStringKeyOnly();
        }

        return message;
    }
}

@@ -827,16 +827,180 @@
 ado;%0D%0A%0D%0A
+import java.io.IOException;%0D%0Aimport java.io.ObjectInputStream;%0D%0Aimport java.io.ObjectOutputStream;%0D%0A%0D%0Aimport com.amazon.carbonado.repo.map.MapRepositoryBuilder;%0D%0A%0D%0A
 /**%0D%0A * 
@@ -1232,26 +1232,8 @@
 D = 
-454350314968348236
 2L;%0D
@@ -2482,24 +2482,31 @@
 be available
+ in the
 %0D%0A     * in 
@@ -2506,15 +2506,8 @@
   * 
-in the 
 retu
@@ -2519,16 +2519,208 @@
 Storable
+. If this exception was re-constructed through serialization, then%0D%0A     * the Storable is as well. As a result, it won't be bound to any Repository and%0D%0A     * updating it will have no effect
 .%0D%0A     
@@ -3138,24 +3138,24 @@
        %7D%0D%0A%0D%0A
-
         retu
@@ -3173,12 +3173,1141 @@
 %0D%0A    %7D%0D
+%0A%0D%0A    // Serialization of corrupt Storable assumes that primary key endoding of client and%0D%0A    // server is identical. Linking into the actual repository is a bit trickier.%0D%0A%0D%0A    private void writeObject(ObjectOutputStream out) throws IOException %7B%0D%0A        Storable s = mStorable;%0D%0A        if (s == null) %7B%0D%0A            out.write(0);%0D%0A        %7D else %7B%0D%0A            out.write(1);%0D%0A            out.writeObject(s.storableType());%0D%0A            try %7B%0D%0A                s.writeTo(out);%0D%0A            %7D catch (SupportException e) %7B%0D%0A                throw new IOException(e);%0D%0A            %7D%0D%0A        %7D%0D%0A    %7D%0D%0A%0D%0A    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException %7B%0D%0A        int h = in.read();%0D%0A        if (h == 1) %7B%0D%0A            try %7B%0D%0A                Class%3C? extends Storable%3E type = (Class) in.readObject();%0D%0A                Storable s = MapRepositoryBuilder.newRepository().storageFor(type).prepare();%0D%0A                s.readFrom(in);%0D%0A                mStorable = s;%0D%0A            %7D catch (RepositoryException e) %7B%0D%0A                throw new IOException(e);%0D%0A            %7D%0D%0A        %7D%0D%0A    %7D%0D
 %0A%7D%0D%0A

Support serialization of corrupt storable.