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 */ 017package org.apache.camel.model.dataformat; 018 019import javax.xml.bind.annotation.XmlAccessType; 020import javax.xml.bind.annotation.XmlAccessorType; 021import javax.xml.bind.annotation.XmlAttribute; 022import javax.xml.bind.annotation.XmlRootElement; 023import javax.xml.bind.annotation.XmlTransient; 024 025import org.apache.camel.CamelContext; 026import org.apache.camel.model.DataFormatDefinition; 027import org.apache.camel.spi.DataFormat; 028import org.apache.camel.spi.Metadata; 029import org.apache.camel.spi.RouteContext; 030import org.apache.camel.util.ObjectHelper; 031 032/** 033 * YAML data format 034 * 035 * @version 036 */ 037@Metadata(label = "dataformat,transformation,yaml", title = "YAML") 038@XmlRootElement(name = "yaml") 039@XmlAccessorType(XmlAccessType.FIELD) 040public class YAMLDataFormat extends DataFormatDefinition { 041 @XmlAttribute @Metadata(defaultValue = "SnakeYAML") 042 private YAMLLibrary library = YAMLLibrary.SnakeYAML; 043 @XmlTransient 044 private ClassLoader classLoader; 045 @XmlTransient 046 private Class<?> unmarshalType; 047 @XmlAttribute 048 private String unmarshalTypeName; 049 @XmlAttribute 050 private String constructor; 051 @XmlAttribute 052 private String representer; 053 @XmlAttribute 054 private String dumperOptions; 055 @XmlAttribute 056 private String resolver; 057 @XmlAttribute @Metadata(defaultValue = "true") 058 private Boolean useApplicationContextClassLoader = true; 059 @XmlAttribute @Metadata(defaultValue = "false") 060 private Boolean prettyFlow = false; 061 062 public YAMLDataFormat() { 063 this(YAMLLibrary.SnakeYAML); 064 } 065 066 public YAMLDataFormat(YAMLLibrary library) { 067 super("yaml-" + library.name().toLowerCase()); 068 this.library = library; 069 } 070 071 public YAMLDataFormat(YAMLLibrary library, Class<?> unmarshalType) { 072 super("yaml-" + library.name().toLowerCase()); 073 this.library = library; 074 this.unmarshalType = unmarshalType; 075 } 076 077 public YAMLLibrary getLibrary() { 078 return library; 079 } 080 081 /** 082 * Which yaml library to use such. 083 * <p/> 084 * Is by default SnakeYAML 085 */ 086 public void setLibrary(YAMLLibrary library) { 087 this.library = library; 088 setDataFormatName("yaml-" + library.name().toLowerCase()); 089 } 090 091 public Class<?> getUnmarshalType() { 092 return unmarshalType; 093 } 094 095 /** 096 * Class of the object to be created 097 */ 098 public void setUnmarshalType(Class<?> type) { 099 this.unmarshalType = type; 100 } 101 102 public String getUnmarshalTypeName() { 103 return unmarshalTypeName; 104 } 105 106 /** 107 * Class name of the java type to use when unarmshalling 108 */ 109 public void setUnmarshalTypeName(String unmarshalTypeName) { 110 this.unmarshalTypeName = unmarshalTypeName; 111 } 112 113 public ClassLoader getClassLoader() { 114 return classLoader; 115 } 116 117 /** 118 * Set a custom classloader 119 */ 120 public void setClassLoader(ClassLoader classLoader) { 121 this.classLoader = classLoader; 122 } 123 124 public String getConstructor() { 125 return constructor; 126 } 127 128 /** 129 * BaseConstructor to construct incoming documents. 130 */ 131 public void setConstructor(String constructor) { 132 this.constructor = constructor; 133 } 134 135 public String getRepresenter() { 136 return representer; 137 } 138 139 /** 140 * Representer to emit outgoing objects. 141 */ 142 public void setRepresenter(String representer) { 143 this.representer = representer; 144 } 145 146 public String getDumperOptions() { 147 return dumperOptions; 148 } 149 150 /** 151 * DumperOptions to configure outgoing objects. 152 */ 153 public void setDumperOptions(String dumperOptions) { 154 this.dumperOptions = dumperOptions; 155 } 156 157 public String getResolver() { 158 return resolver; 159 } 160 161 /** 162 * Resolver to detect implicit type 163 */ 164 public void setResolver(String resolver) { 165 this.resolver = resolver; 166 } 167 168 public boolean isUseApplicationContextClassLoader() { 169 return useApplicationContextClassLoader; 170 } 171 172 /** 173 * Use ApplicationContextClassLoader as custom ClassLoader 174 */ 175 public void setUseApplicationContextClassLoader(boolean useApplicationContextClassLoader) { 176 this.useApplicationContextClassLoader = useApplicationContextClassLoader; 177 } 178 179 public boolean isPrettyFlow() { 180 return prettyFlow; 181 } 182 183 /** 184 * Force the emitter to produce a pretty YAML document when using the flow 185 * style. 186 */ 187 public void setPrettyFlow(boolean prettyFlow) { 188 this.prettyFlow = prettyFlow; 189 } 190 191 @Override 192 protected DataFormat createDataFormat(RouteContext routeContext) { 193 if (library == YAMLLibrary.SnakeYAML) { 194 setProperty(routeContext.getCamelContext(), this, "dataFormatName", "yaml-snakeyaml"); 195 } 196 197 return super.createDataFormat(routeContext); 198 } 199 200 @Override 201 protected void configureDataFormat(DataFormat dataFormat, CamelContext camelContext) { 202 if (library == YAMLLibrary.SnakeYAML) { 203 configureSnakeDataFormat(dataFormat, camelContext); 204 } 205 } 206 207 protected void configureSnakeDataFormat(DataFormat dataFormat, CamelContext camelContext) { 208 Class<?> yamlUnmarshalType = unmarshalType; 209 if (yamlUnmarshalType == null && unmarshalTypeName != null) { 210 try { 211 yamlUnmarshalType = camelContext.getClassResolver().resolveMandatoryClass(unmarshalTypeName); 212 } catch (ClassNotFoundException e) { 213 throw ObjectHelper.wrapRuntimeCamelException(e); 214 } 215 } 216 217 setProperty(dataFormat, camelContext, "unmarshalType", yamlUnmarshalType); 218 setProperty(dataFormat, camelContext, "classLoader", classLoader); 219 setProperty(dataFormat, camelContext, "useApplicationContextClassLoader", useApplicationContextClassLoader); 220 setProperty(dataFormat, camelContext, "prettyFlow", prettyFlow); 221 222 setPropertyRef(dataFormat, camelContext, "constructor", constructor); 223 setPropertyRef(dataFormat, camelContext, "representer", representer); 224 setPropertyRef(dataFormat, camelContext, "dumperOptions", dumperOptions); 225 setPropertyRef(dataFormat, camelContext, "resolver", resolver); 226 } 227 228 protected void setProperty(DataFormat dataFormat, CamelContext camelContext, String propertyName, Object propertyValue) { 229 if (ObjectHelper.isNotEmpty(propertyValue)) { 230 setProperty(camelContext, dataFormat, propertyName, propertyValue); 231 } 232 } 233 234 protected void setPropertyRef(DataFormat dataFormat, CamelContext camelContext, String propertyName, String propertyValue) { 235 if (ObjectHelper.isNotEmpty(propertyValue)) { 236 // must be a reference value 237 String ref = propertyValue.startsWith("#") ? propertyValue : "#" + propertyValue; 238 setProperty(camelContext, dataFormat, propertyName, ref); 239 } 240 } 241}