1 /** 2 * Copyright (C) 2008 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.inject.multibindings; 18 19 import com.google.inject.Key; 20 import com.google.inject.internal.Annotations; 21 22 import java.lang.annotation.Annotation; 23 import java.util.concurrent.atomic.AtomicInteger; 24 25 /** An implementation of Element. */ 26 // TODO(cgruber): Use AutoAnnotation when available, here & wherever else is makes sense. 27 class RealElement implements Element { 28 private static final AtomicInteger nextUniqueId = new AtomicInteger(1); 29 30 private final int uniqueId; 31 private final String setName; 32 private final Element.Type type; 33 private final String keyType; 34 35 RealElement(String setName, Element.Type type, String keyType) { 36 this(setName, type, keyType, nextUniqueId.incrementAndGet()); 37 } 38 39 RealElement(String setName, Element.Type type, String keyType, int uniqueId) { 40 this.uniqueId = uniqueId; 41 this.setName = setName; 42 this.type = type; 43 this.keyType = keyType; 44 } 45 46 @Override public String setName() { 47 return setName; 48 } 49 50 @Override public int uniqueId() { 51 return uniqueId; 52 } 53 54 @Override public Element.Type type() { 55 return type; 56 } 57 58 @Override public String keyType() { 59 return keyType; 60 } 61 62 @Override public Class<? extends Annotation> annotationType() { 63 return Element.class; 64 } 65 66 @Override public String toString() { 67 return "@" + Element.class.getName() + "(setName=" + setName 68 + ",uniqueId=" + uniqueId + ", type=" + type + ", keyType=" + keyType + ")"; 69 } 70 71 @Override public boolean equals(Object o) { 72 return o instanceof Element 73 && ((Element) o).setName().equals(setName()) 74 && ((Element) o).uniqueId() == uniqueId() 75 && ((Element) o).type() == type() 76 && ((Element) o).keyType().equals(keyType()); 77 } 78 79 @Override public int hashCode() { 80 return ((127 * "setName".hashCode()) ^ setName.hashCode()) 81 + ((127 * "uniqueId".hashCode()) ^ uniqueId) 82 + ((127 * "type".hashCode()) ^ type.hashCode()) 83 + ((127 * "keyType".hashCode()) ^ keyType.hashCode()); 84 } 85 86 /** 87 * Returns the name the binding should use. This is based on the annotation. 88 * If the annotation has an instance and is not a marker annotation, 89 * we ask the annotation for its toString. If it was a marker annotation 90 * or just an annotation type, we use the annotation's name. Otherwise, 91 * the name is the empty string. 92 */ 93 static String nameOf(Key<?> key) { 94 Annotation annotation = key.getAnnotation(); 95 Class<? extends Annotation> annotationType = key.getAnnotationType(); 96 if (annotation != null && !Annotations.isMarker(annotationType)) { 97 return key.getAnnotation().toString(); 98 } else if (key.getAnnotationType() != null) { 99 return "@" + key.getAnnotationType().getName(); 100 } else { 101 return ""; 102 } 103 } 104 } 105