001 /*
002 * Copyright 2005,2009 Ivan SZKIBA
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.ini4j;
017
018 import java.util.Map;
019 import java.util.SortedMap;
020 import java.util.TreeMap;
021
022 public class CommonMultiMap<K, V> extends BasicMultiMap<K, V> implements CommentedMap<K, V>
023 {
024 private static final long serialVersionUID = 3012579878005541746L;
025 private static final String SEPARATOR = ";#;";
026 private static final String FIRST_CATEGORY = "";
027 private static final String LAST_CATEGORY = "zzzzzzzzzzzzzzzzzzzzzz";
028 private static final String META_COMMENT = "comment";
029 private SortedMap<String, Object> _meta;
030
031 @Override public String getComment(Object key)
032 {
033 return (String) getMeta(META_COMMENT, key);
034 }
035
036 @Override public void clear()
037 {
038 super.clear();
039 if (_meta != null)
040 {
041 _meta.clear();
042 }
043 }
044
045 @SuppressWarnings("unchecked")
046 @Override public void putAll(Map<? extends K, ? extends V> map)
047 {
048 super.putAll(map);
049 if (map instanceof CommonMultiMap)
050 {
051 Map<String, String> meta = ((CommonMultiMap) map)._meta;
052
053 if (meta != null)
054 {
055 meta().putAll(meta);
056 }
057 }
058 }
059
060 @Override public String putComment(K key, String comment)
061 {
062 return (String) putMeta(META_COMMENT, key, comment);
063 }
064
065 @Override public V remove(Object key)
066 {
067 V ret = super.remove(key);
068
069 removeMeta(key);
070
071 return ret;
072 }
073
074 @Override public V remove(Object key, int index)
075 {
076 V ret = super.remove(key, index);
077
078 if (length(key) == 0)
079 {
080 removeMeta(key);
081 }
082
083 return ret;
084 }
085
086 @Override public String removeComment(Object key)
087 {
088 return (String) removeMeta(META_COMMENT, key);
089 }
090
091 Object getMeta(String category, Object key)
092 {
093 return (_meta == null) ? null : _meta.get(makeKey(category, key));
094 }
095
096 Object putMeta(String category, K key, Object value)
097 {
098 return meta().put(makeKey(category, key), value);
099 }
100
101 void removeMeta(Object key)
102 {
103 if (_meta != null)
104 {
105 _meta.subMap(makeKey(FIRST_CATEGORY, key), makeKey(LAST_CATEGORY, key)).clear();
106 }
107 }
108
109 Object removeMeta(String category, Object key)
110 {
111 return (_meta == null) ? null : _meta.remove(makeKey(category, key));
112 }
113
114 private String makeKey(String category, Object key)
115 {
116 StringBuilder buff = new StringBuilder();
117
118 buff.append(String.valueOf(key));
119 buff.append(SEPARATOR);
120 buff.append(category);
121
122 return buff.toString();
123 }
124
125 private Map<String, Object> meta()
126 {
127 if (_meta == null)
128 {
129 _meta = new TreeMap<String, Object>();
130 }
131
132 return _meta;
133 }
134 }