ExpandoMetaClass is a MetaClass that behaves like an Expando, allowing the addition or replacement of methods, properties and constructors on the fly. Some examples of usage: // defines or replaces instance method: metaClass.myMethod = { args -> } // defines a new instance method
| 256 | * @since 1.5 |
| 257 | */ |
| 258 | public class ExpandoMetaClass extends MetaClassImpl implements GroovyObject { |
| 259 | |
| 260 | private static final String CLASS_PROPERTY = "class"; |
| 261 | /** |
| 262 | * Pseudo-property used by the expando DSL to define constructors. |
| 263 | */ |
| 264 | public static final String CONSTRUCTOR = "constructor"; |
| 265 | private static final String GROOVY_CONSTRUCTOR = "<init>"; |
| 266 | private static final String META_CLASS_PROPERTY = "metaClass"; |
| 267 | private static final String META_METHODS = "metaMethods"; |
| 268 | private static final String METHODS = "methods"; |
| 269 | private static final String PROPERTIES = "properties"; |
| 270 | /** |
| 271 | * Pseudo-property used by the expando DSL to define static members. |
| 272 | */ |
| 273 | public static final String STATIC_QUALIFIER = "static"; |
| 274 | |
| 275 | private final boolean allowChangesAfterInit; |
| 276 | private volatile boolean initialized; |
| 277 | private volatile boolean initCalled; |
| 278 | /** |
| 279 | * Indicates whether this expando meta class is registered in the global registry. |
| 280 | */ |
| 281 | public boolean inRegistry; |
| 282 | private volatile boolean modified; |
| 283 | |
| 284 | private MetaClass myMetaClass; |
| 285 | |
| 286 | private final Lock readLock; |
| 287 | private final Lock writeLock; |
| 288 | { |
| 289 | var rwl = new ReentrantReadWriteLock(); |
| 290 | readLock = rwl.readLock(); |
| 291 | writeLock = rwl.writeLock(); |
| 292 | } |
| 293 | |
| 294 | private final Set<MetaMethod> inheritedMetaMethods = new HashSet<>(); |
| 295 | private final Map<String, MetaProperty> beanPropertyCache = new ConcurrentHashMap<>(16, 0.75f, 1); |
| 296 | private final Map<String, MetaProperty> staticBeanPropertyCache = new ConcurrentHashMap<>(16, 0.75f, 1); |
| 297 | private final Map<MethodKey, MetaMethod> expandoMethods = new ConcurrentHashMap<>(16, 0.75f, 1); |
| 298 | private final Map<String, Object> expandoSubclassMethods = new ConcurrentHashMap<>(16, 0.75f, 1); |
| 299 | private final Map<String, MetaProperty> expandoProperties = new ConcurrentHashMap<>(16, 0.75f, 1); |
| 300 | private ClosureStaticMetaMethod invokeStaticMethodMethod; |
| 301 | private final Set<MixinInMetaClass> mixinClasses = new LinkedHashSet<>(); |
| 302 | |
| 303 | /** |
| 304 | * Creates an expando meta class with explicit registry behaviour and additional methods. |
| 305 | * |
| 306 | * @param theClass the enhanced class |
| 307 | * @param register whether the meta class should be registered globally |
| 308 | * @param allowChangesAfterInit whether mutation is allowed after initialization |
| 309 | * @param add additional meta methods to seed the meta class with |
| 310 | */ |
| 311 | public ExpandoMetaClass(Class theClass, boolean register, boolean allowChangesAfterInit, MetaMethod[] add) { |
| 312 | this(GroovySystem.getMetaClassRegistry(), theClass, register, allowChangesAfterInit, add); |
| 313 | } |
| 314 | |
| 315 | /** |
nothing calls this directly
no outgoing calls
no test coverage detected
searching dependent graphs…