1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.jetspeed.om.page.impl;
18
19 import java.util.AbstractMap;
20 import java.util.AbstractSet;
21 import java.util.Collection;
22 import java.util.Iterator;
23 import java.util.Map;
24 import java.util.Set;
25
26 import org.apache.jetspeed.page.impl.DatabasePageManagerUtils;
27
28 /***
29 * FragmentPropertyMap
30 *
31 * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
32 * @version $Id$
33 */
34 class FragmentPropertyMap extends AbstractMap
35 {
36 private FragmentImpl fragment;
37 private FragmentPropertiesEntrySet entrySet;
38
39 FragmentPropertyMap(FragmentImpl fragment)
40 {
41 super();
42 this.fragment = fragment;
43 // populate fragment properties using property members
44 entrySet = new FragmentPropertiesEntrySet();
45 Iterator keyIter = fragment.getPropertyMemberKeys().iterator();
46 while (keyIter.hasNext())
47 {
48 String key = (String)keyIter.next();
49 entrySet.add(new FragmentPropertiesEntry(key, fragment.getPropertyMember(key)));
50 }
51 }
52
53 /* (non-Javadoc)
54 * @see java.util.Map#put(java.lang.Object, java.lang.Object)
55 */
56 public Object put(Object key, Object value)
57 {
58 // implement for modifiable AbstractMap:
59 // set map entry value or add new map entry
60 // using iterator to find key entry
61 FragmentPropertiesEntry entry = new FragmentPropertiesEntry(key, value);
62 Iterator entryIter = entrySet.iterator();
63 while (entryIter.hasNext())
64 {
65 FragmentPropertiesEntry testEntry = (FragmentPropertiesEntry) entryIter.next();
66 if (testEntry.equals(entry))
67 {
68 Object oldValue = testEntry.getValue();
69 testEntry.setValue(entry.getValue());
70 return oldValue;
71 }
72 }
73 entrySet.add(entry);
74 return null;
75 }
76
77 /* (non-Javadoc)
78 * @see java.util.Map#entrySet()
79 */
80 public Set entrySet()
81 {
82 // implement for modifiable AbstractMap
83 return entrySet;
84 }
85
86 private class FragmentPropertiesEntrySet extends AbstractSet
87 {
88 private Collection entries = DatabasePageManagerUtils.createCollection();
89
90 /* (non-Javadoc)
91 * @see java.util.Set#add(java.lang.Object)
92 */
93 public boolean add(Object o)
94 {
95 // implement for modifiable AbstractSet:
96 FragmentPropertiesEntry entry = (FragmentPropertiesEntry)o;
97 if (!entries.contains(entry))
98 {
99 // set fragment explicit property member
100 fragment.setPropertyMember(entry.getKey().toString(), entry.getValue().toString());
101 // add entry to set
102 entries.add(o);
103 return true;
104 }
105 return false;
106 }
107
108 /* (non-Javadoc)
109 * @see java.util.Set#iterator()
110 */
111 public Iterator iterator()
112 {
113 // implement for modifiable AbstractSet:
114 return new Iterator()
115 {
116 private Iterator iter = entries.iterator();
117 private FragmentPropertiesEntry last;
118
119 /* (non-Javadoc)
120 * @see java.util.Iterator#hasNext()
121 */
122 public boolean hasNext()
123 {
124 // implement for modifiable AbstractSet:
125 return iter.hasNext();
126 }
127
128 /* (non-Javadoc)
129 * @see java.util.Iterator#next()
130 */
131 public Object next()
132 {
133 // implement for modifiable AbstractSet:
134 last = (FragmentPropertiesEntry)iter.next();
135 return last;
136 }
137
138 /* (non-Javadoc)
139 * @see java.util.Iterator#remove()
140 */
141 public void remove()
142 {
143 // implement for modifiable AbstractSet:
144 // clear fragment explicit property associated with entry
145 if (last == null)
146 {
147 throw new IllegalStateException("No preceding call to next() or remove() already invoked");
148 }
149 FragmentPropertyMap.this.fragment.clearPropertyMember(last.getKey().toString());
150 last = null;
151 // remove entry using iterator
152 iter.remove();
153 }
154 };
155 }
156
157 /* (non-Javadoc)
158 * @see java.util.Set#size()
159 */
160 public int size()
161 {
162 // implement for modifiable AbstractSet:
163 return entries.size();
164 }
165 }
166
167 private class FragmentPropertiesEntry implements Map.Entry
168 {
169 private Object key;
170 private Object value;
171
172 public FragmentPropertiesEntry(Object key, Object value)
173 {
174 this.key = key;
175 this.value = value;
176 }
177
178 /* (non-Javadoc)
179 * @see java.util.Map.Entry#getKey()
180 */
181 public Object getKey()
182 {
183 return key;
184 }
185
186 /* (non-Javadoc)
187 * @see java.util.Map.Entry#getValue()
188 */
189 public Object getValue()
190 {
191 return value;
192 }
193
194 /* (non-Javadoc)
195 * @see java.util.Map.Entry#setValue(java.lang.Object)
196 */
197 public Object setValue(Object newValue)
198 {
199 // set fragment explicit property associated with entry
200 FragmentPropertyMap.this.fragment.setPropertyMember(key.toString(), newValue.toString());
201 // set entry value
202 Object oldValue = value;
203 value = newValue;
204 return oldValue;
205 }
206
207 /* (non-Javadoc)
208 * @see java.lang.Object#equals(java.lang.Object)
209 */
210 public boolean equals(Object o)
211 {
212 if (o instanceof FragmentPropertiesEntry)
213 {
214 if (key != null)
215 {
216 return key.equals(((FragmentPropertiesEntry)o).getKey());
217 }
218 return (((FragmentPropertiesEntry)o).getKey() == null);
219 }
220 return false;
221 }
222
223 /* (non-Javadoc)
224 * @see java.lang.Object#hashCode()
225 */
226 public int hashCode()
227 {
228 if (key != null)
229 {
230 return key.hashCode();
231 }
232 return 0;
233 }
234 }
235 }