001 /*
002 * Cumulus4j - Securing your data in the cloud - http://cumulus4j.org
003 * Copyright (C) 2011 NightLabs Consulting GmbH
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Affero General Public License as
007 * published by the Free Software Foundation, either version 3 of the
008 * License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013 * GNU Affero General Public License for more details.
014 *
015 * You should have received a copy of the GNU Affero General Public License
016 * along with this program. If not, see <http://www.gnu.org/licenses/>.
017 */
018 package org.cumulus4j.keystore.prop;
019
020 import java.io.ByteArrayInputStream;
021 import java.io.ByteArrayOutputStream;
022 import java.io.DataInputStream;
023 import java.io.DataOutputStream;
024 import java.io.IOException;
025 import java.util.Map;
026 import java.util.SortedMap;
027 import java.util.TreeMap;
028
029 /**
030 * {@link Property} implementation for the value type {@link SortedMap}
031 * with both key and value being {@link Long}s.
032 * <p>
033 * Used for example by the date-dependent key-strategy to store it's key-is-valid-from-dates.
034 * </p>
035 *
036 * @author Marco หงุ่ยตระกูล-Schulze - marco at nightlabs dot de
037 */
038 public class Long2LongSortedMapProperty
039 extends Property<SortedMap<Long, Long>>
040 {
041
042 @Override
043 public SortedMap<Long, Long> getValue()
044 {
045 if (super.getValue() == null)
046 setValue(new TreeMap<Long, Long>());
047
048 return super.getValue();
049 }
050
051 @Override
052 public byte[] getValueEncoded()
053 {
054 SortedMap<Long, Long> map = getValue();
055
056 if (map == null || map.isEmpty())
057 return null;
058
059 ByteArrayOutputStream bout = new ByteArrayOutputStream();
060 DataOutputStream out = new DataOutputStream(bout);
061 try {
062 out.writeInt(map.size());
063 for (Map.Entry<Long, Long> me : map.entrySet()) {
064 out.writeLong(me.getKey());
065 out.writeLong(me.getValue());
066 }
067 out.close(); // Might be necessary for the flushing of the DataOutputStream even though the ByteArrayOutputStream doesn't need it.
068 } catch (IOException e) {
069 throw new RuntimeException(e);
070 }
071
072 return bout.toByteArray();
073 }
074
075 @Override
076 public void setValueEncoded(byte[] encodedValue)
077 throws IllegalArgumentException
078 {
079 if (encodedValue == null) {
080 setValue(null);
081 return;
082 }
083
084 DataInputStream in = new DataInputStream(new ByteArrayInputStream(encodedValue));
085 try {
086 int mapSize = in.readInt();
087 SortedMap<Long, Long> map = new TreeMap<Long, Long>();
088 for (int i = 0; i < mapSize; ++i) {
089 long key = in.readLong();
090 long value = in.readLong();
091 map.put(key, value);
092 }
093 setValue(map);
094 } catch (IOException e) {
095 throw new RuntimeException(e);
096 }
097 }
098
099 }