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