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.spi;
018
019import org.apache.camel.util.StringHelper;
020
021/**
022 * Represents the data type URN which is used for message data type contract.
023 * <p/>
024 * Java class doesn't always explain the data type completely, for example XML and JSON
025 * data format is sometimes serialized as a {@code String}, {@code InputStream} or etc.
026 * The {@link DataTypeAware} message stores the DataType as a part of the message to carry
027 * those data type information even if it's marshaled, so that it could be
028 * leveraged to detect required {@link Transformer} and {@link Validator}.
029 * DataType consists of two parts, 'model' and 'name'. Its string representation is
030 * 'model:name' connected with colon. For example 'java:com.example.Order', 'xml:ABCOrder'
031 * or 'json:XYZOrder'. These type name other than java class name allows the message to
032 * carry the name of the message data structure even if it's marshaled.
033 * 
034 * @see DataTypeAware
035 * @see Transformer
036 * @see Validator
037 */
038public class DataType {
039
040    public static final String JAVA_TYPE_PREFIX = "java";
041
042    private String model;
043    private String name;
044    private boolean isJavaType;
045    private String typeString;
046    
047    public DataType(String urn) {
048        if (urn != null) {
049            String[] split = StringHelper.splitOnCharacter(urn, ":", 2);
050            model = split[0];
051            isJavaType = model.equals(JAVA_TYPE_PREFIX);
052            if (split.length > 1) {
053                name = split[1];
054            }
055        }
056    }
057    
058    public DataType(Class<?> clazz) {
059        model = JAVA_TYPE_PREFIX;
060        isJavaType = true;
061        name = clazz.getName();
062    }
063    
064    public String getModel() {
065        return model;
066    }
067    
068    public String getName() {
069        return name;
070    }
071    
072    public boolean isJavaType() {
073        return isJavaType;
074    }
075
076    @Override
077    public String toString() {
078        if (this.typeString == null) {
079            this.typeString = name != null && !name.isEmpty() ? model + ":" + name : model;
080        }
081        return this.typeString;
082    }
083
084    @Override
085    public boolean equals(Object target) {
086        if (target instanceof DataType) {
087            DataType targetdt = (DataType)target;
088            String targetModel = targetdt.getModel();
089            String targetName = targetdt.getName();
090            if (targetModel == null) {
091                return false;
092            } else if (targetName == null) {
093                return targetModel.equals(getModel()) && getName() == null;
094            } else {
095                return targetModel.equals(getModel()) && targetName.equals(getName());
096            }
097        }
098        return false;
099    }
100
101    @Override
102    public int hashCode() {
103        return toString().hashCode();
104    }
105}