001/* 002 * Copyright 2002-2017 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.core.type; 018 019import java.lang.reflect.Modifier; 020import java.util.LinkedHashSet; 021 022import org.springframework.util.Assert; 023import org.springframework.util.StringUtils; 024 025/** 026 * {@link ClassMetadata} implementation that uses standard reflection 027 * to introspect a given {@code Class}. 028 * 029 * @author Juergen Hoeller 030 * @since 2.5 031 */ 032public class StandardClassMetadata implements ClassMetadata { 033 034 private final Class<?> introspectedClass; 035 036 037 /** 038 * Create a new StandardClassMetadata wrapper for the given Class. 039 * @param introspectedClass the Class to introspect 040 */ 041 public StandardClassMetadata(Class<?> introspectedClass) { 042 Assert.notNull(introspectedClass, "Class must not be null"); 043 this.introspectedClass = introspectedClass; 044 } 045 046 /** 047 * Return the underlying Class. 048 */ 049 public final Class<?> getIntrospectedClass() { 050 return this.introspectedClass; 051 } 052 053 054 @Override 055 public String getClassName() { 056 return this.introspectedClass.getName(); 057 } 058 059 @Override 060 public boolean isInterface() { 061 return this.introspectedClass.isInterface(); 062 } 063 064 @Override 065 public boolean isAnnotation() { 066 return this.introspectedClass.isAnnotation(); 067 } 068 069 @Override 070 public boolean isAbstract() { 071 return Modifier.isAbstract(this.introspectedClass.getModifiers()); 072 } 073 074 @Override 075 public boolean isConcrete() { 076 return !(isInterface() || isAbstract()); 077 } 078 079 @Override 080 public boolean isFinal() { 081 return Modifier.isFinal(this.introspectedClass.getModifiers()); 082 } 083 084 @Override 085 public boolean isIndependent() { 086 return (!hasEnclosingClass() || 087 (this.introspectedClass.getDeclaringClass() != null && 088 Modifier.isStatic(this.introspectedClass.getModifiers()))); 089 } 090 091 @Override 092 public boolean hasEnclosingClass() { 093 return (this.introspectedClass.getEnclosingClass() != null); 094 } 095 096 @Override 097 public String getEnclosingClassName() { 098 Class<?> enclosingClass = this.introspectedClass.getEnclosingClass(); 099 return (enclosingClass != null ? enclosingClass.getName() : null); 100 } 101 102 @Override 103 public boolean hasSuperClass() { 104 return (this.introspectedClass.getSuperclass() != null); 105 } 106 107 @Override 108 public String getSuperClassName() { 109 Class<?> superClass = this.introspectedClass.getSuperclass(); 110 return (superClass != null ? superClass.getName() : null); 111 } 112 113 @Override 114 public String[] getInterfaceNames() { 115 Class<?>[] ifcs = this.introspectedClass.getInterfaces(); 116 String[] ifcNames = new String[ifcs.length]; 117 for (int i = 0; i < ifcs.length; i++) { 118 ifcNames[i] = ifcs[i].getName(); 119 } 120 return ifcNames; 121 } 122 123 @Override 124 public String[] getMemberClassNames() { 125 LinkedHashSet<String> memberClassNames = new LinkedHashSet<String>(4); 126 for (Class<?> nestedClass : this.introspectedClass.getDeclaredClasses()) { 127 memberClassNames.add(nestedClass.getName()); 128 } 129 return StringUtils.toStringArray(memberClassNames); 130 } 131 132}