Package org.eclipse.core.internal.expressions

Source Code of org.eclipse.core.internal.expressions.TypeExtension

/*******************************************************************************
* Copyright (c) 2000, 2006 IBM Corporation and others.
* 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://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.core.internal.expressions;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;

import org.eclipse.core.expressions.IPropertyTester;
import org.eclipse.core.expressions.PropertyTester;

public class TypeExtension {
 
  private static final TypeExtension[] EMPTY_TYPE_EXTENSION_ARRAY= new TypeExtension[0];

  /* a special property tester instance that is used to signal that method searching has to continue */
  /* package */ static final IPropertyTester CONTINUE= new IPropertyTester() {
    public boolean handles(String namespace, String method) {
      return false;
    }
    public boolean isInstantiated() {
      return true;
    }
    public boolean isDeclaringPluginActive() {
      return true;
    }
    public IPropertyTester instantiate() {
      return this;
    }
    public boolean test(Object receiver, String method, Object[] args, Object expectedValue) {
      return false;
    }
  };
   
  /* a special type extension instance that marks the end of an evaluation chain */
  private static final TypeExtension END_POINT= new TypeExtension() {
    /* package */ IPropertyTester findTypeExtender(TypeExtensionManager manager, String namespace, String name, boolean staticMethod, boolean forcePluginActivation) throws CoreException {
      return CONTINUE;
    }
  };
   
  /* the type this extension is extending */
  private Class fType;
  /* the list of associated extenders */
  private IPropertyTester[] fExtenders;
 
  /* the extension associated with <code>fType</code>'s super class */
  private TypeExtension fExtends;
  /* the extensions associated with <code>fTypes</code>'s interfaces */
  private TypeExtension[] fImplements;
 
  private TypeExtension() {
    // special constructor to create the CONTINUE instance
  }
 
  /* package */ TypeExtension(Class type) {
    Assert.isNotNull(type);
    fType= type;
  }
 
  /* package */ IPropertyTester findTypeExtender(TypeExtensionManager manager, String namespace, String method, boolean staticMethod, boolean forcePluginActivation) throws CoreException {
    if (fExtenders == null) {
      fExtenders= manager.loadTesters(fType);
    }
    IPropertyTester result;
   
    // handle extenders associated with this type extender
    for (int i= 0; i < fExtenders.length; i++) {
      IPropertyTester extender= fExtenders[i];
      if (extender == null || !extender.handles(namespace, method))
        continue;
      if (extender.isInstantiated()) {
        // There is no need to check for an active plug-in here. If a plug-in
        // gets uninstalled we receive an registry event which will flush the whole
        // type extender cache and will reinstantiate the testers. However Bundle#stop
        // isn't handled by this. According to bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=130338
        // we don't have to support stop in 3.2. If we have to in the future we have to
        // reactivate the stopped plug-in if we are in forcePluginActivation mode.
        return extender;
      } else {
        if (extender.isDeclaringPluginActive() || forcePluginActivation) {
          try {
            PropertyTesterDescriptor descriptor= (PropertyTesterDescriptor)extender;
            IPropertyTester inst= descriptor.instantiate();
            ((PropertyTester)inst).internalInitialize(descriptor);
            fExtenders[i]= extender= inst;
            return extender;
          } catch (CoreException e) {
            fExtenders[i]= null;
            throw e;
          } catch (ClassCastException e) {
            fExtenders[i]= null;
            throw new CoreException(new ExpressionStatus(
              ExpressionStatus.TYPE_EXTENDER_INCORRECT_TYPE,
              ExpressionMessages.TypeExtender_incorrectType, 
              e));
          }
        } else {
          return extender;
        }
      }
    }
   
    // there is no inheritance for static methods
    if (staticMethod)
      return CONTINUE;
   
    // handle extends chain
    if (fExtends == null) {
      Class superClass= fType.getSuperclass();
      if (superClass != null) {
        fExtends= manager.get(superClass);
      } else {
        fExtends= END_POINT;
      }
    }
    result= fExtends.findTypeExtender(manager, namespace, method, staticMethod, forcePluginActivation);
    if (result != CONTINUE)
      return result;
   
    // handle implements chain
    if (fImplements == null) {
      Class[] interfaces= fType.getInterfaces();
      if (interfaces.length == 0) {
        fImplements= EMPTY_TYPE_EXTENSION_ARRAY;
      } else {
        fImplements= new TypeExtension[interfaces.length];
        for (int i= 0; i < interfaces.length; i++) {
          fImplements[i]= manager.get(interfaces[i]);
        }       
      }
    }
    for (int i= 0; i < fImplements.length; i++) {
      result= fImplements[i].findTypeExtender(manager, namespace, method, staticMethod, forcePluginActivation);
      if (result != CONTINUE)
        return result;
    }
    return CONTINUE;
  }
}
TOP

Related Classes of org.eclipse.core.internal.expressions.TypeExtension

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.