1 package com.trendmicro.grid.acl.metadata;
2
3 import com.trendmicro.grid.acl.commons.XmlSerializer;
4 import com.trendmicro.grid.acl.commons.collections.AbstractMapValueCollection;
5
6 import javax.xml.bind.annotation.*;
7 import java.io.*;
8 import java.util.Collection;
9 import java.util.List;
10 import java.util.Map;
11
12
13
14
15
16
17
18 @XmlAccessorType(XmlAccessType.PROPERTY)
19 @XmlType(name = "metadata", namespace = Metadata.NS)
20 @XmlRootElement(name = "metadata", namespace = Metadata.NS)
21 public class Metadata implements Cloneable, Externalizable {
22
23 private static class MetaCollectionMapAdapter extends AbstractMapValueCollection<String, Meta> {
24 private MetaCollectionMapAdapter(Map<String, Meta> wrappedMap) {
25 super(wrappedMap);
26 }
27
28 protected String createKeyForValue(Meta value) {
29 return value.getName();
30 }
31 }
32
33 private static final long serialVersionUID = 8942843714209700817L;
34 private static final byte serialVersion = 1;
35
36 public static final String NS = "http://grid.trendmicro.com/metadata/1.0";
37 public static final String DEFAULT_SCHEMA_BASENAME = "metadata-schema";
38
39 private static XmlSerializer<Metadata> xmlSerializer =
40 new XmlSerializer<Metadata>(Metadata.class, NS, DEFAULT_SCHEMA_BASENAME);
41
42 public static XmlSerializer<Metadata> getXmlSerializer() {
43 return xmlSerializer;
44 }
45
46 public static List<File> generateSchema(final File outputDirectory, final String basename) throws Exception {
47 return xmlSerializer.generateSchema(outputDirectory, basename);
48 }
49
50 public static Metadata load(File file) throws Exception {
51 return xmlSerializer.load(file);
52 }
53
54 public static Metadata load(InputStream in) throws Exception {
55 return xmlSerializer.load(in);
56 }
57
58 public void save(File file) throws Exception {
59 xmlSerializer.save(this, file);
60 }
61
62 public void save(OutputStream out) throws Exception {
63 xmlSerializer.save(this, out);
64 }
65
66 ValidatedMetaMap metaElements;
67 final transient Collection<Meta> valueCollection;
68
69
70
71
72 public Metadata() {
73 metaElements = new ValidatedMetaMap();
74 valueCollection = new MetaCollectionMapAdapter(metaElements);
75 }
76
77
78
79
80
81
82 @SuppressWarnings("unchecked")
83 public Metadata(Metadata other) {
84 metaElements = other.metaElements.clone();
85 for (Map.Entry<String, Meta> entry : metaElements.entrySet())
86 entry.setValue(entry.getValue().clone());
87 valueCollection = new MetaCollectionMapAdapter(metaElements);
88 }
89
90
91
92
93
94
95 public Metadata(Collection<Meta> metaElements) {
96 this();
97 setMetaElements(metaElements);
98 }
99
100
101
102
103
104
105 @XmlElement(name = "meta", namespace = NS)
106 public Collection<Meta> getMetaElements() {
107 return valueCollection;
108 }
109
110 public void setMetaElements(Collection<Meta> metaElements) {
111 if (metaElements != valueCollection) {
112 this.metaElements.clear();
113
114 if (metaElements != null)
115 for (Meta meta : metaElements)
116 this.metaElements.put(meta.getName(), meta);
117 }
118 }
119
120
121
122
123 public void assertValuesAreValidForWrite() {
124 metaElements.assertValuesAreValidForWrite();
125 }
126
127
128
129
130
131
132 public Map<String, Meta> getAll() {
133 return metaElements;
134 }
135
136
137
138
139
140
141
142 public Meta add(String name) {
143 Meta p = new Meta(name);
144 metaElements.put(name, p);
145 return p;
146 }
147
148
149
150
151
152
153
154 public Meta get(final String name) {
155 return get(name, null);
156 }
157
158
159
160
161
162
163
164
165 public Meta get(final String name, final Meta defaultValue) {
166 Meta meta = metaElements.get(name);
167 return meta != null ? meta : defaultValue;
168 }
169
170
171
172
173
174
175
176 public Meta addOrGet(final String name) {
177 Meta meta = get(name);
178 return meta != null ? meta : add(name);
179 }
180
181
182
183
184
185
186
187 public Meta remove(final String name) {
188 return metaElements.remove(name);
189 }
190
191
192
193
194 @Override
195 public String toString() {
196 return "Metadata{" +
197 "metaElements=" + valueCollection +
198 '}';
199 }
200
201
202
203
204 @Override
205 public Metadata clone() {
206 return new Metadata(this);
207 }
208
209
210
211
212 @Override
213 public boolean equals(Object o) {
214 if (this == o) return true;
215 if (!(o instanceof Metadata)) return false;
216 Metadata metadata = (Metadata) o;
217 if (valueCollection.size() == metadata.valueCollection.size()) {
218
219 return valueCollection.equals(metadata.valueCollection) ||
220 metaElements.equals(metadata.metaElements);
221 } else
222 return false;
223 }
224
225
226
227
228 @Override
229 public int hashCode() {
230 return metaElements.hashCode();
231 }
232
233
234
235
236 @Override
237 public void writeExternal(ObjectOutput out) throws IOException {
238 out.writeByte(serialVersion);
239
240 final Collection<Meta> metaCollection = metaElements.valuesWithoutValidation();
241 out.writeInt(metaCollection.size());
242 for (Meta meta : metaCollection)
243 meta.writeExternal(out);
244 }
245
246
247
248
249 @Override
250 public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
251 switch (in.readByte()) {
252 case 1:
253 if (!metaElements.isEmpty())
254 metaElements.clear();
255
256 for (int i = in.readInt(); i > 0; i--) {
257 Meta meta = new Meta();
258 meta.readExternal(in);
259 metaElements.putWithoutValidation(meta);
260 }
261 break;
262 default:
263 throw new IOException("Stream is corrupted or was written with a newer unsupported version.");
264 }
265 }
266 }