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