/*
 * Copyright 2014 - 2019 Rafael Winterhalter
 *
 * 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 net.bytebuddy.dynamic.scaffold;

import net.bytebuddy.build.HashCodeAndEqualsPlugin;
import net.bytebuddy.description.field.FieldDescription;
import net.bytebuddy.description.field.FieldList;
import net.bytebuddy.description.type.TypeDefinition;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;

import static net.bytebuddy.matcher.ElementMatchers.*;

A field locator offers an interface for locating a field that is declared by a specified type.
/** * A field locator offers an interface for locating a field that is declared by a specified type. */
public interface FieldLocator {
Locates a field with the given name and throws an exception if no such type exists.
Params:
  • name – The name of the field to locate.
Returns:A resolution for a field lookup.
/** * Locates a field with the given name and throws an exception if no such type exists. * * @param name The name of the field to locate. * @return A resolution for a field lookup. */
Resolution locate(String name);
Locates a field with the given name and type and throws an exception if no such type exists.
Params:
  • name – The name of the field to locate.
  • type – The type fo the field to locate.
Returns:A resolution for a field lookup.
/** * Locates a field with the given name and type and throws an exception if no such type exists. * * @param name The name of the field to locate. * @param type The type fo the field to locate. * @return A resolution for a field lookup. */
Resolution locate(String name, TypeDescription type);
A resolution for a field lookup.
/** * A resolution for a field lookup. */
interface Resolution {
Returns true if a field was located.
Returns:true if a field was located.
/** * Returns {@code true} if a field was located. * * @return {@code true} if a field was located. */
boolean isResolved();
Returns the field description if a field was located. This method must only be called if this resolution was actually resolved.
Returns:The located field.
/** * Returns the field description if a field was located. This method must only be called if * this resolution was actually resolved. * * @return The located field. */
FieldDescription getField();
An illegal resolution.
/** * An illegal resolution. */
enum Illegal implements Resolution {
The singleton instance.
/** * The singleton instance. */
INSTANCE;
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isResolved() { return false; }
{@inheritDoc}
/** * {@inheritDoc} */
public FieldDescription getField() { throw new IllegalStateException("Could not locate field"); } }
A simple implementation for a field resolution.
/** * A simple implementation for a field resolution. */
@HashCodeAndEqualsPlugin.Enhance class Simple implements Resolution {
A description of the located field.
/** * A description of the located field. */
private final FieldDescription fieldDescription;
Creates a new simple resolution for a field.
Params:
  • fieldDescription – A description of the located field.
/** * Creates a new simple resolution for a field. * * @param fieldDescription A description of the located field. */
protected Simple(FieldDescription fieldDescription) { this.fieldDescription = fieldDescription; }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isResolved() { return true; }
{@inheritDoc}
/** * {@inheritDoc} */
public FieldDescription getField() { return fieldDescription; } } }
A factory for creating a FieldLocator.
/** * A factory for creating a {@link FieldLocator}. */
interface Factory {
Creates a field locator for a given type.
Params:
  • typeDescription – The type for which to create a field locator.
Returns:A suitable field locator.
/** * Creates a field locator for a given type. * * @param typeDescription The type for which to create a field locator. * @return A suitable field locator. */
FieldLocator make(TypeDescription typeDescription); }
A field locator that never discovers a field.
/** * A field locator that never discovers a field. */
enum NoOp implements FieldLocator, Factory {
The singleton instance.
/** * The singleton instance. */
INSTANCE;
{@inheritDoc}
/** * {@inheritDoc} */
public FieldLocator make(TypeDescription typeDescription) { return this; }
{@inheritDoc}
/** * {@inheritDoc} */
public Resolution locate(String name) { return Resolution.Illegal.INSTANCE; }
{@inheritDoc}
/** * {@inheritDoc} */
public Resolution locate(String name, TypeDescription type) { return Resolution.Illegal.INSTANCE; } }
An abstract base implementation of a field locator.
/** * An abstract base implementation of a field locator. */
@HashCodeAndEqualsPlugin.Enhance abstract class AbstractBase implements FieldLocator {
The type accessing the field.
/** * The type accessing the field. */
protected final TypeDescription accessingType;
Creates a new field locator.
Params:
  • accessingType – The type accessing the field.
/** * Creates a new field locator. * * @param accessingType The type accessing the field. */
protected AbstractBase(TypeDescription accessingType) { this.accessingType = accessingType; }
{@inheritDoc}
/** * {@inheritDoc} */
public Resolution locate(String name) { FieldList<?> candidates = locate(named(name).and(isVisibleTo(accessingType))); return candidates.size() == 1 ? new Resolution.Simple(candidates.getOnly()) : Resolution.Illegal.INSTANCE; }
{@inheritDoc}
/** * {@inheritDoc} */
public Resolution locate(String name, TypeDescription type) { FieldList<?> candidates = locate(named(name).and(fieldType(type)).and(isVisibleTo(accessingType))); return candidates.size() == 1 ? new Resolution.Simple(candidates.getOnly()) : Resolution.Illegal.INSTANCE; }
Locates fields that match the given matcher.
Params:
  • matcher – The matcher that identifies fields of interest.
Returns:A list of fields that match the specified matcher.
/** * Locates fields that match the given matcher. * * @param matcher The matcher that identifies fields of interest. * @return A list of fields that match the specified matcher. */
protected abstract FieldList<?> locate(ElementMatcher<? super FieldDescription> matcher); }
A field locator that only looks up fields that are declared by a specific type.
/** * A field locator that only looks up fields that are declared by a specific type. */
@HashCodeAndEqualsPlugin.Enhance class ForExactType extends AbstractBase {
The type for which to look up fields.
/** * The type for which to look up fields. */
private final TypeDescription typeDescription;
Creates a new field locator for locating fields from a declared type.
Params:
  • typeDescription – The type for which to look up fields that is also providing the accessing type.
/** * Creates a new field locator for locating fields from a declared type. * * @param typeDescription The type for which to look up fields that is also providing the accessing type. */
public ForExactType(TypeDescription typeDescription) { this(typeDescription, typeDescription); }
Creates a new field locator for locating fields from a declared type.
Params:
  • typeDescription – The type for which to look up fields.
  • accessingType – The accessing type.
/** * Creates a new field locator for locating fields from a declared type. * * @param typeDescription The type for which to look up fields. * @param accessingType The accessing type. */
public ForExactType(TypeDescription typeDescription, TypeDescription accessingType) { super(accessingType); this.typeDescription = typeDescription; } @Override protected FieldList<?> locate(ElementMatcher<? super FieldDescription> matcher) { return typeDescription.getDeclaredFields().filter(matcher); }
A factory for creating a ForExactType.
/** * A factory for creating a {@link ForExactType}. */
@HashCodeAndEqualsPlugin.Enhance public static class Factory implements FieldLocator.Factory {
The type for which to locate a field.
/** * The type for which to locate a field. */
private final TypeDescription typeDescription;
Creates a new factory for a field locator that locates a field for an exact type.
Params:
  • typeDescription – The type for which to locate a field.
/** * Creates a new factory for a field locator that locates a field for an exact type. * * @param typeDescription The type for which to locate a field. */
public Factory(TypeDescription typeDescription) { this.typeDescription = typeDescription; }
{@inheritDoc}
/** * {@inheritDoc} */
public FieldLocator make(TypeDescription typeDescription) { return new ForExactType(this.typeDescription, typeDescription); } } }
A field locator that looks up fields that are declared within a class's class hierarchy.
/** * A field locator that looks up fields that are declared within a class's class hierarchy. */
@HashCodeAndEqualsPlugin.Enhance class ForClassHierarchy extends AbstractBase {
The type for which to look up a field within its class hierarchy.
/** * The type for which to look up a field within its class hierarchy. */
private final TypeDescription typeDescription;
Creates a field locator that looks up fields that are declared within a class's class hierarchy.
Params:
  • typeDescription – The type for which to look up a field within its class hierarchy which is also the accessing type.
/** * Creates a field locator that looks up fields that are declared within a class's class hierarchy. * * @param typeDescription The type for which to look up a field within its class hierarchy which is also the accessing type. */
public ForClassHierarchy(TypeDescription typeDescription) { this(typeDescription, typeDescription); }
Creates a field locator that looks up fields that are declared within a class's class hierarchy.
Params:
  • typeDescription – The type for which to look up a field within its class hierarchy.
  • accessingType – The accessing type.
/** * Creates a field locator that looks up fields that are declared within a class's class hierarchy. * * @param typeDescription The type for which to look up a field within its class hierarchy. * @param accessingType The accessing type. */
public ForClassHierarchy(TypeDescription typeDescription, TypeDescription accessingType) { super(accessingType); this.typeDescription = typeDescription; } @Override protected FieldList<?> locate(ElementMatcher<? super FieldDescription> matcher) { for (TypeDefinition typeDefinition : typeDescription) { FieldList<?> candidates = typeDefinition.getDeclaredFields().filter(matcher); if (!candidates.isEmpty()) { return candidates; } } return new FieldList.Empty<FieldDescription>(); }
A factory for creating a ForClassHierarchy.
/** * A factory for creating a {@link ForClassHierarchy}. */
public enum Factory implements FieldLocator.Factory {
The singleton instance.
/** * The singleton instance. */
INSTANCE;
{@inheritDoc}
/** * {@inheritDoc} */
public FieldLocator make(TypeDescription typeDescription) { return new ForClassHierarchy(typeDescription); } } }
A field locator that only locates fields in the top-level type.
/** * A field locator that only locates fields in the top-level type. */
class ForTopLevelType extends AbstractBase {
Creates a new type locator for a top-level type.
Params:
  • typeDescription – The type to access.
/** * Creates a new type locator for a top-level type. * * @param typeDescription The type to access. */
protected ForTopLevelType(TypeDescription typeDescription) { super(typeDescription); } @Override protected FieldList<?> locate(ElementMatcher<? super FieldDescription> matcher) { return accessingType.getDeclaredFields().filter(matcher); }
A factory for locating a field in a top-level type.
/** * A factory for locating a field in a top-level type. */
public enum Factory implements FieldLocator.Factory {
The singleton instance.
/** * The singleton instance. */
INSTANCE;
{@inheritDoc}
/** * {@inheritDoc} */
public FieldLocator make(TypeDescription typeDescription) { return new ForTopLevelType(typeDescription); } } } }