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 */
017package org.apache.camel.model.dataformat;
018
019import java.util.ArrayList;
020import java.util.Arrays;
021import java.util.HashMap;
022import java.util.List;
023import java.util.Map;
024import java.util.Map.Entry;
025
026import javax.xml.bind.annotation.XmlAccessType;
027import javax.xml.bind.annotation.XmlAccessorType;
028import javax.xml.bind.annotation.XmlAttribute;
029import javax.xml.bind.annotation.XmlElement;
030import javax.xml.bind.annotation.XmlRootElement;
031import javax.xml.bind.annotation.XmlTransient;
032import javax.xml.bind.annotation.XmlType;
033import javax.xml.bind.annotation.adapters.XmlAdapter;
034import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
035
036import org.apache.camel.CamelContext;
037import org.apache.camel.model.DataFormatDefinition;
038import org.apache.camel.spi.DataFormat;
039import org.apache.camel.spi.RouteContext;
040import org.apache.camel.util.CamelContextHelper;
041import org.apache.camel.util.ObjectHelper;
042
043/**
044 * Represents the XStream XML {@link org.apache.camel.spi.DataFormat}
045 *
046 * @version 
047 */
048@XmlRootElement(name = "xstream")
049@XmlAccessorType(XmlAccessType.NONE)
050public class XStreamDataFormat extends DataFormatDefinition {
051    @XmlAttribute
052    private String encoding;
053    @XmlAttribute
054    private String driver;
055    @XmlAttribute
056    private String driverRef;
057    @XmlAttribute
058    private String mode;
059    
060    @XmlJavaTypeAdapter(ConvertersAdapter.class)
061    @XmlElement(name = "converters")
062    private List<String> converters;
063    @XmlJavaTypeAdapter(AliasAdapter.class)
064    @XmlElement(name = "aliases")
065    private Map<String, String> aliases;
066    @XmlJavaTypeAdapter(OmitFieldsAdapter.class)
067    @XmlElement(name = "omitFields")
068    private Map<String, String[]> omitFields;
069    @XmlJavaTypeAdapter(ImplicitCollectionsAdapter.class)
070    @XmlElement(name = "implicitCollections")
071    private Map<String, String[]> implicitCollections;
072    
073
074    public XStreamDataFormat() {
075        super("xstream");
076    }
077    
078    public XStreamDataFormat(String encoding) {
079        this();
080        setEncoding(encoding);
081    }
082    
083    public String getEncoding() {
084        return encoding;
085    }
086    
087    public void setEncoding(String encoding) {
088        this.encoding = encoding;
089    }
090
091    public String getDriver() {
092        return driver;
093    }
094
095    public void setDriver(String driver) {
096        this.driver = driver;
097    }
098
099    public String getDriverRef() {
100        return driverRef;
101    }
102
103    public void setDriverRef(String driverRef) {
104        this.driverRef = driverRef;
105    }
106    
107    public String getMode() {
108        return mode;
109    }
110
111    public void setMode(String mode) {
112        this.mode = mode;
113    }
114
115    public List<String> getConverters() {
116        return converters;
117    }
118
119    public void setConverters(List<String> converters) {
120        this.converters = converters;
121    }
122
123    public Map<String, String> getAliases() {
124        return aliases;
125    }
126
127    public void setAliases(Map<String, String> aliases) {
128        this.aliases = aliases;
129    }
130
131    public Map<String, String[]> getOmitFields() {
132        return omitFields;
133    }
134
135    public void setOmitFields(Map<String, String[]> omitFields) {
136        this.omitFields = omitFields;
137    }
138
139    public Map<String, String[]> getImplicitCollections() {
140        return implicitCollections;
141    }
142
143    public void setImplicitCollections(Map<String, String[]> implicitCollections) {
144        this.implicitCollections = implicitCollections;
145    }
146
147    @Override
148    protected DataFormat createDataFormat(RouteContext routeContext) {
149        if ("json".equals(this.driver)) {
150            setProperty(routeContext.getCamelContext(), this, "dataFormatName", "json-xstream");
151        }
152        DataFormat answer = super.createDataFormat(routeContext);
153        // need to lookup the reference for the xstreamDriver
154        if (ObjectHelper.isNotEmpty(driverRef)) {
155            setProperty(routeContext.getCamelContext(), answer, "xstreamDriver", CamelContextHelper.mandatoryLookup(routeContext.getCamelContext(), driverRef));
156        }
157        return answer;
158    }
159
160    @Override
161    protected void configureDataFormat(DataFormat dataFormat, CamelContext camelContext) {
162        if (encoding != null) {
163            setProperty(camelContext, dataFormat, "encoding", encoding);
164        }
165        if (this.converters != null) {
166            setProperty(camelContext, dataFormat, "converters", this.converters);
167        }
168        if (this.aliases != null) {
169            setProperty(camelContext, dataFormat, "aliases", this.aliases);
170        }
171        if (this.omitFields != null) {
172            setProperty(camelContext, dataFormat, "omitFields", this.omitFields);
173        }
174        if (this.implicitCollections != null) {
175            setProperty(camelContext, dataFormat, "implicitCollections", this.implicitCollections);
176        }
177        if (this.mode != null) {
178            setProperty(camelContext, dataFormat, "mode", mode);
179        }
180    }
181    
182    
183
184    @XmlTransient
185    public static class ConvertersAdapter extends XmlAdapter<ConverterList, List<String>> {
186        @Override
187        public ConverterList marshal(List<String> v) throws Exception {
188            if (v == null) {
189                return null;
190            }
191
192            List<ConverterEntry> list = new ArrayList<ConverterEntry>();
193            for (String str : v) {
194                ConverterEntry entry = new ConverterEntry();
195                entry.setClsName(str);
196                list.add(entry);
197            }
198            ConverterList converterList = new ConverterList();
199            converterList.setList(list);
200            return converterList;
201        }
202
203        @Override
204        public List<String> unmarshal(ConverterList v) throws Exception {
205            if (v == null) {
206                return null;
207            }
208
209            List<String> list = new ArrayList<String>();
210            for (ConverterEntry entry : v.getList()) {
211                list.add(entry.getClsName());
212            }
213            return list;
214        }
215    }
216
217    @XmlAccessorType(XmlAccessType.NONE)
218    @XmlType(name = "converterList", namespace = "http://camel.apache.org/schema/spring")
219    public static class ConverterList {
220        @XmlElement(name = "converter", namespace = "http://camel.apache.org/schema/spring")
221        private List<ConverterEntry> list;
222
223        public List<ConverterEntry> getList() {
224            return list;
225        }
226
227        public void setList(List<ConverterEntry> list) {
228            this.list = list;
229        }
230    }
231
232    @XmlAccessorType(XmlAccessType.NONE)
233    @XmlType(name = "converterEntry", namespace = "http://camel.apache.org/schema/spring")
234    public static class ConverterEntry {
235        @XmlAttribute(name = "class")
236        private String clsName;
237
238        public String getClsName() {
239            return clsName;
240        }
241
242        public void setClsName(String clsName) {
243            this.clsName = clsName;
244        }
245    }
246
247    @XmlTransient
248    public static class ImplicitCollectionsAdapter 
249            extends XmlAdapter<ImplicitCollectionList, Map<String, String[]>> {
250
251        @Override
252        public ImplicitCollectionList marshal(Map<String, String[]> v) throws Exception {
253            if (v == null || v.isEmpty()) {
254                return null;
255            }
256
257            List<ImplicitCollectionEntry> list = new ArrayList<ImplicitCollectionEntry>();
258            for (Entry<String, String[]> e : v.entrySet()) {
259                ImplicitCollectionEntry entry = new ImplicitCollectionEntry(e.getKey(), e.getValue());
260                list.add(entry);
261            }
262
263            ImplicitCollectionList collectionList = new ImplicitCollectionList();
264            collectionList.setList(list);
265
266            return collectionList;
267        }
268
269        @Override
270        public Map<String, String[]> unmarshal(ImplicitCollectionList v) throws Exception {
271            if (v == null) {
272                return null;
273            }
274
275            Map<String, String[]> map = new HashMap<String, String[]>();
276            for (ImplicitCollectionEntry entry : v.getList()) {
277                map.put(entry.getClsName(), entry.getFields());
278            }
279            return map;
280        }
281    }
282
283    @XmlAccessorType(XmlAccessType.NONE)
284    @XmlType(name = "implicitCollectionList", namespace = "http://camel.apache.org/schema/spring")
285    public static class ImplicitCollectionList {
286        @XmlElement(name = "class", namespace = "http://camel.apache.org/schema/spring")
287        private List<ImplicitCollectionEntry> list;
288
289        public List<ImplicitCollectionEntry> getList() {
290            return list;
291        }
292
293        public void setList(List<ImplicitCollectionEntry> list) {
294            this.list = list;
295        }
296    }
297
298    @XmlAccessorType(XmlAccessType.NONE)
299    @XmlType(name = "implicitCollectionEntry", namespace = "http://camel.apache.org/schema/spring")
300    public static class ImplicitCollectionEntry {
301        @XmlAttribute(name = "name")
302        private String clsName;
303
304        @XmlElement(name = "field", namespace = "http://camel.apache.org/schema/spring")
305        private String[] fields;
306
307        public ImplicitCollectionEntry() {
308        }
309
310        public ImplicitCollectionEntry(String clsName, String[] fields) {
311            this.clsName = clsName;
312            this.fields = fields;
313        }
314
315        public String getClsName() {
316            return clsName;
317        }
318
319        public void setClsName(String clsName) {
320            this.clsName = clsName;
321        }
322
323        public String[] getFields() {
324            return fields;
325        }
326
327        public void setFields(String[] fields) {
328            this.fields = fields;
329        }
330
331        @Override
332        public String toString() {
333            return "Alias[ImplicitCollection=" + clsName + ", fields=" + Arrays.asList(this.fields) + "]";
334        }
335    }
336
337    @XmlTransient
338    public static class AliasAdapter extends XmlAdapter<AliasList, Map<String, String>> {
339
340        @Override
341        public AliasList marshal(Map<String, String> value) throws Exception {
342            if (value == null || value.isEmpty()) {
343                return null;
344            }
345
346            List<AliasEntry> ret = new ArrayList<AliasEntry>(value.size());
347            for (Map.Entry<String, String> entry : value.entrySet()) {
348                ret.add(new AliasEntry(entry.getKey(), entry.getValue()));
349            }
350            AliasList jaxbMap = new AliasList();
351            jaxbMap.setList(ret);
352            return jaxbMap;
353        }
354
355        @Override
356        public Map<String, String> unmarshal(AliasList value) throws Exception {
357            if (value == null || value.getList() == null || value.getList().isEmpty()) {
358                return null;
359            }
360
361            Map<String, String> answer = new HashMap<String, String>();
362            for (AliasEntry alias : value.getList()) {
363                answer.put(alias.getName(), alias.getClsName());
364            }
365            return answer;
366        }
367    }
368
369    @XmlAccessorType(XmlAccessType.NONE)
370    @XmlType(name = "aliasList", namespace = "http://camel.apache.org/schema/spring")
371    public static class AliasList {
372        @XmlElement(name = "alias", namespace = "http://camel.apache.org/schema/spring")
373        private List<AliasEntry> list;
374
375        public List<AliasEntry> getList() {
376            return list;
377        }
378
379        public void setList(List<AliasEntry> list) {
380            this.list = list;
381        }
382    }
383
384    @XmlAccessorType(XmlAccessType.NONE)
385    @XmlType(name = "aliasEntry", namespace = "http://camel.apache.org/schema/spring")
386    public static class AliasEntry {
387
388        @XmlAttribute
389        private String name;
390
391        @XmlAttribute(name = "class")
392        private String clsName;
393
394        public AliasEntry() {
395        }
396
397        public AliasEntry(String key, String clsName) {
398            this.name = key;
399            this.clsName = clsName;
400        }
401
402        public String getName() {
403            return name;
404        }
405
406        public void setName(String name) {
407            this.name = name;
408        }
409
410        public String getClsName() {
411            return clsName;
412        }
413
414        public void setClsName(String clsName) {
415            this.clsName = clsName;
416        }
417
418        @Override
419        public String toString() {
420            return "Alias[name=" + name + ", class=" + clsName + "]";
421        }
422    }
423
424    @XmlTransient
425    public static class OmitFieldsAdapter
426            extends XmlAdapter<OmitFieldList, Map<String, String[]>> {
427
428        @Override
429        public OmitFieldList marshal(Map<String, String[]> v) throws Exception {
430            if (v == null || v.isEmpty()) {
431                return null;
432            }
433
434            List<OmitFieldEntry> list = new ArrayList<OmitFieldEntry>();
435            for (Entry<String, String[]> e : v.entrySet()) {
436                OmitFieldEntry entry = new OmitFieldEntry(e.getKey(), e.getValue());
437                list.add(entry);
438            }
439
440            OmitFieldList collectionList = new OmitFieldList();
441            collectionList.setList(list);
442
443            return collectionList;
444        }
445
446        @Override
447        public Map<String, String[]> unmarshal(OmitFieldList v) throws Exception {
448            if (v == null || v.getList() == null || v.getList().isEmpty()) {
449                return null;
450            }
451
452            Map<String, String[]> map = new HashMap<String, String[]>();
453            for (OmitFieldEntry entry : v.getList()) {
454                map.put(entry.getClsName(), entry.getFields());
455            }
456            return map;
457        }
458    }
459
460    @XmlAccessorType(XmlAccessType.NONE)
461    @XmlType(name = "omitFieldList", namespace = "http://camel.apache.org/schema/spring")
462    public static class OmitFieldList {
463        @XmlElement(name = "omitField", namespace = "http://camel.apache.org/schema/spring")
464        private List<OmitFieldEntry> list;
465
466        public List<OmitFieldEntry> getList() {
467            return list;
468        }
469
470        public void setList(List<OmitFieldEntry> list) {
471            this.list = list;
472        }
473    }
474
475    @XmlAccessorType(XmlAccessType.NONE)
476    @XmlType(name = "omitFieldEntry", namespace = "http://camel.apache.org/schema/spring")
477    public static class OmitFieldEntry {
478
479        @XmlAttribute(name = "class")
480        private String clsName;
481
482        @XmlElement(name = "field", namespace = "http://camel.apache.org/schema/spring")
483        private String[] fields;
484
485        public OmitFieldEntry() {
486        }
487
488        public OmitFieldEntry(String clsName, String[] fields) {
489            this.clsName = clsName;
490            this.fields = fields;
491        }
492
493        public String getClsName() {
494            return clsName;
495        }
496
497        public void setClsName(String clsName) {
498            this.clsName = clsName;
499        }
500
501        public String[] getFields() {
502            return fields;
503        }
504
505        public void setFields(String[] fields) {
506            this.fields = fields;
507        }
508
509        @Override
510        public String toString() {
511            return "OmitField[" + clsName + ", fields=" + Arrays.asList(this.fields) + "]";
512        }
513    }
514
515}