Package org.aspectj.weaver

Source Code of org.aspectj.weaver.MethodDelegateTypeMunger$FieldHostTypeMunger

/* *******************************************************************
* Copyright (c) 2005 Contributors.
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://eclipse.org/legal/epl-v10.html
*
* Contributors:
*     Alexandre Vasseur     initial implementation
* ******************************************************************/

package org.aspectj.weaver;

import java.io.IOException;

import org.aspectj.weaver.patterns.TypePattern;

/**
* Type munger for annotation style ITD declare parents. with an interface AND an implementation. Given the aspect that has a field
* public static Interface fieldI = ... // impl. we will weave in the Interface' methods and delegate to the aspect public static
* field fieldI
*
* Note: this munger DOES NOT handles the interface addition to the target classes - a regular Parent kinded munger must be added in
* coordination.
*/
public class MethodDelegateTypeMunger extends ResolvedTypeMunger {

  private final UnresolvedType aspect;

  private UnresolvedType fieldType;

  /**
   * The mixin implementation (which should have a no-argument constructor)
   */
  private final String implClassName;

  /**
   * Type pattern this munger applies to
   */
  private final TypePattern typePattern;

  /**
   * When created to represent a mixed in method for @DeclareMixin, these hold the signature of the factory method
   */
  private String factoryMethodName;
  private String factoryMethodSignature;

  private int bitflags;
  private static final int REPLACING_EXISTING_METHOD = 0x001;

  /**
   * Construct a new type munger for @AspectJ ITD
   *
   * @param signature
   * @param aspect
   * @param implClassName
   * @param typePattern
   */
  public MethodDelegateTypeMunger(ResolvedMember signature, UnresolvedType aspect, String implClassName, TypePattern typePattern) {
    super(MethodDelegate2, signature);
    this.aspect = aspect;
    this.typePattern = typePattern;
    this.implClassName = implClassName;
    factoryMethodName = "";
    factoryMethodSignature = "";
  }

  public MethodDelegateTypeMunger(ResolvedMember signature, UnresolvedType aspect, String implClassName, TypePattern typePattern,
      String factoryMethodName, String factoryMethodSignature) {
    super(MethodDelegate2, signature);
    this.aspect = aspect;
    this.typePattern = typePattern;
    this.implClassName = implClassName;
    this.factoryMethodName = factoryMethodName;
    this.factoryMethodSignature = factoryMethodSignature;
  }

  public boolean equals(Object other) {
    if (!(other instanceof MethodDelegateTypeMunger)) {
      return false;
    }
    MethodDelegateTypeMunger o = (MethodDelegateTypeMunger) other;
    return ((o.aspect == null) ? (aspect == null) : aspect.equals(o.aspect))
        && ((o.typePattern == null) ? (typePattern == null) : typePattern.equals(o.typePattern))
        && ((o.implClassName == null) ? (implClassName == null) : implClassName.equals(o.implClassName))
        && ((o.fieldType == null ? (fieldType == null) : fieldType.equals(o.fieldType)))
        && ((o.factoryMethodName == null) ? (factoryMethodName == null) : factoryMethodName.equals(o.factoryMethodName))
        && ((o.factoryMethodSignature == null) ? (factoryMethodSignature == null) : factoryMethodSignature
            .equals(o.factoryMethodSignature)) && o.bitflags == bitflags;
  }

  private volatile int hashCode = 0;

  public int hashCode() {
    if (hashCode == 0) {
      int result = 17;
      result = 37 * result + ((aspect == null) ? 0 : aspect.hashCode());
      result = 37 * result + ((typePattern == null) ? 0 : typePattern.hashCode());
      result = 37 * result + ((implClassName == null) ? 0 : implClassName.hashCode());
      result = 37 * result + ((fieldType == null) ? 0 : fieldType.hashCode());
      result = 37 * result + ((factoryMethodName == null) ? 0 : factoryMethodName.hashCode());
      result = 37 * result + ((factoryMethodSignature == null) ? 0 : factoryMethodSignature.hashCode());
      result = 37 * result + bitflags;
      hashCode = result;
    }
    return hashCode;
  }

  public ResolvedMember getDelegate(ResolvedType targetType) {
    return AjcMemberMaker.itdAtDeclareParentsField(targetType, fieldType, aspect);
  }

  public ResolvedMember getDelegateFactoryMethod(World w) {
    ResolvedType aspectType = w.resolve(aspect);
    ResolvedMember[] methods = aspectType.getDeclaredMethods();
    for (int i = 0; i < methods.length; i++) {
      ResolvedMember rm = methods[i];
      if (rm.getName().equals(factoryMethodName) && rm.getSignature().equals(factoryMethodSignature)) {
        return rm;
      }
    }
    return null;
  }

  public String getImplClassName() {
    return implClassName;
  }

  public void write(CompressingDataOutputStream s) throws IOException {
    kind.write(s);
    signature.write(s);
    aspect.write(s);
    s.writeUTF(implClassName);
    typePattern.write(s);
    fieldType.write(s);
    s.writeUTF(factoryMethodName);
    s.writeUTF(factoryMethodSignature);
    s.writeInt(bitflags);
  }

  public static ResolvedTypeMunger readMethod(VersionedDataInputStream s, ISourceContext context, boolean isEnhanced)
      throws IOException {
    ResolvedMemberImpl signature = ResolvedMemberImpl.readResolvedMember(s, context);
    UnresolvedType aspect = UnresolvedType.read(s);
    String implClassName = s.readUTF();
    TypePattern tp = TypePattern.read(s, context);
    MethodDelegateTypeMunger typeMunger = new MethodDelegateTypeMunger(signature, aspect, implClassName, tp);
    UnresolvedType fieldType = null;
    if (isEnhanced) {
      fieldType = UnresolvedType.read(s);
    } else {
      // a guess... that will work in a lot of cases
      fieldType = signature.getDeclaringType();
    }
    typeMunger.setFieldType(fieldType);
    if (isEnhanced) {
      typeMunger.factoryMethodName = s.readUTF();
      typeMunger.factoryMethodSignature = s.readUTF();
      typeMunger.bitflags = s.readInt();
    }
    return typeMunger;
  }

  /**
   * Match based on given type pattern, only classes can be matched
   *
   * @param matchType
   * @param aspectType
   * @return true if match
   */
  public boolean matches(ResolvedType matchType, ResolvedType aspectType) {
    // match only on class
    if (matchType.isEnum() || matchType.isInterface() || matchType.isAnnotation()) {
      return false;
    }

    return typePattern.matchesStatically(matchType);
  }

  /**
   * Needed for reweavable
   *
   * @return true
   */
  public boolean changesPublicSignature() {
    return true;
  }

  public static class FieldHostTypeMunger extends ResolvedTypeMunger {

    private final UnresolvedType aspect;

    /**
     * Type pattern this munger applies to
     */
    private final TypePattern typePattern;

    /**
     * Construct a new type munger for @AspectJ ITD
     *
     * @param field
     * @param aspect
     * @param typePattern
     */
    public FieldHostTypeMunger(ResolvedMember field, UnresolvedType aspect, TypePattern typePattern) {
      super(FieldHost, field);
      this.aspect = aspect;
      this.typePattern = typePattern;
    }

    public boolean equals(Object other) {
      if (!(other instanceof FieldHostTypeMunger)) {
        return false;
      }
      FieldHostTypeMunger o = (FieldHostTypeMunger) other;
      return ((o.aspect == null) ? (aspect == null) : aspect.equals(o.aspect))
          && ((o.typePattern == null) ? (typePattern == null) : typePattern.equals(o.typePattern));
    }

    public int hashCode() {
      int result = 17;
      result = 37 * result + ((aspect == null) ? 0 : aspect.hashCode());
      result = 37 * result + ((typePattern == null) ? 0 : typePattern.hashCode());
      return result;
    }

    public void write(CompressingDataOutputStream s) throws IOException {
      kind.write(s);
      signature.write(s);
      aspect.write(s);
      typePattern.write(s);
    }

    public static ResolvedTypeMunger readFieldHost(VersionedDataInputStream s, ISourceContext context) throws IOException {
      ResolvedMemberImpl signature = ResolvedMemberImpl.readResolvedMember(s, context);
      UnresolvedType aspect = UnresolvedType.read(s);
      TypePattern tp = TypePattern.read(s, context);
      return new FieldHostTypeMunger(signature, aspect, tp);
    }

    /**
     * Match based on given type pattern, only classes can be matched
     *
     * @param matchType
     * @param aspectType
     * @return true if match
     */
    public boolean matches(ResolvedType matchType, ResolvedType aspectType) {
      // match only on class
      if (matchType.isEnum() || matchType.isInterface() || matchType.isAnnotation()) {
        return false;
      }

      return typePattern.matchesStatically(matchType);
    }

    public boolean changesPublicSignature() {
      return false;
    }

    public boolean existsToSupportShadowMunging() {
      return true;
    }
  }

  public void setFieldType(UnresolvedType fieldType) {
    this.fieldType = fieldType;
  }

  public boolean specifiesDelegateFactoryMethod() {
    return factoryMethodName != null && factoryMethodName.length() != 0;
  }

  public String getFactoryMethodName() {
    return factoryMethodName;
  }

  public String getFactoryMethodSignature() {
    return factoryMethodSignature;
  }

  public UnresolvedType getAspect() {
    return aspect;
  }

  public boolean existsToSupportShadowMunging() {
    return true;
  }

  public void tagAsReplacingExistingMethod() {
    bitflags |= REPLACING_EXISTING_METHOD;
  }

  public boolean isReplacingExistingMethod() {
    return (bitflags & REPLACING_EXISTING_METHOD) != 0;
  }
}
TOP

Related Classes of org.aspectj.weaver.MethodDelegateTypeMunger$FieldHostTypeMunger

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.