001/* 002 Licensed to the Apache Software Foundation (ASF) under one 003 or more contributor license agreements. See the NOTICE file 004 distributed with this work for additional information 005 regarding copyright ownership. The ASF licenses this file 006 to you under the Apache License, Version 2.0 (the 007 "License"); you may not use this file except in compliance 008 with the License. You may obtain a copy of the License at 009 010 http://www.apache.org/licenses/LICENSE-2.0 011 012 Unless required by applicable law or agreed to in writing, 013 software distributed under the License is distributed on an 014 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 KIND, either express or implied. See the License for the 016 specific language governing permissions and limitations 017 under the License. 018 */ 019package org.apache.wiki.util; 020 021import java.io.ByteArrayInputStream; 022import java.io.ByteArrayOutputStream; 023import java.io.IOException; 024import java.io.InputStream; 025import java.io.ObjectInputStream; 026import java.io.ObjectOutputStream; 027import java.io.Serializable; 028import java.nio.charset.StandardCharsets; 029import java.util.Base64; 030import java.util.HashMap; 031import java.util.Map; 032 033 034/** 035 * Provides static helper functions for serializing different objects. 036 * 037 * @since 2.8 038 */ 039public final class Serializer 040{ 041 /** 042 * Prefix used to indicated that a serialized item was encoded with Base64. 043 */ 044 protected static final String BASE64_PREFIX = "base64 "; 045 046 /** 047 * Prevent instantiation. 048 */ 049 private Serializer() 050 {} 051 052 /** 053 * Deserializes a Base64-encoded String into a HashMap. Both the keys and values 054 * must implement {@link java.io.Serializable}. 055 * @param rawString the String contents containing the map to be deserialized 056 * @return the attributes, parsed into a Map 057 * @throws IOException if the contents cannot be parsed for any reason 058 */ 059 @SuppressWarnings("unchecked") 060 public static Map< String, ? extends Serializable > deserializeFromBase64( String rawString ) throws IOException { 061 // Decode from Base64-encoded String to byte array 062 byte[] decodedBytes = Base64.getDecoder().decode( rawString.getBytes( StandardCharsets.UTF_8 ) ); 063 064 // Deserialize from the input stream to the Map 065 InputStream bytesIn = new ByteArrayInputStream( decodedBytes ); 066 try( ObjectInputStream in = new ObjectInputStream( bytesIn ) ) { 067 return ( HashMap< String, Serializable > )in.readObject(); 068 } catch ( ClassNotFoundException e ) { 069 throw new IOException( "Could not deserialiaze user profile attributes. Reason: " + e.getMessage() ); 070 } 071 } 072 073 /** 074 * Serializes a Map and formats it into a Base64-encoded String. For ease of serialization, the Map contents 075 * are first copied into a HashMap, then serialized into a byte array that is encoded as a Base64 String. 076 * @param map the Map to serialize 077 * @return a String representing the serialized form of the Map 078 * @throws IOException If serialization cannot be done 079 */ 080 public static String serializeToBase64( Map< String, Serializable > map ) throws IOException { 081 // Load the Map contents into a defensive HashMap 082 Map< String, Serializable > serialMap = new HashMap<>(); 083 serialMap.putAll( map ); 084 085 // Serialize the Map to an output stream 086 ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); 087 ObjectOutputStream out = new ObjectOutputStream( bytesOut ); 088 out.writeObject( serialMap ); 089 out.close(); 090 091 // Transform to Base64-encoded String 092 byte[] result = Base64.getEncoder().encode( bytesOut.toByteArray() ); 093 return new String( result ) ; 094 } 095 096}