001package org.apache.commons.jcs3.utils.serialization;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.io.IOException;
023
024import org.apache.commons.jcs3.engine.CacheElement;
025import org.apache.commons.jcs3.engine.CacheElementSerialized;
026import org.apache.commons.jcs3.engine.behavior.ICacheElement;
027import org.apache.commons.jcs3.engine.behavior.ICacheElementSerialized;
028import org.apache.commons.jcs3.engine.behavior.IElementSerializer;
029import org.apache.commons.jcs3.log.Log;
030import org.apache.commons.jcs3.log.LogManager;
031
032/**
033 * This uses a supplied Serializer to convert to and from cache elements.
034 */
035public class SerializationConversionUtil
036{
037    /** The logger */
038    private static final Log log = LogManager.getLog( SerializationConversionUtil.class );
039
040    /**
041     * This returns a wrapper that has a serialized version of the value instead
042     * of the value.
043     * <p>
044     * @param element
045     * @param elementSerializer
046     *            the serializer to be used.
047     * @return null for null;
048     * @throws IOException
049     */
050    public static <K, V> ICacheElementSerialized<K, V> getSerializedCacheElement( final ICacheElement<K, V> element,
051                                                                    final IElementSerializer elementSerializer )
052        throws IOException
053    {
054        if ( element == null )
055        {
056            return null;
057        }
058
059        byte[] serializedValue = null;
060
061        // if it has already been serialized, don't do it again.
062        if ( element instanceof ICacheElementSerialized )
063        {
064            serializedValue = ( (ICacheElementSerialized<K, V>) element ).getSerializedValue();
065        }
066        else
067        {
068            if ( elementSerializer == null ) {
069                // we could just use the default.
070                throw new IOException( "Could not serialize object. The ElementSerializer is null." );
071            }
072            try
073            {
074                serializedValue = elementSerializer.serialize(element.getVal());
075
076                // update size in bytes
077                element.getElementAttributes().setSize(serializedValue.length);
078            }
079            catch ( final IOException e )
080            {
081                log.error( "Problem serializing object.", e );
082                throw e;
083            }
084        }
085
086        return new CacheElementSerialized<>(
087                element.getCacheName(), element.getKey(), serializedValue, element.getElementAttributes() );
088    }
089
090    /**
091     * This returns a wrapper that has a de-serialized version of the value
092     * instead of the serialized value.
093     * <p>
094     * @param serialized
095     * @param elementSerializer
096     *            the serializer to be used.
097     * @return null for null;
098     * @throws IOException
099     * @throws ClassNotFoundException
100     */
101    public static <K, V> ICacheElement<K, V> getDeSerializedCacheElement( final ICacheElementSerialized<K, V> serialized,
102                                                            final IElementSerializer elementSerializer )
103        throws IOException, ClassNotFoundException
104    {
105        if ( serialized == null )
106        {
107            return null;
108        }
109
110        V deSerializedValue = null;
111
112        if ( elementSerializer == null ) {
113            // we could just use the default.
114            throw new IOException( "Could not de-serialize object. The ElementSerializer is null." );
115        }
116        try
117        {
118            deSerializedValue = elementSerializer.deSerialize( serialized.getSerializedValue(), null );
119        }
120        catch ( final ClassNotFoundException | IOException e )
121        {
122            log.error( "Problem de-serializing object.", e );
123            throw e;
124        }
125        final ICacheElement<K, V> deSerialized = new CacheElement<>( serialized.getCacheName(), serialized.getKey(), deSerializedValue );
126        deSerialized.setElementAttributes( serialized.getElementAttributes() );
127
128        return deSerialized;
129    }
130}