Package org.aspectj.weaver.patterns

Source Code of org.aspectj.weaver.patterns.HasMemberTypePattern

/* *******************************************************************
* 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:
*   Adrian Colyer      Initial implementation
*   Nieraj Singh
* ******************************************************************/
package org.aspectj.weaver.patterns;

import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.aspectj.bridge.IMessage;
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.CompressingDataOutputStream;
import org.aspectj.weaver.ConcreteTypeMunger;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.Member;
import org.aspectj.weaver.ResolvedMember;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.VersionedDataInputStream;
import org.aspectj.weaver.WeaverMessages;
import org.aspectj.weaver.World;

/**
* @author colyer Matches types that have a certain method / constructor / field Currently only allowed within declare parents and
*         declare @type
*/
public class HasMemberTypePattern extends TypePattern {

  private SignaturePattern signaturePattern;

  public HasMemberTypePattern(SignaturePattern aSignaturePattern) {
    super(false, false);
    this.signaturePattern = aSignaturePattern;
  }

  @Override
  protected boolean matchesExactly(ResolvedType type) {
    if (signaturePattern.getKind() == Member.FIELD) {
      return hasField(type);
    } else {
      return hasMethod(type);
    }
  }

  public ISignaturePattern getSignaturePattern() {
    return signaturePattern;
  }

  private final static String declareAtPrefix = "ajc$declare_at";

  private boolean hasField(ResolvedType type) {
    // TODO what about ITDs
    World world = type.getWorld();
    for (Iterator iter = type.getFields(); iter.hasNext();) {
      Member field = (Member) iter.next();
      if (field.getName().startsWith(declareAtPrefix)) {
        continue;
      }
      if (signaturePattern.matches(field, type.getWorld(), false)) {
        if (field.getDeclaringType().resolve(world) != type) {
          if (Modifier.isPrivate(field.getModifiers())) {
            continue;
          }
        }
        return true;
      }
    }
    return false;
  }

  protected boolean hasMethod(ResolvedType type) {
    // TODO what about ITDs
    World world = type.getWorld();
    for (Iterator<ResolvedMember> iter = type.getMethods(true, true); iter.hasNext();) {
      Member method = (Member) iter.next();
      if (method.getName().startsWith(declareAtPrefix)) {
        continue;
      }
      if (signaturePattern.matches(method, type.getWorld(), false)) {
        if (method.getDeclaringType().resolve(world) != type) {
          if (Modifier.isPrivate(method.getModifiers())) {
            continue;
          }
        }
        return true;
      }
    }
    // try itds before we give up (this doesnt find annotations - the signature returned may not include them)
    List<ConcreteTypeMunger> mungers = type.getInterTypeMungersIncludingSupers();
    for (Iterator<ConcreteTypeMunger> iter = mungers.iterator(); iter.hasNext();) {
      ConcreteTypeMunger munger = iter.next();
      Member member = munger.getSignature();
      if (signaturePattern.matches(member, type.getWorld(), false)) {
        if (!Modifier.isPublic(member.getModifiers())) {
          continue;
        }
        return true;
      }
    }
    return false;
  }

  @Override
  protected boolean matchesExactly(ResolvedType type, ResolvedType annotatedType) {
    return matchesExactly(type);
  }

  @Override
  public FuzzyBoolean matchesInstanceof(ResolvedType type) {
    throw new UnsupportedOperationException("hasmethod/field do not support instanceof matching");
  }

  @Override
  public TypePattern parameterizeWith(Map typeVariableMap, World w) {
    HasMemberTypePattern ret = new HasMemberTypePattern(signaturePattern.parameterizeWith(typeVariableMap, w));
    ret.copyLocationFrom(this);
    return ret;
  }

  @Override
  public TypePattern resolveBindings(IScope scope, Bindings bindings, boolean allowBinding, boolean requireExactType) {
    // check that hasmember type patterns are allowed!
    if (!scope.getWorld().isHasMemberSupportEnabled()) {
      String msg = WeaverMessages.format(WeaverMessages.HAS_MEMBER_NOT_ENABLED, this.toString());
      scope.message(IMessage.ERROR, this, msg);
    }
    signaturePattern.resolveBindings(scope, bindings);
    return this;
  }

  @Override
  public boolean equals(Object obj) {
    if (!(obj instanceof HasMemberTypePattern)) {
      return false;
    }
    if (this == obj) {
      return true;
    }
    return signaturePattern.equals(((HasMemberTypePattern) obj).signaturePattern);
  }

  @Override
  public int hashCode() {
    return signaturePattern.hashCode();
  }

  @Override
  public String toString() {
    StringBuffer buff = new StringBuffer();
    if (signaturePattern.getKind() == Member.FIELD) {
      buff.append("hasfield(");
    } else {
      buff.append("hasmethod(");
    }
    buff.append(signaturePattern.toString());
    buff.append(")");
    return buff.toString();
  }

  @Override
  public void write(CompressingDataOutputStream s) throws IOException {
    s.writeByte(TypePattern.HAS_MEMBER);
    signaturePattern.write(s);
    writeLocation(s);
  }

  public static TypePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException {
    SignaturePattern sp = SignaturePattern.read(s, context);
    HasMemberTypePattern ret = new HasMemberTypePattern(sp);
    ret.readLocation(context, s);
    return ret;
  }

  @Override
  public Object accept(PatternNodeVisitor visitor, Object data) {
    return visitor.visit(this, data);
  }

}
TOP

Related Classes of org.aspectj.weaver.patterns.HasMemberTypePattern

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.