/* * JBoss, Home of Professional Open Source * Copyright 2012, Red Hat, Inc., and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jboss.weld.annotated.slim; import java.lang.reflect.Type; import java.util.Objects; import javax.enterprise.inject.New; import javax.enterprise.inject.spi.AnnotatedType; import javax.enterprise.inject.spi.ProcessAnnotatedType; import org.jboss.weld.annotated.Identifier; import org.jboss.weld.annotated.slim.backed.BackedAnnotatedType; import org.jboss.weld.annotated.slim.unbacked.UnbackedAnnotatedType; import org.jboss.weld.bootstrap.spi.BeanDeploymentArchive; import org.jboss.weld.util.AnnotatedTypes; import org.jboss.weld.util.Types; /** * An identifier for a an {@link AnnotatedType} The identifier is composed of four parts: * * <ul> * <li>The identifier of the {@link BeanDeploymentArchive} which the type resides in. This allows different {@link BeanDeploymentArchive}s to bundle classes with the same name.</li> * <li>The declaring class name.</li> * <li>An optional suffix. The suffix is used for two purposes.</li> * <ul> * <li>If a {@link BackedAnnotatedType} is created for a parameterized type (a {@link New} injection point), suffix is set to an identifier of that type</li> * <li>For an {@link UnbackedAnnotatedType} suffix holds the type identifier provided by the extension or calculated based on the type's qualities (see {@link AnnotatedTypes#createTypeId(AnnotatedType)})</li> * </ul> * <li>Modified flag which indicates whether this is an identifier for an {@link AnnotatedType} which has been modified during {@link ProcessAnnotatedType} event notification.</li> * </ul> * * @author Jozef Hartinger * */ public class AnnotatedTypeIdentifier implements Identifier { public static final String NULL_BDA_ID = AnnotatedTypeIdentifier.class.getName() + ".null"; public static final String SYNTHETIC_ANNOTATION_SUFFIX = "syntheticAnnotation"; public static AnnotatedTypeIdentifier forBackedAnnotatedType(String contextId, Class<?> javaClass, Type type, String bdaId) { return forBackedAnnotatedType(contextId, javaClass, type, bdaId, null); } public static AnnotatedTypeIdentifier forBackedAnnotatedType(String contextId, Class<?> javaClass, Type type, String bdaId, String suffix) { return new AnnotatedTypeIdentifier(contextId, bdaId, javaClass.getName(), suffix != null ? suffix : getTypeId(type), false); } public static AnnotatedTypeIdentifier forModifiedAnnotatedType(AnnotatedTypeIdentifier originalIdentifier) { if (originalIdentifier.modified) { throw new IllegalArgumentException("Cannot create a modified identifier for an already modified identifier."); } return new AnnotatedTypeIdentifier(originalIdentifier.contextId, originalIdentifier.bdaId, originalIdentifier.className, originalIdentifier.suffix, true); } public static AnnotatedTypeIdentifier of(String contextId, String bdaId, String className, String suffix, boolean modified) { return new AnnotatedTypeIdentifier(contextId, bdaId, className, suffix, modified); } private static final long serialVersionUID = -264184070652700144L; private final String contextId; private final String bdaId; private final String className; private final String suffix; private final boolean modified; private final int hashCode; private AnnotatedTypeIdentifier(String contextId, String bdaId, String className, String suffix, boolean modified) { this.contextId = contextId; this.bdaId = bdaId; this.className = className; this.suffix = suffix; this.modified = modified; this.hashCode = Objects.hash(contextId, bdaId, className, suffix, modified); } private static String getTypeId(Type type) { if (type == null || type instanceof Class<?>) { return null; } return Types.getTypeId(type); } public String getContextId() { return contextId; } public String getBdaId() { return bdaId; } public String getClassName() { return className; } public String getSuffix() { return suffix; } public boolean isModified() { return modified; } @Override public int hashCode() { return hashCode; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj instanceof AnnotatedTypeIdentifier) { AnnotatedTypeIdentifier they = (AnnotatedTypeIdentifier) obj; return Objects.equals(bdaId, they.bdaId) && Objects.equals(className, they.className) && Objects.equals(suffix, they.suffix) && Objects.equals(modified, they.modified) && Objects.equals(contextId, they.contextId); } return false; } @Override public String asString() { StringBuilder builder = new StringBuilder(); builder.append(contextId); builder.append(ID_SEPARATOR); builder.append(bdaId); builder.append(ID_SEPARATOR); builder.append(className); builder.append(ID_SEPARATOR); builder.append(suffix); builder.append(ID_SEPARATOR); builder.append(modified); return builder.toString(); } @Override public String toString() { return "AnnotatedTypeIdentifier [contextId=" + contextId + ", bdaId=" + bdaId + ", className=" + className + ", suffix=" + suffix + ", modified=" + modified + "]"; } }