View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.transformer.types;
8   
9   import org.mule.api.transformer.DataType;
10  import org.mule.util.generics.GenericsUtils;
11  import org.mule.util.generics.MethodParameter;
12  
13  import java.lang.reflect.Method;
14  import java.util.Collection;
15  
16  /**
17   * A data type that represents a generified collection.  When checked for compatability both the colection type and the
18   * generic item type will be compared.
19   *
20   * @since 3.0
21   */
22  public class CollectionDataType<T> extends SimpleDataType<T>
23  {
24      private Class<? extends Collection> collectionType;
25  
26      /**
27       * Creates an untyped collection data type
28       *
29       * @param collectionType the collection class type
30       */
31      public CollectionDataType(Class<? extends Collection> collectionType)
32      {
33          super(Object.class);
34          this.collectionType = collectionType;
35      }
36  
37      public CollectionDataType(Class<? extends Collection> collectionType, String mimeType)
38      {
39          super(Object.class, mimeType);
40          this.collectionType = collectionType;
41      }
42  
43      public CollectionDataType(Class<? extends Collection> collectionType, Class type, String mimeType)
44      {
45          super(type, mimeType);
46          this.collectionType = collectionType;
47      }
48  
49      public CollectionDataType(Class<? extends Collection> collectionType, Class type)
50      {
51          super(type);
52          this.collectionType = collectionType;
53      }
54  
55      public Class<?> getItemType()
56      {
57          return type;
58      }
59  
60      @Override
61      public Class getType()
62      {
63          return collectionType;
64      }
65  
66      public static CollectionDataType createFromMethodReturn(Method m)
67      {
68          return createFromMethodReturn(m, null);
69      }
70  
71      public static CollectionDataType createFromMethodReturn(Method m, String mimeType)
72      {
73          Class collType = GenericsUtils.getCollectionReturnType(m);
74  
75          if (collType != null)
76          {
77              return new CollectionDataType((Class<? extends Collection>)m.getReturnType(), collType, mimeType);
78          }
79          else
80          {
81              throw new IllegalArgumentException("Return type for method is not a generic type collection. " + m);
82          }
83      }
84  
85      public static CollectionDataType createFromMethodParam(Method m, int paramIndex)
86      {
87          return createFromMethodParam(m, paramIndex, null);
88      }
89  
90      public static CollectionDataType createFromMethodParam(Method m, int paramIndex, String mimeType)
91      {
92          Class collType = GenericsUtils.getCollectionParameterType(new MethodParameter(m, paramIndex));
93  
94          if (collType != null)
95          {
96              return new CollectionDataType((Class<? extends Collection>)m.getParameterTypes()[paramIndex], collType, mimeType);
97          }
98          else
99          {
100             throw new IllegalArgumentException("Parameter type (index: " + paramIndex + ") for method is not a generic type collection. " + m);
101         }
102     }
103 
104     public static boolean isReturnTypeACollection(Method m)
105     {
106         return GenericsUtils.getCollectionReturnType(m) != null;
107     }
108 
109     public static boolean isParamTypeACollection(Method m, int paramIndex)
110     {
111         return GenericsUtils.getCollectionParameterType(new MethodParameter(m, paramIndex)) != null;
112     }
113 
114     @Override
115     public boolean isCompatibleWith(DataType dataType)
116     {
117         if (dataType instanceof ImmutableDataType)
118         {
119             dataType = ((ImmutableDataType)dataType).getWrappedDataType();
120         }
121         if (!(dataType instanceof CollectionDataType))
122         {
123             return false;
124         }
125 
126         if (!super.isCompatibleWith(dataType))
127         {
128             return false;
129         }
130         CollectionDataType that = (CollectionDataType) dataType;
131 
132         //Untyped compatible collection
133         return that.getItemType() == Object.class || this.getItemType().isAssignableFrom(that.getItemType());
134 
135     }
136 
137     @Override
138     public boolean equals(Object o)
139     {
140         if (this == o)
141         {
142             return true;
143         }
144         if (o == null || getClass() != o.getClass())
145         {
146             return false;
147         }
148 
149         CollectionDataType that = (CollectionDataType) o;
150 
151         if (!getItemType().equals(that.getItemType()))
152         {
153             return false;
154         }
155 
156         if ((mimeType != null ? !mimeType.equals(that.mimeType) : that.mimeType != null) && !ANY_MIME_TYPE.equals(that.mimeType) && !ANY_MIME_TYPE.equals(this.mimeType))
157         {
158             return false;
159         }
160 
161         return getType().equals(that.getType());
162 
163     }
164 
165     @Override
166     public int hashCode()
167     {
168         int result = getType().hashCode();
169         result = 31 * result + getItemType().hashCode();
170         result = 31 * result + (getMimeType() != null ? getMimeType().hashCode() : 0);
171         result = 31 * result + (getEncoding() != null ? getEncoding().hashCode() : 0);
172         return result;
173     }
174 
175     @Override
176     public String toString()
177     {
178         return "CollectionDataType{" +
179                 "type=" + getType().getName() +
180                 ", itemType=" + getItemType().getName() +
181                 ", mimeType='" + getMimeType() + '\'' +
182                 '}';
183     }
184 }