| /******************************************************************************* |
| * 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.ui.internal; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.core.runtime.IConfigurationElement; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.ui.IActionFilter; |
| import org.eclipse.ui.internal.util.BundleUtility; |
| import org.eclipse.ui.internal.util.Util; |
| import org.osgi.framework.Bundle; |
| |
| /** |
| * An ActionExpression is used to evaluate the enablement / visibility criteria |
| * for an action. |
| */ |
| public class ActionExpression { |
| |
| private static abstract class AbstractExpression { |
| |
| /** |
| * The hash code for this object. This value is computed lazily, and |
| * marked as invalid when one of the values on which it is based |
| * changes. |
| */ |
| protected transient int expressionHashCode = HASH_CODE_NOT_COMPUTED; |
| |
| /** |
| * Extract the object class tests from the expression. This allows |
| * clients (e.g. the decorator manager) to handle object class testing |
| * in a more optimized way. This method extracts the objectClass test |
| * from the expression and returns the object classes. The expression is |
| * not changed and a <code>null</code> is returned if no object class |
| * is found. |
| * |
| * @return String[] the object class names or <code>null</code> if |
| * none was found. |
| */ |
| public String[] extractObjectClasses() { |
| return null; |
| } |
| |
| /** |
| * Returns whether the expression is valid for the given object. |
| * |
| * @param object |
| * the object to validate against (can be <code>null</code>) |
| * @return boolean whether the expression is valid for the object. |
| */ |
| public abstract boolean isEnabledFor(Object object); |
| |
| /** |
| * Returns whether or not the receiver is potentially valid for the |
| * object via just the extension type. Currently the only supported |
| * expression type is <code>EXP_TYPE_OBJECT_CLASS</code>. |
| * |
| * @param object |
| * the object to validate against (can be <code>null</code>) |
| * @param expressionType |
| * the expression type to consider |
| * @return boolean whether the expression is potentially valid for the |
| * object. |
| */ |
| public boolean isEnabledForExpression(Object object, |
| String expressionType) { |
| return false; |
| } |
| |
| /** |
| * Return the value of the expression type that the receiver is enabled |
| * for. If the receiver is not enabled for the expressionType then |
| * return <code>null</code>. |
| * |
| * @param expressionType |
| * the expression type to consider |
| * @return Collection of String if there are values for this expression |
| * or <code>null</code> if this is not possible in the |
| * receiver or any of it's children |
| */ |
| public Collection valuesForExpression(String expressionType) { |
| return null; |
| } |
| } |
| |
| private static class AndExpression extends CompositeExpression { |
| |
| /** |
| * Creates and populates the expression from the attributes and sub- |
| * elements of the configuration element. |
| * |
| * @param element. |
| * The element that will be used to determine the expressions |
| * for And. |
| * @throws IllegalStateException |
| * if the expression tag is not defined in the schema. |
| * @see org.eclipse.ui\schema\commonExpression.mxsd |
| */ |
| public AndExpression(IConfigurationElement element) |
| throws IllegalStateException { |
| super(element); |
| } |
| |
| public final boolean equals(final Object object) { |
| if (object instanceof AndExpression) { |
| final AndExpression that = (AndExpression) object; |
| return Util.equals(this.list, that.list); |
| } |
| |
| return false; |
| } |
| |
| /* |
| * (non-Javadoc) Method declared on AbstractExpression. |
| */ |
| public boolean isEnabledFor(Object object) { |
| Iterator iter = list.iterator(); |
| while (iter.hasNext()) { |
| AbstractExpression expr = (AbstractExpression) iter.next(); |
| if (!expr.isEnabledFor(object)) { |
| return false; |
| } |
| } |
| return true; |
| } |
| } |
| |
| private static abstract class CompositeExpression extends |
| AbstractExpression { |
| protected ArrayList list; |
| |
| /** |
| * Creates and populates the expression from the attributes and sub- |
| * elements of the configuration element. |
| * |
| * @param element |
| * The composite element we will create the expression from. |
| * @throws IllegalStateException |
| * if the expression tag is not defined in the schema. |
| * @see org.eclipse.ui\schema\commonExpression.mxsd |
| */ |
| public CompositeExpression(IConfigurationElement element) |
| throws IllegalStateException { |
| super(); |
| |
| IConfigurationElement[] children = element.getChildren(); |
| if (children.length == 0) { |
| throw new IllegalStateException( |
| "Composite expression cannot be empty"); //$NON-NLS-1$ |
| } |
| |
| list = new ArrayList(children.length); |
| for (int i = 0; i < children.length; i++) { |
| String tag = children[i].getName(); |
| AbstractExpression expr = createExpression(children[i]); |
| if (EXP_TYPE_OBJECT_CLASS.equals(tag)) { |
| list.add(0, expr); |
| } else { |
| list.add(expr); |
| } |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.internal.ActionExpression.AbstractExpression#extractObjectClasses() |
| */ |
| public String[] extractObjectClasses() { |
| Iterator iterator = list.iterator(); |
| List classNames = null; |
| while (iterator.hasNext()) { |
| AbstractExpression next = (AbstractExpression) iterator.next(); |
| String[] objectClasses = next.extractObjectClasses(); |
| if (objectClasses != null) { |
| if (classNames == null) { |
| classNames = new ArrayList(); |
| } |
| for (int i = 0; i < objectClasses.length; i++) { |
| classNames.add(objectClasses[i]); |
| } |
| } |
| } |
| if (classNames == null) { |
| return null; |
| } |
| |
| String[] returnValue = new String[classNames.size()]; |
| classNames.toArray(returnValue); |
| return returnValue; |
| } |
| |
| /** |
| * Computes the hash code for this object based on the id. |
| * |
| * @return The hash code for this object. |
| */ |
| public final int hashCode() { |
| if (expressionHashCode == HASH_CODE_NOT_COMPUTED) { |
| expressionHashCode = HASH_INITIAL * HASH_FACTOR + Util.hashCode(list); |
| if (expressionHashCode == HASH_CODE_NOT_COMPUTED) { |
| expressionHashCode++; |
| } |
| } |
| return expressionHashCode; |
| } |
| |
| /* |
| * (non-Javadoc) Method declared on AbstractExpression. |
| */ |
| public boolean isEnabledForExpression(Object object, |
| String expressionType) { |
| Iterator iterator = list.iterator(); |
| while (iterator.hasNext()) { |
| AbstractExpression next = (AbstractExpression) iterator.next(); |
| if (next.isEnabledForExpression(object, expressionType)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.internal.ActionExpression.AbstractExpression#valuesForExpression(java.lang.String) |
| */ |
| public Collection valuesForExpression(String expressionType) { |
| Iterator iterator = list.iterator(); |
| Collection allValues = null; |
| while (iterator.hasNext()) { |
| AbstractExpression next = (AbstractExpression) iterator.next(); |
| Collection values = next.valuesForExpression(expressionType); |
| if (values != null) { |
| if (allValues == null) { |
| allValues = values; |
| } else { |
| allValues.addAll(values); |
| } |
| } |
| |
| } |
| return allValues; |
| } |
| } |
| |
| private static class NotExpression extends SingleExpression { |
| |
| /** |
| * Creates and populates the expression from the attributes and sub- |
| * elements of the configuration element. |
| * |
| * @param element |
| * The element that will be used to create the definition for |
| * the receiver. |
| * @throws IllegalStateException |
| * if the expression tag is not defined in the schema. |
| * @see org.eclipse.ui\schema\commonExpression.mxsd |
| */ |
| public NotExpression(IConfigurationElement element) |
| throws IllegalStateException { |
| super(element); |
| } |
| |
| /* |
| * (non-Javadoc) Method declared on AbstractExpression. |
| */ |
| public boolean isEnabledFor(Object object) { |
| return !super.isEnabledFor(object); |
| } |
| } |
| |
| private static class ObjectClassExpression extends AbstractExpression { |
| private String className; |
| |
| private boolean extracted; |
| |
| /** |
| * Creates and populates the expression from the attributes and sub- |
| * elements of the configuration element. |
| * |
| * @param element. |
| * The element that will be used to determine the expressions |
| * for objectClass. |
| * @throws IllegalStateException |
| * if the expression tag is not defined in the schema. |
| * @see org.eclipse.ui\schema\commonExpression.mxsd |
| */ |
| public ObjectClassExpression(IConfigurationElement element) |
| throws IllegalStateException { |
| super(); |
| |
| className = element.getAttribute(ATT_NAME); |
| if (className == null) { |
| throw new IllegalStateException( |
| "Object class expression missing name attribute"); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Create an ObjectClass expression based on the className. Added for |
| * backwards compatibility. |
| * |
| * @param className |
| */ |
| public ObjectClassExpression(String className) { |
| super(); |
| |
| if (className != null) { |
| this.className = className; |
| } else { |
| throw new IllegalStateException( |
| "Object class expression must have class name"); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Check the interfaces the whole way up. If one of them matches |
| * className return <code>true</code>. |
| * |
| * @param interfaceToCheck |
| * The interface whose name we are testing against. |
| * @return <code>true</code> if one of the interfaces in the hierarchy |
| * matches className, <code>false</code> otherwise. |
| */ |
| private boolean checkInterfaceHierarchy(Class interfaceToCheck) { |
| if (interfaceToCheck.getName().equals(className)) { |
| return true; |
| } |
| Class[] superInterfaces = interfaceToCheck.getInterfaces(); |
| for (int i = 0; i < superInterfaces.length; i++) { |
| if (checkInterfaceHierarchy(superInterfaces[i])) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| public final boolean equals(final Object object) { |
| if (object instanceof ObjectClassExpression) { |
| final ObjectClassExpression that = (ObjectClassExpression) object; |
| return Util.equals(this.className, that.className) |
| && Util.equals(this.extracted, that.extracted); |
| } |
| |
| return false; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.internal.ActionExpression.AbstractExpression#extractObjectClasses() |
| */ |
| public String[] extractObjectClasses() { |
| extracted = true; |
| return new String[] { className }; |
| } |
| |
| /** |
| * Computes the hash code for this object based on the id. |
| * |
| * @return The hash code for this object. |
| */ |
| public final int hashCode() { |
| if (expressionHashCode == HASH_CODE_NOT_COMPUTED) { |
| expressionHashCode = HASH_INITIAL * HASH_FACTOR |
| + Util.hashCode(className); |
| expressionHashCode = expressionHashCode * HASH_FACTOR + Util.hashCode(extracted); |
| if (expressionHashCode == HASH_CODE_NOT_COMPUTED) { |
| expressionHashCode++; |
| } |
| } |
| return expressionHashCode; |
| } |
| |
| /* |
| * (non-Javadoc) Method declared on AbstractExpression. |
| */ |
| public boolean isEnabledFor(Object object) { |
| if (object == null) { |
| return false; |
| } |
| if (extracted) { |
| return true; |
| } |
| |
| Class clazz = object.getClass(); |
| while (clazz != null) { |
| // test the class itself |
| if (clazz.getName().equals(className)) { |
| return true; |
| } |
| |
| // test all the interfaces the class implements |
| Class[] interfaces = clazz.getInterfaces(); |
| for (int i = 0; i < interfaces.length; i++) { |
| if (checkInterfaceHierarchy(interfaces[i])) { |
| return true; |
| } |
| } |
| |
| // get the superclass |
| clazz = clazz.getSuperclass(); |
| } |
| |
| return false; |
| } |
| |
| /* |
| * (non-Javadoc) Method declared on AbstractExpression. |
| */ |
| public boolean isEnabledForExpression(Object object, |
| String expressionType) { |
| if (expressionType.equals(EXP_TYPE_OBJECT_CLASS)) { |
| return isEnabledFor(object); |
| } |
| return false; |
| } |
| } |
| |
| private static class ObjectStateExpression extends AbstractExpression { |
| private String name; |
| |
| private String value; |
| |
| /** |
| * Creates and populates the expression from the attributes and sub- |
| * elements of the configuration element. |
| * |
| * @param element. |
| * The element that will be used to determine the expressions |
| * for objectState. |
| * @throws IllegalStateException |
| * if the expression tag is not defined in the schema. |
| * @see org.eclipse.ui\schema\commonExpression.mxsd |
| */ |
| public ObjectStateExpression(IConfigurationElement element) |
| throws IllegalStateException { |
| super(); |
| |
| name = element.getAttribute(ATT_NAME); |
| value = element.getAttribute(ATT_VALUE); |
| if (name == null || value == null) { |
| throw new IllegalStateException( |
| "Object state expression missing attribute"); //$NON-NLS-1$ |
| } |
| } |
| |
| public final boolean equals(final Object object) { |
| if (object instanceof ObjectStateExpression) { |
| final ObjectStateExpression that = (ObjectStateExpression) object; |
| return Util.equals(this.name, that.name) |
| && Util.equals(this.value, that.value); |
| } |
| |
| return false; |
| } |
| |
| private IActionFilter getActionFilter(Object object) { |
| return (IActionFilter)Util.getAdapter(object, IActionFilter.class); |
| } |
| |
| /** |
| * Computes the hash code for this object based on the id. |
| * |
| * @return The hash code for this object. |
| */ |
| public final int hashCode() { |
| if (expressionHashCode == HASH_CODE_NOT_COMPUTED) { |
| expressionHashCode = HASH_INITIAL * HASH_FACTOR + Util.hashCode(name); |
| expressionHashCode = expressionHashCode * HASH_FACTOR + Util.hashCode(value); |
| if (expressionHashCode == HASH_CODE_NOT_COMPUTED) { |
| expressionHashCode++; |
| } |
| } |
| return expressionHashCode; |
| } |
| |
| /* |
| * (non-Javadoc) Method declared on AbstractExpression. |
| */ |
| public boolean isEnabledFor(Object object) { |
| if (object == null) { |
| return false; |
| } |
| |
| // Try out the object first. |
| if (preciselyMatches(object)) { |
| return true; |
| } |
| |
| // Try out the underlying resource. |
| Class resourceClass = LegacyResourceSupport.getResourceClass(); |
| if (resourceClass == null) { |
| return false; |
| } |
| |
| if (resourceClass.isInstance(object)) { |
| return false; |
| } |
| |
| Object res = Util.getAdapter(object, resourceClass); |
| if (res == null) { |
| return false; |
| } |
| |
| return preciselyMatches(res); |
| |
| } |
| |
| private boolean preciselyMatches(Object object) { |
| // Get the action filter. |
| IActionFilter filter = getActionFilter(object); |
| if (filter == null) { |
| return false; |
| } |
| |
| // Run the action filter. |
| return filter.testAttribute(object, name, value); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.internal.ActionExpression.AbstractExpression#valuesForExpression(java.lang.String) |
| */ |
| public Collection valuesForExpression(String expressionType) { |
| if (expressionType.equals(name)) { |
| Collection returnValue = new HashSet(); |
| returnValue.add(value); |
| return returnValue; |
| } |
| return null; |
| } |
| |
| } |
| |
| private static class OrExpression extends CompositeExpression { |
| |
| /** |
| * Creates and populates the expression from the attributes and sub- |
| * elements of the configuration element. |
| * |
| * @param element. |
| * The element that will be used to determine the expressions |
| * for Or. |
| * @throws IllegalStateException |
| * if the expression tag is not defined in the schema. |
| * @see org.eclipse.ui\schema\commonExpression.mxsd |
| */ |
| public OrExpression(IConfigurationElement element) |
| throws IllegalStateException { |
| super(element); |
| } |
| |
| public final boolean equals(final Object object) { |
| if (object instanceof OrExpression) { |
| final OrExpression that = (OrExpression) object; |
| return Util.equals(this.list, that.list); |
| } |
| |
| return false; |
| } |
| |
| /* |
| * (non-Javadoc) Method declared on AbstractExpression. |
| */ |
| public boolean isEnabledFor(Object object) { |
| Iterator iter = list.iterator(); |
| while (iter.hasNext()) { |
| AbstractExpression expr = (AbstractExpression) iter.next(); |
| if (expr.isEnabledFor(object)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| } |
| |
| private static class PluginStateExpression extends AbstractExpression { |
| private String id; |
| |
| private String value; |
| |
| /** |
| * Creates and populates the expression from the attributes and sub- |
| * elements of the configuration element. |
| * |
| * @param element. |
| * The element that will be used to determine the expressions |
| * for pluginState. |
| * @throws IllegalStateException |
| * if the expression tag is not defined in the schema. |
| * @see org.eclipse.ui\schema\commonExpression.mxsd |
| */ |
| public PluginStateExpression(IConfigurationElement element) |
| throws IllegalStateException { |
| super(); |
| |
| id = element.getAttribute(ATT_ID); |
| value = element.getAttribute(ATT_VALUE); |
| if (id == null || value == null) { |
| throw new IllegalStateException( |
| "Plugin state expression missing attribute"); //$NON-NLS-1$ |
| } |
| } |
| |
| public final boolean equals(final Object object) { |
| if (object instanceof PluginStateExpression) { |
| final PluginStateExpression that = (PluginStateExpression) object; |
| return Util.equals(this.id, that.id) |
| && Util.equals(this.value, that.value); |
| } |
| |
| return false; |
| } |
| |
| /** |
| * Computes the hash code for this object based on the id. |
| * |
| * @return The hash code for this object. |
| */ |
| public final int hashCode() { |
| if (expressionHashCode == HASH_CODE_NOT_COMPUTED) { |
| expressionHashCode = HASH_INITIAL * HASH_FACTOR + Util.hashCode(id); |
| expressionHashCode = expressionHashCode * HASH_FACTOR + Util.hashCode(value); |
| if (expressionHashCode == HASH_CODE_NOT_COMPUTED) { |
| expressionHashCode++; |
| } |
| } |
| return expressionHashCode; |
| } |
| |
| /* |
| * (non-Javadoc) Method declared on AbstractExpression. |
| */ |
| public boolean isEnabledFor(Object object) { |
| Bundle bundle = Platform.getBundle(id); |
| if (!BundleUtility.isReady(bundle)) { |
| return false; |
| } |
| if (value.equals(PLUGIN_INSTALLED)) { |
| return true; |
| } |
| if (value.equals(PLUGIN_ACTIVATED)) { |
| return BundleUtility.isActivated(bundle); |
| } |
| return false; |
| } |
| } |
| |
| private static class SingleExpression extends AbstractExpression { |
| private AbstractExpression child; |
| |
| /** |
| * Create a single expression from the abstract definition. |
| * |
| * @param expression |
| * The expression that will be the child of the new single |
| * expression. |
| * @throws IllegalStateException |
| * if the expression tag is not defined in the schema. |
| * @see org.eclipse.ui\schema\commonExpression.mxsd |
| */ |
| public SingleExpression(AbstractExpression expression) |
| throws IllegalStateException { |
| super(); |
| |
| if (expression != null) { |
| child = expression; |
| } else { |
| throw new IllegalStateException( |
| "Single expression must contain 1 expression"); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Creates and populates the expression from the attributes and sub- |
| * elements of the configuration element. |
| * |
| * @param element |
| * The element to create the expression from. |
| * @throws IllegalStateException |
| * if the expression tag is not defined in the schema. |
| * @see org.eclipse.ui\schema\commonExpression.mxsd |
| */ |
| public SingleExpression(IConfigurationElement element) |
| throws IllegalStateException { |
| super(); |
| |
| IConfigurationElement[] children = element.getChildren(); |
| if (children.length != 1) { |
| throw new IllegalStateException( |
| "Single expression does not contain only 1 expression"); //$NON-NLS-1$ |
| } |
| child = createExpression(children[0]); |
| } |
| |
| public final boolean equals(final Object object) { |
| if (object instanceof SingleExpression) { |
| final SingleExpression that = (SingleExpression) object; |
| return Util.equals(this.child, that.child); |
| } |
| |
| return false; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.internal.ActionExpression.AbstractExpression#extractObjectClasses() |
| */ |
| public String[] extractObjectClasses() { |
| return child.extractObjectClasses(); |
| } |
| |
| /** |
| * Computes the hash code for this object based on the id. |
| * |
| * @return The hash code for this object. |
| */ |
| public final int hashCode() { |
| if (expressionHashCode == HASH_CODE_NOT_COMPUTED) { |
| expressionHashCode = HASH_INITIAL * HASH_FACTOR + Util.hashCode(child); |
| if (expressionHashCode == HASH_CODE_NOT_COMPUTED) { |
| expressionHashCode++; |
| } |
| } |
| return expressionHashCode; |
| } |
| |
| /* |
| * (non-Javadoc) Method declared on AbstractExpression. |
| */ |
| public boolean isEnabledFor(Object object) { |
| return child.isEnabledFor(object); |
| } |
| |
| /* |
| * (non-Javadoc) Method declared on AbstractExpression. |
| */ |
| public boolean isEnabledForExpression(Object object, |
| String expressionType) { |
| return child.isEnabledForExpression(object, expressionType); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.internal.ActionExpression.AbstractExpression#valuesForExpression(java.lang.String) |
| */ |
| public Collection valuesForExpression(String expressionType) { |
| return child.valuesForExpression(expressionType); |
| } |
| |
| } |
| |
| private static class SystemPropertyExpression extends AbstractExpression { |
| private String name; |
| |
| private String value; |
| |
| /** |
| * Creates and populates the expression from the attributes and sub- |
| * elements of the configuration element. |
| * |
| * @param element. |
| * The element that will be used to determine the expressions |
| * for systemProperty. |
| * @throws IllegalStateException |
| * if the expression tag is not defined in the schema. |
| * @see org.eclipse.ui\schema\commonExpression.mxsd |
| */ |
| public SystemPropertyExpression(IConfigurationElement element) |
| throws IllegalStateException { |
| super(); |
| |
| name = element.getAttribute(ATT_NAME); |
| value = element.getAttribute(ATT_VALUE); |
| if (name == null || value == null) { |
| throw new IllegalStateException( |
| "System property expression missing attribute"); //$NON-NLS-1$ |
| } |
| } |
| |
| /* |
| * (non-Javadoc) Method declared on AbstractExpression. |
| */ |
| public boolean isEnabledFor(Object object) { |
| String str = System.getProperty(name); |
| if (str == null) { |
| return false; |
| } |
| return value.equals(str); |
| } |
| |
| public final boolean equals(final Object object) { |
| if (object instanceof SystemPropertyExpression) { |
| final SystemPropertyExpression that = (SystemPropertyExpression) object; |
| return Util.equals(this.name, that.name) |
| && Util.equals(this.value, that.value); |
| } |
| |
| return false; |
| } |
| |
| /** |
| * Computes the hash code for this object based on the id. |
| * |
| * @return The hash code for this object. |
| */ |
| public final int hashCode() { |
| if (expressionHashCode == HASH_CODE_NOT_COMPUTED) { |
| expressionHashCode = HASH_INITIAL * HASH_FACTOR + Util.hashCode(name); |
| expressionHashCode = expressionHashCode * HASH_FACTOR + Util.hashCode(value); |
| if (expressionHashCode == HASH_CODE_NOT_COMPUTED) { |
| expressionHashCode++; |
| } |
| } |
| return expressionHashCode; |
| } |
| } |
| |
| private static final String ATT_ID = "id"; //$NON-NLS-1$ |
| |
| private static final String ATT_NAME = "name"; //$NON-NLS-1$ |
| |
| private static final String ATT_VALUE = "value"; //$NON-NLS-1$ |
| |
| /** |
| * Constant definition for AND. |
| * |
| * @see org.eclipse.ui\schema\commonExpression.mxsd |
| */ |
| public static final String EXP_TYPE_AND = "and"; //$NON-NLS-1$ |
| |
| /** |
| * Constant definition for NOT. |
| * |
| * @see org.eclipse.ui\schema\commonExpression.mxsd |
| */ |
| public static final String EXP_TYPE_NOT = "not"; //$NON-NLS-1$ |
| |
| /** |
| * Constant definition for objectClass. |
| * |
| * @see org.eclipse.ui\schema\commonExpression.mxsd |
| */ |
| public static final String EXP_TYPE_OBJECT_CLASS = "objectClass"; //$NON-NLS-1$ |
| |
| /** |
| * Constant definition for objectState. |
| * |
| * @see org.eclipse.ui\schema\commonExpression.mxsd |
| */ |
| public static final String EXP_TYPE_OBJECT_STATE = "objectState"; //$NON-NLS-1$ |
| |
| /** |
| * Constant definition for OR. |
| * |
| * @see org.eclipse.ui\schema\commonExpression.mxsd |
| */ |
| public static final String EXP_TYPE_OR = "or"; //$NON-NLS-1$ |
| |
| /** |
| * Constant definition for pluginState. |
| * |
| * @see org.eclipse.ui\schema\commonExpression.mxsd |
| */ |
| public static final String EXP_TYPE_PLUG_IN_STATE = "pluginState"; //$NON-NLS-1$ |
| |
| /** |
| * Constant definition for systemProperty. |
| * |
| * @see org.eclipse.ui\schema\commonExpression.mxsd |
| */ |
| public static final String EXP_TYPE_SYSTEM_PROPERTY = "systemProperty"; //$NON-NLS-1$ |
| |
| /** |
| * The constant integer hash code value meaning the hash code has not yet |
| * been computed. |
| */ |
| private static final int HASH_CODE_NOT_COMPUTED = -1; |
| |
| /** |
| * A factor for computing the hash code for all schemes. |
| */ |
| private static final int HASH_FACTOR = 89; |
| |
| /** |
| * The seed for the hash code for all schemes. |
| */ |
| private static final int HASH_INITIAL = ActionExpression.class.getName() |
| .hashCode(); |
| |
| private static final String PLUGIN_ACTIVATED = "activated"; //$NON-NLS-1$ |
| |
| private static final String PLUGIN_INSTALLED = "installed"; //$NON-NLS-1$ |
| |
| /** |
| * Create an expression from the attributes and sub-elements of the |
| * configuration element. |
| * |
| * @param element |
| * The IConfigurationElement with a tag defined in the public |
| * constants. |
| * @return AbstractExpression based on the definition |
| * @throws IllegalStateException |
| * if the expression tag is not defined in the schema. |
| * @see org.eclipse.ui\schema\commonExpression.mxsd |
| */ |
| private static AbstractExpression createExpression( |
| IConfigurationElement element) throws IllegalStateException { |
| String tag = element.getName(); |
| if (tag.equals(EXP_TYPE_OR)) { |
| return new OrExpression(element); |
| } |
| if (tag.equals(EXP_TYPE_AND)) { |
| return new AndExpression(element); |
| } |
| if (tag.equals(EXP_TYPE_NOT)) { |
| return new NotExpression(element); |
| } |
| if (tag.equals(EXP_TYPE_OBJECT_STATE)) { |
| return new ObjectStateExpression(element); |
| } |
| if (tag.equals(EXP_TYPE_OBJECT_CLASS)) { |
| return new ObjectClassExpression(element); |
| } |
| if (tag.equals(EXP_TYPE_PLUG_IN_STATE)) { |
| return new PluginStateExpression(element); |
| } |
| if (tag.equals(EXP_TYPE_SYSTEM_PROPERTY)) { |
| return new SystemPropertyExpression(element); |
| } |
| |
| throw new IllegalStateException( |
| "Action expression unrecognized element: " + tag); //$NON-NLS-1$ |
| } |
| |
| /** |
| * The hash code for this object. This value is computed lazily, and marked |
| * as invalid when one of the values on which it is based changes. |
| */ |
| private transient int hashCode = HASH_CODE_NOT_COMPUTED; |
| |
| private SingleExpression root; |
| |
| /** |
| * Creates an action expression for the given configuration element. |
| * |
| * @param element. |
| * The element to build the expression from. |
| */ |
| public ActionExpression(IConfigurationElement element) { |
| try { |
| root = new SingleExpression(element); |
| } catch (IllegalStateException e) { |
| e.printStackTrace(); |
| root = null; |
| } |
| } |
| |
| /** |
| * Create an instance of the receiver with the given expression type and |
| * value. Currently the only supported expression type is |
| * <code>EXP_TYPE_OBJECT_CLASS</code>. |
| * |
| * @param expressionType |
| * The expression constant we are creating an instance of. |
| * @param expressionValue |
| * The name of the class we are creating an expression for. |
| */ |
| public ActionExpression(String expressionType, String expressionValue) { |
| if (expressionType.equals(EXP_TYPE_OBJECT_CLASS)) { |
| root = new SingleExpression(new ObjectClassExpression( |
| expressionValue)); |
| } |
| } |
| |
| public final boolean equals(final Object object) { |
| if (object instanceof ActionExpression) { |
| final ActionExpression that = (ActionExpression) object; |
| return Util.equals(this.root, that.root); |
| } |
| |
| return false; |
| } |
| |
| /** |
| * Extract the object class test from the expression. This allows clients |
| * (e.g. the decorator manager) to handle object class testing in a more |
| * optimized way. This method removes the objectClass test from the |
| * expression and returns the object class. The expression is not changed |
| * and a <code>null</code> is returned if no object class is found. |
| * |
| * @return the object class or <code>null</code> if none was found. |
| */ |
| public String[] extractObjectClasses() { |
| return root.extractObjectClasses(); |
| } |
| |
| /** |
| * Computes the hash code for this object based on the id. |
| * |
| * @return The hash code for this object. |
| */ |
| public final int hashCode() { |
| if (hashCode == HASH_CODE_NOT_COMPUTED) { |
| hashCode = HASH_INITIAL * HASH_FACTOR + Util.hashCode(root); |
| if (hashCode == HASH_CODE_NOT_COMPUTED) { |
| hashCode++; |
| } |
| } |
| return hashCode; |
| } |
| |
| /** |
| * Returns whether the expression is valid for all elements of the given |
| * selection. |
| * |
| * @param selection |
| * the structured selection to use |
| * @return boolean whether the expression is valid for the selection. |
| */ |
| public boolean isEnabledFor(IStructuredSelection selection) { |
| if (root == null) { |
| return false; |
| } |
| |
| if (selection == null || selection.isEmpty()) { |
| return root.isEnabledFor(null); |
| } |
| |
| Iterator elements = selection.iterator(); |
| while (elements.hasNext()) { |
| if (!isEnabledFor(elements.next())) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| /** |
| * Returns whether the expression is valid for the given object. |
| * |
| * @param object |
| * the object to validate against (can be <code>null</code>) |
| * @return boolean whether the expression is valid for the object. |
| */ |
| public boolean isEnabledFor(Object object) { |
| if (root == null) { |
| return false; |
| } |
| return root.isEnabledFor(object); |
| } |
| |
| /** |
| * Returns whether or not the receiver is potentially valid for the object |
| * via just the extension type. Currently the only supported expression type |
| * is <code>EXP_TYPE_OBJECT_CLASS</code>. |
| * |
| * @param object |
| * the object to validate against (can be <code>null</code>) |
| * @param expressionType |
| * the expression type to consider |
| * @return boolean whether the expression is potentially valid for the |
| * object. |
| */ |
| public boolean isEnabledForExpression(Object object, String expressionType) { |
| if (root == null) { |
| return false; |
| } |
| return root.isEnabledForExpression(object, expressionType); |
| } |
| |
| /** |
| * Return the values of the expression type that the receiver is enabled |
| * for. If the receiver is not enabled for the expressionType then return |
| * <code>null</code>. |
| * |
| * @param expressionType |
| * the expression type to consider |
| * @return Collection if there are values for this expression or |
| * <code>null</code> if this is not possible in the receiver or |
| * any of it's children |
| */ |
| public Collection valuesForExpression(String expressionType) { |
| return root.valuesForExpression(expressionType); |
| } |
| } |