ClassMetadataReadingVisitor.java 5.8 KB
Newer Older
A
Arjen Poutsma 已提交
1
/*
2
 * Copyright 2002-2014 the original author or authors.
A
Arjen Poutsma 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 *
 * 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.springframework.core.type.classreading;

19 20 21
import java.util.LinkedHashSet;
import java.util.Set;

22 23 24 25 26
import org.springframework.asm.AnnotationVisitor;
import org.springframework.asm.Attribute;
import org.springframework.asm.ClassVisitor;
import org.springframework.asm.FieldVisitor;
import org.springframework.asm.MethodVisitor;
27
import org.springframework.asm.Opcodes;
28
import org.springframework.asm.SpringAsmInfo;
A
Arjen Poutsma 已提交
29 30 31 32 33 34 35 36 37 38 39 40
import org.springframework.core.type.ClassMetadata;
import org.springframework.util.ClassUtils;

/**
 * ASM class visitor which looks only for the class name and implemented types,
 * exposing them through the {@link org.springframework.core.type.ClassMetadata}
 * interface.
 *
 * @author Rod Johnson
 * @author Costin Leau
 * @author Mark Fisher
 * @author Ramnivas Laddad
41
 * @author Chris Beams
A
Arjen Poutsma 已提交
42 43
 * @since 2.5
 */
44
class ClassMetadataReadingVisitor extends ClassVisitor implements ClassMetadata {
A
Arjen Poutsma 已提交
45 46 47 48 49

	private String className;

	private boolean isInterface;

50 51
	private boolean isAnnotation;

A
Arjen Poutsma 已提交
52 53
	private boolean isAbstract;

54 55
	private boolean isFinal;

A
Arjen Poutsma 已提交
56 57 58 59 60 61 62
	private String enclosingClassName;

	private boolean independentInnerClass;

	private String superClassName;

	private String[] interfaces;
63 64 65

	private Set<String> memberClassNames = new LinkedHashSet<String>();

66

67 68 69 70 71
	public ClassMetadataReadingVisitor() {
		super(SpringAsmInfo.ASM_VERSION);
	}


72
	@Override
73
	public void visit(int version, int access, String name, String signature, String supername, String[] interfaces) {
A
Arjen Poutsma 已提交
74 75
		this.className = ClassUtils.convertResourcePathToClassName(name);
		this.isInterface = ((access & Opcodes.ACC_INTERFACE) != 0);
76
		this.isAnnotation = ((access & Opcodes.ACC_ANNOTATION) != 0);
A
Arjen Poutsma 已提交
77
		this.isAbstract = ((access & Opcodes.ACC_ABSTRACT) != 0);
78
		this.isFinal = ((access & Opcodes.ACC_FINAL) != 0);
79
		if (supername != null && !this.isInterface) {
A
Arjen Poutsma 已提交
80 81 82 83 84 85 86 87
			this.superClassName = ClassUtils.convertResourcePathToClassName(supername);
		}
		this.interfaces = new String[interfaces.length];
		for (int i = 0; i < interfaces.length; i++) {
			this.interfaces[i] = ClassUtils.convertResourcePathToClassName(interfaces[i]);
		}
	}

88
	@Override
89
	public void visitOuterClass(String owner, String name, String desc) {
A
Arjen Poutsma 已提交
90 91 92
		this.enclosingClassName = ClassUtils.convertResourcePathToClassName(owner);
	}

93
	@Override
94
	public void visitInnerClass(String name, String outerName, String innerName, int access) {
95
		if (outerName != null) {
96 97
			String fqName = ClassUtils.convertResourcePathToClassName(name);
			String fqOuterName = ClassUtils.convertResourcePathToClassName(outerName);
98 99 100 101 102 103 104
			if (this.className.equals(fqName)) {
				this.enclosingClassName = fqOuterName;
				this.independentInnerClass = ((access & Opcodes.ACC_STATIC) != 0);
			}
			else if (this.className.equals(fqOuterName)) {
				this.memberClassNames.add(fqName);
			}
A
Arjen Poutsma 已提交
105 106 107
		}
	}

108
	@Override
109 110 111 112
	public void visitSource(String source, String debug) {
		// no-op
	}

113
	@Override
114 115
	public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
		// no-op
116
		return new EmptyAnnotationVisitor();
117 118
	}

119
	@Override
120 121 122 123
	public void visitAttribute(Attribute attr) {
		// no-op
	}

124
	@Override
125 126
	public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
		// no-op
127
		return new EmptyFieldVisitor();
128 129
	}

130
	@Override
131 132
	public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
		// no-op
133
		return new EmptyMethodVisitor();
134 135
	}

136
	@Override
137 138 139 140
	public void visitEnd() {
		// no-op
	}

A
Arjen Poutsma 已提交
141

142
	@Override
A
Arjen Poutsma 已提交
143 144 145 146
	public String getClassName() {
		return this.className;
	}

147
	@Override
A
Arjen Poutsma 已提交
148 149 150 151
	public boolean isInterface() {
		return this.isInterface;
	}

152 153 154 155 156
	@Override
	public boolean isAnnotation() {
		return this.isAnnotation;
	}

157
	@Override
A
Arjen Poutsma 已提交
158 159 160 161
	public boolean isAbstract() {
		return this.isAbstract;
	}

162
	@Override
A
Arjen Poutsma 已提交
163 164 165 166
	public boolean isConcrete() {
		return !(this.isInterface || this.isAbstract);
	}

167
	@Override
168 169 170 171
	public boolean isFinal() {
		return this.isFinal;
	}

172
	@Override
A
Arjen Poutsma 已提交
173 174 175 176
	public boolean isIndependent() {
		return (this.enclosingClassName == null || this.independentInnerClass);
	}

177
	@Override
A
Arjen Poutsma 已提交
178 179 180 181
	public boolean hasEnclosingClass() {
		return (this.enclosingClassName != null);
	}

182
	@Override
A
Arjen Poutsma 已提交
183 184 185 186
	public String getEnclosingClassName() {
		return this.enclosingClassName;
	}

187
	@Override
A
Arjen Poutsma 已提交
188 189 190 191
	public boolean hasSuperClass() {
		return (this.superClassName != null);
	}

192
	@Override
A
Arjen Poutsma 已提交
193 194 195 196
	public String getSuperClassName() {
		return this.superClassName;
	}

197
	@Override
A
Arjen Poutsma 已提交
198 199 200 201
	public String[] getInterfaceNames() {
		return this.interfaces;
	}

202
	@Override
203 204 205 206
	public String[] getMemberClassNames() {
		return this.memberClassNames.toArray(new String[this.memberClassNames.size()]);
	}

207

208
	private static class EmptyAnnotationVisitor extends AnnotationVisitor {
209

210 211 212
		public EmptyAnnotationVisitor() {
			super(SpringAsmInfo.ASM_VERSION);
		}
213

214 215 216 217
		@Override
		public AnnotationVisitor visitAnnotation(String name, String desc) {
			return this;
		}
218

219 220 221 222
		@Override
		public AnnotationVisitor visitArray(String name) {
			return this;
		}
223 224 225
	}


226
	private static class EmptyMethodVisitor extends MethodVisitor {
227

228 229 230
		public EmptyMethodVisitor() {
			super(SpringAsmInfo.ASM_VERSION);
		}
231 232 233
	}


234
	private static class EmptyFieldVisitor extends FieldVisitor {
235

236 237 238
		public EmptyFieldVisitor() {
			super(SpringAsmInfo.ASM_VERSION);
		}
239 240
	}

241
}