001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.camel.model.dataformat;
018
019 import java.util.ArrayList;
020 import java.util.Arrays;
021 import java.util.HashMap;
022 import java.util.List;
023 import java.util.Map;
024
025 import javax.xml.bind.annotation.XmlAccessType;
026 import javax.xml.bind.annotation.XmlAccessorType;
027 import javax.xml.bind.annotation.XmlAttribute;
028 import javax.xml.bind.annotation.XmlElement;
029 import javax.xml.bind.annotation.XmlRootElement;
030 import javax.xml.bind.annotation.XmlTransient;
031 import javax.xml.bind.annotation.adapters.XmlAdapter;
032 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
033
034 import org.apache.camel.model.DataFormatDefinition;
035 import org.apache.camel.spi.DataFormat;
036 import org.apache.camel.spi.RouteContext;
037
038 /**
039 * Represents the XStream XML {@link org.apache.camel.spi.DataFormat}
040 *
041 * @version $Revision: 20332 $
042 */
043 @XmlRootElement(name = "xstream")
044 @XmlAccessorType(XmlAccessType.NONE)
045 public class XStreamDataFormat extends DataFormatDefinition {
046 @XmlAttribute
047 private String encoding;
048
049 @XmlAttribute
050 private String driver = "xml";
051
052 @XmlJavaTypeAdapter(ConvertersAdapter.class)
053 @XmlElement(name = "converters")
054 private List<String> converters;
055
056 @XmlJavaTypeAdapter(AliasAdapter.class)
057 @XmlElement(name = "aliases")
058 private Map<String, String> aliases;
059
060 @XmlJavaTypeAdapter(ImplicitCollectionsAdapter.class)
061 @XmlElement(name = "implicitCollections")
062 private Map<String, String[]> implicitCollections;
063
064
065 public XStreamDataFormat() {
066 super("xstream");
067 }
068
069 public XStreamDataFormat(String encoding) {
070 this();
071 setEncoding(encoding);
072 }
073
074 public String getEncoding() {
075 return encoding;
076 }
077
078 public void setEncoding(String encoding) {
079 this.encoding = encoding;
080 }
081
082 public String getDriver() {
083 return driver;
084 }
085
086 public void setDriver(String driver) {
087 this.driver = driver;
088 }
089
090 public List<String> getConverters() {
091 return converters;
092 }
093
094 public void setConverters(List<String> converters) {
095 this.converters = converters;
096 }
097
098 public Map<String, String> getAliases() {
099 return aliases;
100 }
101
102 public void setAliases(Map<String, String> aliases) {
103 this.aliases = aliases;
104 }
105
106 public Map<String, String[]> getImplicitCollections() {
107 return implicitCollections;
108 }
109
110 public void setImplicitCollections(Map<String, String[]> implicitCollections) {
111 this.implicitCollections = implicitCollections;
112 }
113
114 @Override
115 protected DataFormat createDataFormat(RouteContext routeContext) {
116 if ("json".equals(this.driver)) {
117 setProperty(this, "dataFormatName", "json-xstream");
118 }
119 return super.createDataFormat(routeContext);
120 }
121
122 @Override
123 protected void configureDataFormat(DataFormat dataFormat) {
124 if (encoding != null) {
125 setProperty(dataFormat, "encoding", encoding);
126 }
127
128 if (this.converters != null) {
129 setProperty(dataFormat, "converters", this.converters);
130 }
131
132 if (this.aliases != null) {
133 setProperty(dataFormat, "aliases", this.aliases);
134 }
135
136 if (this.implicitCollections != null) {
137 setProperty(dataFormat, "implicitCollections", this.implicitCollections);
138 }
139 }
140
141
142 @XmlTransient
143 public static class ConvertersAdapter extends XmlAdapter<ConverterList, List<String>> {
144 @Override
145 public ConverterList marshal(List<String> v) throws Exception {
146 List<ConverterEntry> list = new ArrayList<ConverterEntry>();
147 for (String str : v) {
148 ConverterEntry entry = new ConverterEntry();
149 entry.setClsName(str);
150 list.add(entry);
151 }
152
153 ConverterList converterList = new ConverterList();
154 converterList.setList(list);
155 return converterList;
156 }
157
158 @Override
159 public List<String> unmarshal(ConverterList v) throws Exception {
160 List<String> list = new ArrayList<String>();
161 for (ConverterEntry entry : v.getList()) {
162 list.add(entry.getClsName());
163 }
164 return list;
165 }
166 }
167
168 @XmlAccessorType(XmlAccessType.NONE)
169 public static class ConverterList {
170 @XmlElement(name = "converter")
171 private List<ConverterEntry> list = new ArrayList<ConverterEntry>();
172
173 public List<ConverterEntry> getList() {
174 return list;
175 }
176
177 public void setList(List<ConverterEntry> list) {
178 this.list = list;
179 }
180 }
181
182 @XmlAccessorType(XmlAccessType.NONE)
183 public static class ConverterEntry {
184 @XmlAttribute(name = "class")
185 private String clsName;
186
187 public String getClsName() {
188 return clsName;
189 }
190
191 public void setClsName(String clsName) {
192 this.clsName = clsName;
193 }
194
195 }
196
197 @XmlTransient
198 public static class ImplicitCollectionsAdapter
199 extends XmlAdapter<ImplicitCollectionList, Map<String, String[]>> {
200
201 @Override
202 public ImplicitCollectionList marshal(Map<String, String[]> v) throws Exception {
203 List<ImplicitCollectionEntry> list = new ArrayList<ImplicitCollectionEntry>();
204 for (String clsName : v.keySet()) {
205 ImplicitCollectionEntry entry = new ImplicitCollectionEntry(
206 clsName, v.get(clsName));
207 list.add(entry);
208 }
209
210 ImplicitCollectionList collectionList = new ImplicitCollectionList();
211 collectionList.setList(list);
212
213 return collectionList;
214 }
215
216 @Override
217 public Map<String, String[]> unmarshal(ImplicitCollectionList v) throws Exception {
218 Map<String, String[]> map = new HashMap<String, String[]>();
219 for (ImplicitCollectionEntry entry : v.getList()) {
220 map.put(entry.getClsName(), entry.getFields());
221 }
222 return map;
223 }
224 }
225
226 @XmlAccessorType(XmlAccessType.NONE)
227 public static class ImplicitCollectionList {
228 @XmlElement(name = "class")
229 private List<ImplicitCollectionEntry> list = new ArrayList<ImplicitCollectionEntry>();
230
231 public List<ImplicitCollectionEntry> getList() {
232 return list;
233 }
234
235 public void setList(List<ImplicitCollectionEntry> list) {
236 this.list = list;
237 }
238 }
239
240 @XmlAccessorType(XmlAccessType.NONE)
241 public static class ImplicitCollectionEntry {
242 @XmlAttribute(name = "name")
243 private String clsName;
244
245 @XmlElement(name = "field")
246 private String[] fields;
247
248 public ImplicitCollectionEntry() {
249 }
250
251 public ImplicitCollectionEntry(String clsName, String[] fields) {
252 this.clsName = clsName;
253 this.fields = fields;
254 }
255
256 public String getClsName() {
257 return clsName;
258 }
259
260 public void setClsName(String clsName) {
261 this.clsName = clsName;
262 }
263
264 public String[] getFields() {
265 return fields;
266 }
267
268 public void setFields(String[] fields) {
269 this.fields = fields;
270 }
271
272 @Override
273 public String toString() {
274 return "Alias [ImplicitCollection=" + clsName + ", fields=" + Arrays.asList(this.fields) + "]";
275 }
276 }
277
278 @XmlTransient
279 public static class AliasAdapter extends XmlAdapter<AliasList, Map<String, String>> {
280
281 @Override
282 public AliasList marshal(Map<String, String> value) throws Exception {
283 if (value == null || value.isEmpty()) {
284 return new AliasList();
285 }
286
287 List<AliasEntry> ret = new ArrayList<AliasEntry>(value.size());
288 for (Map.Entry<String, String> entry : value.entrySet()) {
289 ret.add(new AliasEntry(entry.getKey(), entry.getValue()));
290 }
291 AliasList jaxbMap = new AliasList();
292 jaxbMap.setList(ret);
293 return jaxbMap; // ret.toArray( new JaxbMapEntry[ret.size()] );
294 }
295
296 @Override
297 public Map<String, String> unmarshal(AliasList value) throws Exception {
298 Map<String, String> answer = new HashMap<String, String>();
299 for (AliasEntry alias : value.getList()) {
300 answer.put(alias.getName(), alias.getClsName());
301 }
302 return answer;
303 }
304
305 }
306
307 @XmlAccessorType(XmlAccessType.NONE)
308 public static class AliasList {
309 @XmlElement(name = "alias")
310 private List<AliasEntry> list = new ArrayList<AliasEntry>();
311
312 public List<AliasEntry> getList() {
313 return list;
314 }
315
316 public void setList(List<AliasEntry> list) {
317 this.list = list;
318 }
319 }
320
321 @XmlAccessorType(XmlAccessType.NONE)
322 public static class AliasEntry {
323
324 @XmlAttribute
325 private String name;
326
327 @XmlAttribute(name = "class")
328 private String clsName;
329
330 public AliasEntry() {
331 }
332
333 public AliasEntry(String key, String clsName) {
334 this.name = key;
335 this.clsName = clsName;
336 }
337
338 public String getName() {
339 return name;
340 }
341
342 public void setName(String name) {
343 this.name = name;
344 }
345
346 public String getClsName() {
347 return clsName;
348 }
349
350 public void setClsName(String clsName) {
351 this.clsName = clsName;
352 }
353
354 @Override
355 public String toString() {
356 return "Alias [name=" + name + ", class=" + clsName + "]";
357 }
358 }
359 }