001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.commons.weaver.model; 020 021import java.lang.reflect.Constructor; 022import java.lang.reflect.Field; 023import java.lang.reflect.Method; 024import java.util.Collections; 025import java.util.Comparator; 026import java.util.concurrent.ConcurrentNavigableMap; 027import java.util.concurrent.ConcurrentSkipListMap; 028 029import org.apache.commons.weaver.utils.Args; 030 031/** 032 * {@link Weavable} {@link Class}. 033 * 034 * @param <T> type 035 */ 036public class WeavableClass<T> extends NestedWeavable<WeavableClass<T>, Class<T>, WeavablePackage, Package> { 037 private final ConcurrentNavigableMap<String, WeavableField<T>> fields = 038 new ConcurrentSkipListMap<String, WeavableField<T>>(); 039 040 private final ConcurrentNavigableMap<Constructor<T>, WeavableConstructor<T>> ctors = 041 new ConcurrentSkipListMap<Constructor<T>, WeavableConstructor<T>>(new Comparator<Constructor<?>>() { 042 043 @Override 044 public int compare(final Constructor<?> ctor1, final Constructor<?> ctor2) { 045 return Args.compare(ctor1.getParameterTypes(), ctor2.getParameterTypes()); 046 } 047 }); 048 049 private final ConcurrentNavigableMap<Method, WeavableMethod<T>> methods = 050 new ConcurrentSkipListMap<Method, WeavableMethod<T>>(new Comparator<Method>() { 051 052 @Override 053 public int compare(final Method methd1, final Method methd2) { 054 final int result = methd1.getName().compareTo(methd2.getName()); 055 return result == 0 ? Args.compare(methd1.getParameterTypes(), methd2.getParameterTypes()) : result; 056 } 057 }); 058 059 /** 060 * Create a new {@link WeavableClass} instance. 061 * @param target {@link Class} 062 * @param parent {@link WeavablePackage} enclosing 063 */ 064 public WeavableClass(final Class<T> target, final WeavablePackage parent) { 065 super(target, parent); 066 } 067 068 /** 069 * Get a {@link WeavableField} representing {@code fld}. 070 * @param fld to wrap 071 * @return {@link WeavableField} 072 */ 073 public WeavableField<T> getWeavable(final Field fld) { 074 final String key = fld.getName(); 075 if (fields.containsKey(key)) { 076 final WeavableField<T> result = fields.get(key); 077 return result; 078 } 079 final WeavableField<T> result = new WeavableField<T>(fld, this); 080 final WeavableField<T> faster = fields.putIfAbsent(key, result); 081 return faster == null ? result : faster; 082 } 083 084 /** 085 * Get a {@link WeavableMethod} representing {@code mt}. 086 * @param methd to wrap 087 * @return {@link WeavableMethod} 088 */ 089 public WeavableMethod<T> getWeavable(final Method methd) { 090 if (methods.containsKey(methd)) { 091 final WeavableMethod<T> result = methods.get(methd); 092 return result; 093 } 094 final WeavableMethod<T> result = new WeavableMethod<T>(methd, this); 095 final WeavableMethod<T> faster = methods.putIfAbsent(methd, result); 096 return faster == null ? result : faster; 097 } 098 099 /** 100 * Get a {@link WeavableConstructor} representing {@code ctor}. 101 * @param ctor to wrap 102 * @return {@link WeavableConstructor} 103 */ 104 public WeavableConstructor<T> getWeavable(final Constructor<T> ctor) { 105 if (ctors.containsKey(ctor)) { 106 final WeavableConstructor<T> result = ctors.get(ctor); 107 return result; 108 } 109 final WeavableConstructor<T> result = new WeavableConstructor<T>(ctor, this); 110 final WeavableConstructor<T> faster = ctors.putIfAbsent(ctor, result); 111 return faster == null ? result : faster; 112 } 113 114 /** 115 * Get {@link WeavableField}s of this {@link WeavableClass}. 116 * @return {@link Iterable} 117 */ 118 public Iterable<WeavableField<T>> getFields() { 119 return Collections.unmodifiableCollection(fields.values()); 120 } 121 122 /** 123 * Get {@link WeavableConstructor}s of this {@link WeavableClass}. 124 * @return {@link Iterable} 125 */ 126 public Iterable<WeavableConstructor<T>> getConstructors() { 127 return Collections.unmodifiableCollection(ctors.values()); 128 } 129 130 /** 131 * Get {@link WeavableMethod}s of this {@link WeavableClass}. 132 * @return {@link Iterable} 133 */ 134 public Iterable<WeavableMethod<T>> getMethods() { 135 return Collections.unmodifiableCollection(methods.values()); 136 } 137 138 /** 139 * {@inheritDoc} 140 */ 141 @Override 142 protected int localCompareTo(final WeavableClass<T> obj) { 143 return getTarget().getName().compareTo(obj.getTarget().getName()); 144 } 145}