View Javadoc
1   /*
2    * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  package com.sun.xml.internal.bind.api;
27  
28  import java.lang.annotation.Annotation;
29  import java.lang.reflect.Type;
30  import java.util.Arrays;
31  import java.util.Collection;
32  
33  import javax.xml.namespace.QName;
34  
35  /**
36   * A reference to a JAXB-bound type.
37   *
38   * <p>
39   * <b>Subject to change without notice</b>.
40   *
41   * @since 2.0 EA1
42   * @author Kohsuke Kawaguchi
43   */
44  public final class TypeReference {
45  
46      /**
47       * The associated XML element name that the JAX-RPC uses with this type reference.
48       *
49       * Always non-null. Strings are interned.
50       */
51      public final QName tagName;
52  
53      /**
54       * The Java type that's being referenced.
55       *
56       * Always non-null.
57       */
58      public final Type type;
59  
60      /**
61       * The annotations associated with the reference of this type.
62       *
63       * Always non-null.
64       */
65      public final Annotation[] annotations;
66  
67      public TypeReference(QName tagName, Type type, Annotation... annotations) {
68          if(tagName==null || type==null || annotations==null) {
69              String nullArgs = "";
70  
71              if(tagName == null)     nullArgs = "tagName";
72              if(type == null)        nullArgs += (nullArgs.length() > 0 ? ", type" : "type");
73              if(annotations == null) nullArgs += (nullArgs.length() > 0 ? ", annotations" : "annotations");
74  
75              Messages.ARGUMENT_CANT_BE_NULL.format(nullArgs);
76  
77              throw new IllegalArgumentException(Messages.ARGUMENT_CANT_BE_NULL.format(nullArgs));
78          }
79  
80          this.tagName = new QName(tagName.getNamespaceURI().intern(), tagName.getLocalPart().intern(), tagName.getPrefix());
81          this.type = type;
82          this.annotations = annotations;
83      }
84  
85      /**
86       * Finds the specified annotation from the array and returns it.
87       * Null if not found.
88       */
89      public <A extends Annotation> A get( Class<A> annotationType ) {
90          for (Annotation a : annotations) {
91              if(a.annotationType()==annotationType)
92                  return annotationType.cast(a);
93          }
94          return null;
95      }
96  
97      /**
98       * Creates a {@link TypeReference} for the item type,
99       * if this {@link TypeReference} represents a collection type.
100      * Otherwise returns an identical type.
101      */
102     public TypeReference toItemType() {
103         // if we are to reinstitute this check, check JAXB annotations only
104         // assert annotations.length==0;   // not designed to work with adapters.
105 
106         Type base = Utils.REFLECTION_NAVIGATOR.getBaseClass(type, Collection.class);
107         if(base==null)
108             return this;    // not a collection
109 
110         return new TypeReference(tagName, Utils.REFLECTION_NAVIGATOR.getTypeArgument(base,0));
111     }
112 
113     @Override
114     public boolean equals(Object o) {
115         if (this == o) return true;
116         if (o == null || getClass() != o.getClass()) return false;
117 
118         TypeReference that = (TypeReference) o;
119 
120         if (!Arrays.equals(annotations, that.annotations)) return false;
121         if (!tagName.equals(that.tagName)) return false;
122         if (!type.equals(that.type)) return false;
123 
124         return true;
125     }
126 
127     @Override
128     public int hashCode() {
129         int result = tagName.hashCode();
130         result = 31 * result + type.hashCode();
131         result = 31 * result + Arrays.hashCode(annotations);
132         return result;
133     }
134 }