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.io.InputStream;
020    import java.io.OutputStream;
021    
022    import javax.xml.bind.annotation.XmlAccessType;
023    import javax.xml.bind.annotation.XmlAccessorType;
024    import javax.xml.bind.annotation.XmlTransient;
025    import javax.xml.bind.annotation.XmlType;
026    
027    import org.apache.camel.Exchange;
028    import org.apache.camel.model.IdentifiedType;
029    import org.apache.camel.spi.DataFormat;
030    import org.apache.camel.spi.RouteContext;
031    import org.apache.camel.util.IntrospectionSupport;
032    import org.apache.camel.util.ObjectHelper;
033    import static org.apache.camel.util.ObjectHelper.notNull;
034    
035    /**
036     * Represents the base XML type for DataFormat.
037     *
038     * @version $Revision: 1239 $
039     */
040    @XmlType(name = "dataFormatType")
041    @XmlAccessorType(XmlAccessType.FIELD)
042    public class DataFormatType extends IdentifiedType implements DataFormat {
043        @XmlTransient
044        private DataFormat dataFormat;
045        @XmlTransient
046        private String dataFormatTypeName;
047    
048        public DataFormatType() {
049        }
050    
051        public DataFormatType(DataFormat dataFormat) {
052            this.dataFormat = dataFormat;
053        }
054    
055        protected DataFormatType(String dataFormatTypeName) {
056            this.dataFormatTypeName = dataFormatTypeName;
057        }
058    
059        public static DataFormat getDataFormat(RouteContext routeContext, DataFormatType type, String ref) {
060            if (type == null) {
061                notNull(ref, "ref or dataFormatType");
062                DataFormat dataFormat = routeContext.lookup(ref, DataFormat.class);
063                
064                if (dataFormat == null) {
065                    dataFormat = routeContext.getDataFormat(ref);
066                }
067                
068                if (dataFormat instanceof DataFormatType) {
069                    type = (DataFormatType)dataFormat;
070                } else {
071                    return dataFormat;
072                }
073            }
074            return type.getDataFormat(routeContext);
075        }
076    
077    
078        public void marshal(Exchange exchange, Object graph, OutputStream stream) throws Exception {
079            ObjectHelper.notNull(dataFormat, "dataFormat");
080            dataFormat.marshal(exchange, graph, stream);
081        }
082    
083        public Object unmarshal(Exchange exchange, InputStream stream) throws Exception {
084            ObjectHelper.notNull(dataFormat, "dataFormat");
085            return dataFormat.unmarshal(exchange, stream);
086        }
087    
088        public DataFormat getDataFormat(RouteContext routeContext) {
089            if (dataFormat == null) {
090                dataFormat = createDataFormat(routeContext);
091                ObjectHelper.notNull(dataFormat, "dataFormat");
092                configureDataFormat(dataFormat);
093            }
094            return dataFormat;
095        }
096    
097        /**
098         * Factory method to create the data format instance
099         */
100        protected DataFormat createDataFormat(RouteContext routeContext) {
101            if (dataFormatTypeName != null) {
102                Class type = ObjectHelper.loadClass(dataFormatTypeName, getClass().getClassLoader());
103                if (type == null) {
104                    throw new IllegalArgumentException("The class " + dataFormatTypeName + " is not on the classpath! Cannot use the dataFormat " + this);
105                }
106                return (DataFormat) ObjectHelper.newInstance(type);
107            }
108            return null;
109        }
110    
111        /**
112         * Allows derived classes to customize the data format
113         */
114        protected void configureDataFormat(DataFormat dataFormat) {
115        }
116    
117        /**
118         * Sets a named property on the data format instance using introspection
119         */
120        protected void setProperty(Object bean, String name, Object value) {
121            try {
122                IntrospectionSupport.setProperty(bean, name, value);
123            } catch (Exception e) {
124                throw new IllegalArgumentException("Failed to set property " + name + " on " + bean
125                                                   + ". Reason: " + e, e);
126            }
127        }
128    
129    
130    }