001package org.apache.turbine.util;
002
003
004/*
005 * Licensed to the Apache Software Foundation (ASF) under one
006 * or more contributor license agreements.  See the NOTICE file
007 * distributed with this work for additional information
008 * regarding copyright ownership.  The ASF licenses this file
009 * to you under the Apache License, Version 2.0 (the
010 * "License"); you may not use this file except in compliance
011 * with the License.  You may obtain a copy of the License at
012 *
013 *   http://www.apache.org/licenses/LICENSE-2.0
014 *
015 * Unless required by applicable law or agreed to in writing,
016 * software distributed under the License is distributed on an
017 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
018 * KIND, either express or implied.  See the License for the
019 * specific language governing permissions and limitations
020 * under the License.
021 */
022
023
024import java.io.BufferedInputStream;
025import java.io.BufferedOutputStream;
026import java.io.ByteArrayInputStream;
027import java.io.ByteArrayOutputStream;
028import java.io.IOException;
029import java.io.ObjectInputStream;
030import java.io.ObjectOutputStream;
031import java.io.Serializable;
032import java.util.Hashtable;
033import java.util.Map;
034
035/**
036 * This is where common Object manipulation routines should go.
037 *
038 * @author <a href="mailto:nissim@nksystems.com">Nissim Karpenstein</a>
039 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
040 * @version $Id: ObjectUtils.java 1524160 2013-09-17 18:37:14Z tv $
041 */
042public abstract class ObjectUtils
043{
044    /**
045     * Converts a map to a byte array for storage/serialization.
046     *
047     * @param map The Map to convert.
048     *
049     * @return A byte[] with the converted Map.
050     *
051     * @exception Exception A generic exception.
052     */
053    public static byte[] serializeMap(Map<String, Object> map)
054        throws Exception
055    {
056        Map<String, Serializable> saveData =
057            new Hashtable<String, Serializable>(map.size());
058        String key = null;
059        Object value = null;
060        byte[] byteArray = null;
061
062        for (Map.Entry<String, Object> entry : map.entrySet())
063        {
064            key = entry.getKey();
065            value = entry.getValue();
066            if (value instanceof Serializable)
067            {
068                saveData.put (key, (Serializable)value);
069            }
070        }
071
072        ByteArrayOutputStream baos = null;
073        BufferedOutputStream bos = null;
074        ObjectOutputStream out = null;
075        try
076        {
077            // These objects are closed in the finally.
078            baos = new ByteArrayOutputStream();
079            bos  = new BufferedOutputStream(baos);
080            out  = new ObjectOutputStream(bos);
081
082            out.writeObject(saveData);
083            out.flush();
084            bos.flush();
085
086            byteArray = baos.toByteArray();
087        }
088        finally
089        {
090            if (out != null)
091            {
092                out.close();
093            }
094            if (bos != null)
095            {
096                bos.close();
097            }
098            if (baos != null)
099            {
100                baos.close();
101            }
102        }
103        return byteArray;
104    }
105
106    /**
107     * Deserializes a single object from an array of bytes.
108     *
109     * @param objectData The serialized object.
110     *
111     * @return The deserialized object, or <code>null</code> on failure.
112     */
113    @SuppressWarnings("unchecked")
114    public static <T> T deserialize(byte[] objectData)
115    {
116        T object = null;
117
118        if (objectData != null)
119        {
120            // These streams are closed in finally.
121            ObjectInputStream in = null;
122            ByteArrayInputStream bin = new ByteArrayInputStream(objectData);
123            BufferedInputStream bufin = new BufferedInputStream(bin);
124
125            try
126            {
127                in = new ObjectInputStream(bufin);
128
129                // If objectData has not been initialized, an
130                // exception will occur.
131                object = (T)in.readObject();
132            }
133            catch (Exception e)
134            {
135                // ignore
136            }
137            finally
138            {
139                try
140                {
141                    if (in != null)
142                    {
143                        in.close();
144                    }
145
146                    bufin.close();
147                    bin.close();
148                }
149                catch (IOException e)
150                {
151                    // ignore
152                }
153            }
154        }
155        return object;
156    }
157}