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.CamelContext;
037    import org.apache.camel.model.DataFormatDefinition;
038    import org.apache.camel.spi.DataFormat;
039    import org.apache.camel.spi.RouteContext;
040    import org.apache.camel.util.CamelContextHelper;
041    import 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)
050    public 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    }