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