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;
018    
019    import javax.xml.bind.annotation.XmlAccessType;
020    import javax.xml.bind.annotation.XmlAccessorType;
021    import javax.xml.bind.annotation.XmlTransient;
022    import javax.xml.bind.annotation.XmlType;
023    
024    import org.apache.camel.CamelContext;
025    import org.apache.camel.spi.DataFormat;
026    import org.apache.camel.spi.RouteContext;
027    import org.apache.camel.util.IntrospectionSupport;
028    import org.apache.camel.util.ObjectHelper;
029    
030    import static org.apache.camel.util.EndpointHelper.isReferenceParameter;
031    
032    /**
033     * Represents the base XML type for DataFormat.
034     */
035    @XmlType(name = "dataFormat")
036    @XmlAccessorType(XmlAccessType.FIELD)
037    public class DataFormatDefinition extends IdentifiedType {
038        @XmlTransient
039        private DataFormat dataFormat;
040        @XmlTransient
041        private String dataFormatName;
042    
043        public DataFormatDefinition() {
044        }
045    
046        public DataFormatDefinition(DataFormat dataFormat) {
047            this.dataFormat = dataFormat;
048        }
049    
050        protected DataFormatDefinition(String dataFormatName) {
051            this.dataFormatName = dataFormatName;
052        }
053    
054        /**
055         * Factory method to create the data format
056         *
057         * @param routeContext route context
058         * @param type         the data format type
059         * @param ref          reference to lookup for a data format
060         * @return the data format or null if not possible to create
061         */
062        public static DataFormat getDataFormat(RouteContext routeContext, DataFormatDefinition type, String ref) {
063            if (type == null) {
064                ObjectHelper.notNull(ref, "ref or type");
065    
066                // try to let resolver see if it can resolve it, its not always possible
067                type = ((ModelCamelContext) routeContext.getCamelContext()).resolveDataFormatDefinition(ref);
068    
069                if (type != null) {
070                    return type.getDataFormat(routeContext);
071                }
072    
073                DataFormat dataFormat = routeContext.getCamelContext().resolveDataFormat(ref);
074                if (dataFormat == null) {
075                    throw new IllegalArgumentException("Cannot find data format in registry with ref: " + ref);
076                }
077    
078                return dataFormat;
079            } else {
080                return type.getDataFormat(routeContext);
081            }
082        }
083    
084        public DataFormat getDataFormat(RouteContext routeContext) {
085            if (dataFormat == null) {
086                dataFormat = createDataFormat(routeContext);
087                if (dataFormat != null) {
088                    configureDataFormat(dataFormat, routeContext.getCamelContext());
089                } else {
090                    throw new IllegalArgumentException(
091                            "Data format '" + (dataFormatName != null ? dataFormatName : "<null>") + "' could not be created. "
092                                    + "Ensure that the data format is valid and the associated Camel component is present on the classpath");
093                }
094            }
095            return dataFormat;
096        }
097    
098        /**
099         * Factory method to create the data format instance
100         */
101        protected DataFormat createDataFormat(RouteContext routeContext) {
102            if (dataFormatName != null) {
103                return routeContext.getCamelContext().resolveDataFormat(dataFormatName);
104            }
105            return null;
106        }
107    
108        /**
109         * Allows derived classes to customize the data format
110         *
111         * @deprecated use {@link #configureDataFormat(org.apache.camel.spi.DataFormat, org.apache.camel.CamelContext)}
112         */
113        @Deprecated
114        protected void configureDataFormat(DataFormat dataFormat) {
115        }
116    
117        /**
118         * Allows derived classes to customize the data format
119         */
120        protected void configureDataFormat(DataFormat dataFormat, CamelContext camelContext) {
121        }
122    
123        /**
124         * Sets a named property on the data format instance using introspection
125         *
126         * @deprecated use {@link #setProperty(org.apache.camel.CamelContext, Object, String, Object)}
127         */
128        @Deprecated
129        protected void setProperty(Object bean, String name, Object value) {
130            setProperty(null, bean, name, value);
131        }
132    
133        /**
134         * Sets a named property on the data format instance using introspection
135         */
136        protected void setProperty(CamelContext camelContext, Object bean, String name, Object value) {
137            try {
138                String ref = value instanceof String ? value.toString() : null;
139                if (isReferenceParameter(ref) && camelContext != null) {
140                    IntrospectionSupport.setProperty(camelContext, camelContext.getTypeConverter(), bean, name, null, ref, true);
141                } else {
142                    IntrospectionSupport.setProperty(bean, name, value);
143                }
144            } catch (Exception e) {
145                throw new IllegalArgumentException("Failed to set property: " + name + " on: " + bean + ". Reason: " + e, e);
146            }
147        }
148    
149        public String getDataFormatName() {
150            return dataFormatName;
151        }
152    
153        public void setDataFormatName(String dataFormatName) {
154            this.dataFormatName = dataFormatName;
155        }
156    
157        public DataFormat getDataFormat() {
158            return dataFormat;
159        }
160    
161        public void setDataFormat(DataFormat dataFormat) {
162            this.dataFormat = dataFormat;
163        }
164    
165        public String getShortName() {
166            String name = getClass().getSimpleName();
167            if (name.endsWith("DataFormat")) {
168                name = name.substring(0, name.indexOf("DataFormat"));
169            }
170            return name;
171        }
172    
173    }
174