KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > ActionExpression


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.ui.internal;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Collection JavaDoc;
15 import java.util.HashSet JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18
19 import org.eclipse.core.runtime.IConfigurationElement;
20 import org.eclipse.core.runtime.Platform;
21 import org.eclipse.jface.viewers.IStructuredSelection;
22 import org.eclipse.ui.IActionFilter;
23 import org.eclipse.ui.internal.util.BundleUtility;
24 import org.eclipse.ui.internal.util.Util;
25 import org.osgi.framework.Bundle;
26
27 /**
28  * An ActionExpression is used to evaluate the enablement / visibility criteria
29  * for an action.
30  */

31 public class ActionExpression {
32
33     private static abstract class AbstractExpression {
34
35         /**
36          * The hash code for this object. This value is computed lazily, and
37          * marked as invalid when one of the values on which it is based
38          * changes.
39          */

40         protected transient int expressionHashCode = HASH_CODE_NOT_COMPUTED;
41
42         /**
43          * Extract the object class tests from the expression. This allows
44          * clients (e.g. the decorator manager) to handle object class testing
45          * in a more optimized way. This method extracts the objectClass test
46          * from the expression and returns the object classes. The expression is
47          * not changed and a <code>null</code> is returned if no object class
48          * is found.
49          *
50          * @return String[] the object class names or <code>null</code> if
51          * none was found.
52          */

53         public String JavaDoc[] extractObjectClasses() {
54             return null;
55         }
56
57         /**
58          * Returns whether the expression is valid for the given object.
59          *
60          * @param object
61          * the object to validate against (can be <code>null</code>)
62          * @return boolean whether the expression is valid for the object.
63          */

64         public abstract boolean isEnabledFor(Object JavaDoc object);
65
66         /**
67          * Returns whether or not the receiver is potentially valid for the
68          * object via just the extension type. Currently the only supported
69          * expression type is <code>EXP_TYPE_OBJECT_CLASS</code>.
70          *
71          * @param object
72          * the object to validate against (can be <code>null</code>)
73          * @param expressionType
74          * the expression type to consider
75          * @return boolean whether the expression is potentially valid for the
76          * object.
77          */

78         public boolean isEnabledForExpression(Object JavaDoc object,
79                 String JavaDoc expressionType) {
80             return false;
81         }
82
83         /**
84          * Return the value of the expression type that the receiver is enabled
85          * for. If the receiver is not enabled for the expressionType then
86          * return <code>null</code>.
87          *
88          * @param expressionType
89          * the expression type to consider
90          * @return Collection of String if there are values for this expression
91          * or <code>null</code> if this is not possible in the
92          * receiver or any of it's children
93          */

94         public Collection JavaDoc valuesForExpression(String JavaDoc expressionType) {
95             return null;
96         }
97     }
98
99     private static class AndExpression extends CompositeExpression {
100
101         /**
102          * Creates and populates the expression from the attributes and sub-
103          * elements of the configuration element.
104          *
105          * @param element
106          * The element that will be used to determine the expressions
107          * for And.
108          * @throws IllegalStateException
109          * if the expression tag is not defined in the schema.
110          */

111         public AndExpression(IConfigurationElement element)
112                 throws IllegalStateException JavaDoc {
113             super(element);
114         }
115
116         public final boolean equals(final Object JavaDoc object) {
117             if (object instanceof AndExpression) {
118                 final AndExpression that = (AndExpression) object;
119                 return Util.equals(this.list, that.list);
120             }
121
122             return false;
123         }
124
125         /*
126          * (non-Javadoc) Method declared on AbstractExpression.
127          */

128         public boolean isEnabledFor(Object JavaDoc object) {
129             Iterator JavaDoc iter = list.iterator();
130             while (iter.hasNext()) {
131                 AbstractExpression expr = (AbstractExpression) iter.next();
132                 if (!expr.isEnabledFor(object)) {
133                     return false;
134                 }
135             }
136             return true;
137         }
138     }
139
140     private static abstract class CompositeExpression extends
141             AbstractExpression {
142         /**
143          *
144          */

145         protected ArrayList JavaDoc list;
146
147         /**
148          * Creates and populates the expression from the attributes and sub-
149          * elements of the configuration element.
150          *
151          * @param element
152          * The composite element we will create the expression from.
153          * @throws IllegalStateException
154          * if the expression tag is not defined in the schema.
155          */

156         public CompositeExpression(IConfigurationElement element)
157                 throws IllegalStateException JavaDoc {
158             super();
159
160             IConfigurationElement[] children = element.getChildren();
161             if (children.length == 0) {
162                 throw new IllegalStateException JavaDoc(
163                         "Composite expression cannot be empty"); //$NON-NLS-1$
164
}
165
166             list = new ArrayList JavaDoc(children.length);
167             for (int i = 0; i < children.length; i++) {
168                 String JavaDoc tag = children[i].getName();
169                 AbstractExpression expr = createExpression(children[i]);
170                 if (EXP_TYPE_OBJECT_CLASS.equals(tag)) {
171                     list.add(0, expr);
172                 } else {
173                     list.add(expr);
174                 }
175             }
176         }
177
178         /*
179          * (non-Javadoc)
180          *
181          * @see org.eclipse.ui.internal.ActionExpression.AbstractExpression#extractObjectClasses()
182          */

183         public String JavaDoc[] extractObjectClasses() {
184             Iterator JavaDoc iterator = list.iterator();
185             List JavaDoc classNames = null;
186             while (iterator.hasNext()) {
187                 AbstractExpression next = (AbstractExpression) iterator.next();
188                 String JavaDoc[] objectClasses = next.extractObjectClasses();
189                 if (objectClasses != null) {
190                     if (classNames == null) {
191                         classNames = new ArrayList JavaDoc();
192                     }
193                     for (int i = 0; i < objectClasses.length; i++) {
194                         classNames.add(objectClasses[i]);
195                     }
196                 }
197             }
198             if (classNames == null) {
199                 return null;
200             }
201
202             String JavaDoc[] returnValue = new String JavaDoc[classNames.size()];
203             classNames.toArray(returnValue);
204             return returnValue;
205         }
206
207         /**
208          * Computes the hash code for this object based on the id.
209          *
210          * @return The hash code for this object.
211          */

212         public final int hashCode() {
213             if (expressionHashCode == HASH_CODE_NOT_COMPUTED) {
214                 expressionHashCode = HASH_INITIAL * HASH_FACTOR + Util.hashCode(list);
215                 if (expressionHashCode == HASH_CODE_NOT_COMPUTED) {
216                     expressionHashCode++;
217                 }
218             }
219             return expressionHashCode;
220         }
221
222         /*
223          * (non-Javadoc) Method declared on AbstractExpression.
224          */

225         public boolean isEnabledForExpression(Object JavaDoc object,
226                 String JavaDoc expressionType) {
227             Iterator JavaDoc iterator = list.iterator();
228             while (iterator.hasNext()) {
229                 AbstractExpression next = (AbstractExpression) iterator.next();
230                 if (next.isEnabledForExpression(object, expressionType)) {
231                     return true;
232                 }
233             }
234             return false;
235         }
236
237         /*
238          * (non-Javadoc)
239          *
240          * @see org.eclipse.ui.internal.ActionExpression.AbstractExpression#valuesForExpression(java.lang.String)
241          */

242         public Collection JavaDoc valuesForExpression(String JavaDoc expressionType) {
243             Iterator JavaDoc iterator = list.iterator();
244             Collection JavaDoc allValues = null;
245             while (iterator.hasNext()) {
246                 AbstractExpression next = (AbstractExpression) iterator.next();
247                 Collection JavaDoc values = next.valuesForExpression(expressionType);
248                 if (values != null) {
249                     if (allValues == null) {
250                         allValues = values;
251                     } else {
252                         allValues.addAll(values);
253                     }
254                 }
255
256             }
257             return allValues;
258         }
259     }
260
261     private static class NotExpression extends SingleExpression {
262
263         /**
264          * Creates and populates the expression from the attributes and sub-
265          * elements of the configuration element.
266          *
267          * @param element
268          * The element that will be used to create the definition for
269          * the receiver.
270          * @throws IllegalStateException
271          * if the expression tag is not defined in the schema.
272          */

273         public NotExpression(IConfigurationElement element)
274                 throws IllegalStateException JavaDoc {
275             super(element);
276         }
277
278         /*
279          * (non-Javadoc) Method declared on AbstractExpression.
280          */

281         public boolean isEnabledFor(Object JavaDoc object) {
282             return !super.isEnabledFor(object);
283         }
284     }
285
286     private static class ObjectClassExpression extends AbstractExpression {
287         private String JavaDoc className;
288
289         private boolean extracted;
290
291         /**
292          * Creates and populates the expression from the attributes and sub-
293          * elements of the configuration element.
294          *
295          * @param element
296          * The element that will be used to determine the expressions
297          * for objectClass.
298          * @throws IllegalStateException
299          * if the expression tag is not defined in the schema.
300          */

301         public ObjectClassExpression(IConfigurationElement element)
302                 throws IllegalStateException JavaDoc {
303             super();
304
305             className = element.getAttribute(ATT_NAME);
306             if (className == null) {
307                 throw new IllegalStateException JavaDoc(
308                         "Object class expression missing name attribute"); //$NON-NLS-1$
309
}
310         }
311
312         /**
313          * Create an ObjectClass expression based on the className. Added for
314          * backwards compatibility.
315          *
316          * @param className
317          */

318         public ObjectClassExpression(String JavaDoc className) {
319             super();
320
321             if (className != null) {
322                 this.className = className;
323             } else {
324                 throw new IllegalStateException JavaDoc(
325                         "Object class expression must have class name"); //$NON-NLS-1$
326
}
327         }
328
329         /**
330          * Check the interfaces the whole way up. If one of them matches
331          * className return <code>true</code>.
332          *
333          * @param interfaceToCheck
334          * The interface whose name we are testing against.
335          * @return <code>true</code> if one of the interfaces in the hierarchy
336          * matches className, <code>false</code> otherwise.
337          */

338         private boolean checkInterfaceHierarchy(Class JavaDoc interfaceToCheck) {
339             if (interfaceToCheck.getName().equals(className)) {
340                 return true;
341             }
342             Class JavaDoc[] superInterfaces = interfaceToCheck.getInterfaces();
343             for (int i = 0; i < superInterfaces.length; i++) {
344                 if (checkInterfaceHierarchy(superInterfaces[i])) {
345                     return true;
346                 }
347             }
348             return false;
349         }
350
351         public final boolean equals(final Object JavaDoc object) {
352             if (object instanceof ObjectClassExpression) {
353                 final ObjectClassExpression that = (ObjectClassExpression) object;
354                 return Util.equals(this.className, that.className)
355                         && Util.equals(this.extracted, that.extracted);
356             }
357
358             return false;
359         }
360
361         /*
362          * (non-Javadoc)
363          *
364          * @see org.eclipse.ui.internal.ActionExpression.AbstractExpression#extractObjectClasses()
365          */

366         public String JavaDoc[] extractObjectClasses() {
367             extracted = true;
368             return new String JavaDoc[] { className };
369         }
370
371         /**
372          * Computes the hash code for this object based on the id.
373          *
374          * @return The hash code for this object.
375          */

376         public final int hashCode() {
377             if (expressionHashCode == HASH_CODE_NOT_COMPUTED) {
378                 expressionHashCode = HASH_INITIAL * HASH_FACTOR
379                         + Util.hashCode(className);
380                 expressionHashCode = expressionHashCode * HASH_FACTOR + Util.hashCode(extracted);
381                 if (expressionHashCode == HASH_CODE_NOT_COMPUTED) {
382                     expressionHashCode++;
383                 }
384             }
385             return expressionHashCode;
386         }
387
388         /*
389          * (non-Javadoc) Method declared on AbstractExpression.
390          */

391         public boolean isEnabledFor(Object JavaDoc object) {
392             if (object == null) {
393                 return false;
394             }
395             if (extracted) {
396                 return true;
397             }
398
399             Class JavaDoc clazz = object.getClass();
400             while (clazz != null) {
401                 // test the class itself
402
if (clazz.getName().equals(className)) {
403                     return true;
404                 }
405
406                 // test all the interfaces the class implements
407
Class JavaDoc[] interfaces = clazz.getInterfaces();
408                 for (int i = 0; i < interfaces.length; i++) {
409                     if (checkInterfaceHierarchy(interfaces[i])) {
410                         return true;
411                     }
412                 }
413
414                 // get the superclass
415
clazz = clazz.getSuperclass();
416             }
417
418             return false;
419         }
420
421         /*
422          * (non-Javadoc) Method declared on AbstractExpression.
423          */

424         public boolean isEnabledForExpression(Object JavaDoc object,
425                 String JavaDoc expressionType) {
426             if (expressionType.equals(EXP_TYPE_OBJECT_CLASS)) {
427                 return isEnabledFor(object);
428             }
429             return false;
430         }
431     }
432
433     private static class ObjectStateExpression extends AbstractExpression {
434         private String JavaDoc name;
435
436         private String JavaDoc value;
437
438         /**
439          * Creates and populates the expression from the attributes and sub-
440          * elements of the configuration element.
441          *
442          * @param element
443          * The element that will be used to determine the expressions
444          * for objectState.
445          * @throws IllegalStateException
446          * if the expression tag is not defined in the schema.
447          */

448         public ObjectStateExpression(IConfigurationElement element)
449                 throws IllegalStateException JavaDoc {
450             super();
451
452             name = element.getAttribute(ATT_NAME);
453             value = element.getAttribute(ATT_VALUE);
454             if (name == null || value == null) {
455                 throw new IllegalStateException JavaDoc(
456                         "Object state expression missing attribute"); //$NON-NLS-1$
457
}
458         }
459
460         public final boolean equals(final Object JavaDoc object) {
461             if (object instanceof ObjectStateExpression) {
462                 final ObjectStateExpression that = (ObjectStateExpression) object;
463                 return Util.equals(this.name, that.name)
464                         && Util.equals(this.value, that.value);
465             }
466
467             return false;
468         }
469
470         private IActionFilter getActionFilter(Object JavaDoc object) {
471             return (IActionFilter)Util.getAdapter(object, IActionFilter.class);
472         }
473
474         /**
475          * Computes the hash code for this object based on the id.
476          *
477          * @return The hash code for this object.
478          */

479         public final int hashCode() {
480             if (expressionHashCode == HASH_CODE_NOT_COMPUTED) {
481                 expressionHashCode = HASH_INITIAL * HASH_FACTOR + Util.hashCode(name);
482                 expressionHashCode = expressionHashCode * HASH_FACTOR + Util.hashCode(value);
483                 if (expressionHashCode == HASH_CODE_NOT_COMPUTED) {
484                     expressionHashCode++;
485                 }
486             }
487             return expressionHashCode;
488         }
489
490         /*
491          * (non-Javadoc) Method declared on AbstractExpression.
492          */

493         public boolean isEnabledFor(Object JavaDoc object) {
494             if (object == null) {
495                 return false;
496             }
497
498             // Try out the object first.
499
if (preciselyMatches(object)) {
500                 return true;
501             }
502
503             // Try out the underlying resource.
504
Class JavaDoc resourceClass = LegacyResourceSupport.getResourceClass();
505             if (resourceClass == null) {
506                 return false;
507             }
508
509             if (resourceClass.isInstance(object)) {
510                 return false;
511             }
512
513             Object JavaDoc res = Util.getAdapter(object, resourceClass);
514             if (res == null) {
515                 return false;
516             }
517
518             return preciselyMatches(res);
519
520         }
521
522         private boolean preciselyMatches(Object JavaDoc object) {
523             // Get the action filter.
524
IActionFilter filter = getActionFilter(object);
525             if (filter == null) {
526                 return false;
527             }
528
529             // Run the action filter.
530
return filter.testAttribute(object, name, value);
531         }
532
533         /*
534          * (non-Javadoc)
535          *
536          * @see org.eclipse.ui.internal.ActionExpression.AbstractExpression#valuesForExpression(java.lang.String)
537          */

538         public Collection JavaDoc valuesForExpression(String JavaDoc expressionType) {
539             if (expressionType.equals(name)) {
540                 Collection JavaDoc returnValue = new HashSet JavaDoc();
541                 returnValue.add(value);
542                 return returnValue;
543             }
544             return null;
545         }
546
547     }
548
549     private static class OrExpression extends CompositeExpression {
550
551         /**
552          * Creates and populates the expression from the attributes and sub-
553          * elements of the configuration element.
554          *
555          * @param element
556          * The element that will be used to determine the expressions
557          * for Or.
558          * @throws IllegalStateException
559          * if the expression tag is not defined in the schema.
560          */

561         public OrExpression(IConfigurationElement element)
562                 throws IllegalStateException JavaDoc {
563             super(element);
564         }
565
566         public final boolean equals(final Object JavaDoc object) {
567             if (object instanceof OrExpression) {
568                 final OrExpression that = (OrExpression) object;
569                 return Util.equals(this.list, that.list);
570             }
571
572             return false;
573         }
574
575         /*
576          * (non-Javadoc) Method declared on AbstractExpression.
577          */

578         public boolean isEnabledFor(Object JavaDoc object) {
579             Iterator JavaDoc iter = list.iterator();
580             while (iter.hasNext()) {
581                 AbstractExpression expr = (AbstractExpression) iter.next();
582                 if (expr.isEnabledFor(object)) {
583                     return true;
584                 }
585             }
586             return false;
587         }
588     }
589
590     private static class PluginStateExpression extends AbstractExpression {
591         private String JavaDoc id;
592
593         private String JavaDoc value;
594
595         /**
596          * Creates and populates the expression from the attributes and sub-
597          * elements of the configuration element.
598          *
599          * @param element
600          * The element that will be used to determine the expressions
601          * for pluginState.
602          * @throws IllegalStateException
603          * if the expression tag is not defined in the schema.
604          */

605         public PluginStateExpression(IConfigurationElement element)
606                 throws IllegalStateException JavaDoc {
607             super();
608
609             id = element.getAttribute(ATT_ID);
610             value = element.getAttribute(ATT_VALUE);
611             if (id == null || value == null) {
612                 throw new IllegalStateException JavaDoc(
613                         "Plugin state expression missing attribute"); //$NON-NLS-1$
614
}
615         }
616
617         public final boolean equals(final Object JavaDoc object) {
618             if (object instanceof PluginStateExpression) {
619                 final PluginStateExpression that = (PluginStateExpression) object;
620                 return Util.equals(this.id, that.id)
621                         && Util.equals(this.value, that.value);
622             }
623
624             return false;
625         }
626
627         /**
628          * Computes the hash code for this object based on the id.
629          *
630          * @return The hash code for this object.
631          */

632         public final int hashCode() {
633             if (expressionHashCode == HASH_CODE_NOT_COMPUTED) {
634                 expressionHashCode = HASH_INITIAL * HASH_FACTOR + Util.hashCode(id);
635                 expressionHashCode = expressionHashCode * HASH_FACTOR + Util.hashCode(value);
636                 if (expressionHashCode == HASH_CODE_NOT_COMPUTED) {
637                     expressionHashCode++;
638                 }
639             }
640             return expressionHashCode;
641         }
642
643         /*
644          * (non-Javadoc) Method declared on AbstractExpression.
645          */

646         public boolean isEnabledFor(Object JavaDoc object) {
647             Bundle bundle = Platform.getBundle(id);
648             if (!BundleUtility.isReady(bundle)) {
649                 return false;
650             }
651             if (value.equals(PLUGIN_INSTALLED)) {
652                 return true;
653             }
654             if (value.equals(PLUGIN_ACTIVATED)) {
655                 return BundleUtility.isActivated(bundle);
656             }
657             return false;
658         }
659     }
660
661     private static class SingleExpression extends AbstractExpression {
662         private AbstractExpression child;
663
664         /**
665          * Create a single expression from the abstract definition.
666          *
667          * @param expression
668          * The expression that will be the child of the new single
669          * expression.
670          * @throws IllegalStateException
671          * if the expression tag is not defined in the schema.
672          */

673         public SingleExpression(AbstractExpression expression)
674                 throws IllegalStateException JavaDoc {
675             super();
676
677             if (expression != null) {
678                 child = expression;
679             } else {
680                 throw new IllegalStateException JavaDoc(
681                         "Single expression must contain 1 expression"); //$NON-NLS-1$
682
}
683         }
684
685         /**
686          * Creates and populates the expression from the attributes and sub-
687          * elements of the configuration element.
688          *
689          * @param element
690          * The element to create the expression from.
691          * @throws IllegalStateException
692          * if the expression tag is not defined in the schema.
693          */

694         public SingleExpression(IConfigurationElement element)
695                 throws IllegalStateException JavaDoc {
696             super();
697
698             IConfigurationElement[] children = element.getChildren();
699             if (children.length != 1) {
700                 throw new IllegalStateException JavaDoc(
701                         "Single expression does not contain only 1 expression"); //$NON-NLS-1$
702
}
703             child = createExpression(children[0]);
704         }
705
706         public final boolean equals(final Object JavaDoc object) {
707             if (object instanceof SingleExpression) {
708                 final SingleExpression that = (SingleExpression) object;
709                 return Util.equals(this.child, that.child);
710             }
711
712             return false;
713         }
714
715         /*
716          * (non-Javadoc)
717          *
718          * @see org.eclipse.ui.internal.ActionExpression.AbstractExpression#extractObjectClasses()
719          */

720         public String JavaDoc[] extractObjectClasses() {
721             return child.extractObjectClasses();
722         }
723
724         /**
725          * Computes the hash code for this object based on the id.
726          *
727          * @return The hash code for this object.
728          */

729         public final int hashCode() {
730             if (expressionHashCode == HASH_CODE_NOT_COMPUTED) {
731                 expressionHashCode = HASH_INITIAL * HASH_FACTOR + Util.hashCode(child);
732                 if (expressionHashCode == HASH_CODE_NOT_COMPUTED) {
733                     expressionHashCode++;
734                 }
735             }
736             return expressionHashCode;
737         }
738
739         /*
740          * (non-Javadoc) Method declared on AbstractExpression.
741          */

742         public boolean isEnabledFor(Object JavaDoc object) {
743             return child.isEnabledFor(object);
744         }
745
746         /*
747          * (non-Javadoc) Method declared on AbstractExpression.
748          */

749         public boolean isEnabledForExpression(Object JavaDoc object,
750                 String JavaDoc expressionType) {
751             return child.isEnabledForExpression(object, expressionType);
752         }
753
754         /*
755          * (non-Javadoc)
756          *
757          * @see org.eclipse.ui.internal.ActionExpression.AbstractExpression#valuesForExpression(java.lang.String)
758          */

759         public Collection JavaDoc valuesForExpression(String JavaDoc expressionType) {
760             return child.valuesForExpression(expressionType);
761         }
762
763     }
764
765     private static class SystemPropertyExpression extends AbstractExpression {
766         private String JavaDoc name;
767
768         private String JavaDoc value;
769
770         /**
771          * Creates and populates the expression from the attributes and sub-
772          * elements of the configuration element.
773          *
774          * @param element
775          * The element that will be used to determine the expressions
776          * for systemProperty.
777          * @throws IllegalStateException
778          * if the expression tag is not defined in the schema.
779          */

780         public SystemPropertyExpression(IConfigurationElement element)
781                 throws IllegalStateException JavaDoc {
782             super();
783
784             name = element.getAttribute(ATT_NAME);
785             value = element.getAttribute(ATT_VALUE);
786             if (name == null || value == null) {
787                 throw new IllegalStateException JavaDoc(
788                         "System property expression missing attribute"); //$NON-NLS-1$
789
}
790         }
791
792         /*
793          * (non-Javadoc) Method declared on AbstractExpression.
794          */

795         public boolean isEnabledFor(Object JavaDoc object) {
796             String JavaDoc str = System.getProperty(name);
797             if (str == null) {
798                 return false;
799             }
800             return value.equals(str);
801         }
802
803         public final boolean equals(final Object JavaDoc object) {
804             if (object instanceof SystemPropertyExpression) {
805                 final SystemPropertyExpression that = (SystemPropertyExpression) object;
806                 return Util.equals(this.name, that.name)
807                         && Util.equals(this.value, that.value);
808             }
809
810             return false;
811         }
812
813         /**
814          * Computes the hash code for this object based on the id.
815          *
816          * @return The hash code for this object.
817          */

818         public final int hashCode() {
819             if (expressionHashCode == HASH_CODE_NOT_COMPUTED) {
820                 expressionHashCode = HASH_INITIAL * HASH_FACTOR + Util.hashCode(name);
821                 expressionHashCode = expressionHashCode * HASH_FACTOR + Util.hashCode(value);
822                 if (expressionHashCode == HASH_CODE_NOT_COMPUTED) {
823                     expressionHashCode++;
824                 }
825             }
826             return expressionHashCode;
827         }
828     }
829
830     private static final String JavaDoc ATT_ID = "id"; //$NON-NLS-1$
831

832     private static final String JavaDoc ATT_NAME = "name"; //$NON-NLS-1$
833

834     private static final String JavaDoc ATT_VALUE = "value"; //$NON-NLS-1$
835

836     /**
837      * Constant definition for AND.
838      *
839      */

840     public static final String JavaDoc EXP_TYPE_AND = "and"; //$NON-NLS-1$
841

842     /**
843      * Constant definition for NOT.
844      *
845      */

846     public static final String JavaDoc EXP_TYPE_NOT = "not"; //$NON-NLS-1$
847

848     /**
849      * Constant definition for objectClass.
850      *
851      */

852     public static final String JavaDoc EXP_TYPE_OBJECT_CLASS = "objectClass"; //$NON-NLS-1$
853

854     /**
855      * Constant definition for objectState.
856      *
857      */

858     public static final String JavaDoc EXP_TYPE_OBJECT_STATE = "objectState"; //$NON-NLS-1$
859

860     /**
861      * Constant definition for OR.
862      *
863      */

864     public static final String JavaDoc EXP_TYPE_OR = "or"; //$NON-NLS-1$
865

866     /**
867      * Constant definition for pluginState.
868      *
869      */

870     public static final String JavaDoc EXP_TYPE_PLUG_IN_STATE = "pluginState"; //$NON-NLS-1$
871

872     /**
873      * Constant definition for systemProperty.
874      *
875      */

876     public static final String JavaDoc EXP_TYPE_SYSTEM_PROPERTY = "systemProperty"; //$NON-NLS-1$
877

878     /**
879      * The constant integer hash code value meaning the hash code has not yet
880      * been computed.
881      */

882     private static final int HASH_CODE_NOT_COMPUTED = -1;
883
884     /**
885      * A factor for computing the hash code for all schemes.
886      */

887     private static final int HASH_FACTOR = 89;
888
889     /**
890      * The seed for the hash code for all schemes.
891      */

892     private static final int HASH_INITIAL = ActionExpression.class.getName()
893             .hashCode();
894
895     private static final String JavaDoc PLUGIN_ACTIVATED = "activated"; //$NON-NLS-1$
896

897     private static final String JavaDoc PLUGIN_INSTALLED = "installed"; //$NON-NLS-1$
898

899     /**
900      * Create an expression from the attributes and sub-elements of the
901      * configuration element.
902      *
903      * @param element
904      * The IConfigurationElement with a tag defined in the public
905      * constants.
906      * @return AbstractExpression based on the definition
907      * @throws IllegalStateException
908      * if the expression tag is not defined in the schema.
909      */

910     private static AbstractExpression createExpression(
911             IConfigurationElement element) throws IllegalStateException JavaDoc {
912         String JavaDoc tag = element.getName();
913         if (tag.equals(EXP_TYPE_OR)) {
914             return new OrExpression(element);
915         }
916         if (tag.equals(EXP_TYPE_AND)) {
917             return new AndExpression(element);
918         }
919         if (tag.equals(EXP_TYPE_NOT)) {
920             return new NotExpression(element);
921         }
922         if (tag.equals(EXP_TYPE_OBJECT_STATE)) {
923             return new ObjectStateExpression(element);
924         }
925         if (tag.equals(EXP_TYPE_OBJECT_CLASS)) {
926             return new ObjectClassExpression(element);
927         }
928         if (tag.equals(EXP_TYPE_PLUG_IN_STATE)) {
929             return new PluginStateExpression(element);
930         }
931         if (tag.equals(EXP_TYPE_SYSTEM_PROPERTY)) {
932             return new SystemPropertyExpression(element);
933         }
934
935         throw new IllegalStateException JavaDoc(
936                 "Action expression unrecognized element: " + tag); //$NON-NLS-1$
937
}
938
939     /**
940      * The hash code for this object. This value is computed lazily, and marked
941      * as invalid when one of the values on which it is based changes.
942      */

943     private transient int hashCode = HASH_CODE_NOT_COMPUTED;
944
945     private SingleExpression root;
946
947     /**
948      * Creates an action expression for the given configuration element.
949      *
950      * @param element
951      * The element to build the expression from.
952      */

953     public ActionExpression(IConfigurationElement element) {
954         try {
955             root = new SingleExpression(element);
956         } catch (IllegalStateException JavaDoc e) {
957             e.printStackTrace();
958             root = null;
959         }
960     }
961
962     /**
963      * Create an instance of the receiver with the given expression type and
964      * value. Currently the only supported expression type is
965      * <code>EXP_TYPE_OBJECT_CLASS</code>.
966      *
967      * @param expressionType
968      * The expression constant we are creating an instance of.
969      * @param expressionValue
970      * The name of the class we are creating an expression for.
971      */

972     public ActionExpression(String JavaDoc expressionType, String JavaDoc expressionValue) {
973         if (expressionType.equals(EXP_TYPE_OBJECT_CLASS)) {
974             root = new SingleExpression(new ObjectClassExpression(
975                     expressionValue));
976         }
977     }
978
979     public final boolean equals(final Object JavaDoc object) {
980         if (object instanceof ActionExpression) {
981             final ActionExpression that = (ActionExpression) object;
982             return Util.equals(this.root, that.root);
983         }
984
985         return false;
986     }
987
988     /**
989      * Extract the object class test from the expression. This allows clients
990      * (e.g. the decorator manager) to handle object class testing in a more
991      * optimized way. This method removes the objectClass test from the
992      * expression and returns the object class. The expression is not changed
993      * and a <code>null</code> is returned if no object class is found.
994      *
995      * @return the object class or <code>null</code> if none was found.
996      */

997     public String JavaDoc[] extractObjectClasses() {
998         return root.extractObjectClasses();
999     }
1000
1001    /**
1002     * Computes the hash code for this object based on the id.
1003     *
1004     * @return The hash code for this object.
1005     */

1006    public final int hashCode() {
1007        if (hashCode == HASH_CODE_NOT_COMPUTED) {
1008            hashCode = HASH_INITIAL * HASH_FACTOR + Util.hashCode(root);
1009            if (hashCode == HASH_CODE_NOT_COMPUTED) {
1010                hashCode++;
1011            }
1012        }
1013        return hashCode;
1014    }
1015
1016    /**
1017     * Returns whether the expression is valid for all elements of the given
1018     * selection.
1019     *
1020     * @param selection
1021     * the structured selection to use
1022     * @return boolean whether the expression is valid for the selection.
1023     */

1024    public boolean isEnabledFor(IStructuredSelection selection) {
1025        if (root == null) {
1026            return false;
1027        }
1028
1029        if (selection == null || selection.isEmpty()) {
1030            return root.isEnabledFor(null);
1031        }
1032
1033        Iterator JavaDoc elements = selection.iterator();
1034        while (elements.hasNext()) {
1035            if (!isEnabledFor(elements.next())) {
1036                return false;
1037            }
1038        }
1039        return true;
1040    }
1041
1042    /**
1043     * Returns whether the expression is valid for the given object.
1044     *
1045     * @param object
1046     * the object to validate against (can be <code>null</code>)
1047     * @return boolean whether the expression is valid for the object.
1048     */

1049    public boolean isEnabledFor(Object JavaDoc object) {
1050        if (root == null) {
1051            return false;
1052        }
1053        return root.isEnabledFor(object);
1054    }
1055
1056    /**
1057     * Returns whether or not the receiver is potentially valid for the object
1058     * via just the extension type. Currently the only supported expression type
1059     * is <code>EXP_TYPE_OBJECT_CLASS</code>.
1060     *
1061     * @param object
1062     * the object to validate against (can be <code>null</code>)
1063     * @param expressionType
1064     * the expression type to consider
1065     * @return boolean whether the expression is potentially valid for the
1066     * object.
1067     */

1068    public boolean isEnabledForExpression(Object JavaDoc object, String JavaDoc expressionType) {
1069        if (root == null) {
1070            return false;
1071        }
1072        return root.isEnabledForExpression(object, expressionType);
1073    }
1074
1075    /**
1076     * Return the values of the expression type that the receiver is enabled
1077     * for. If the receiver is not enabled for the expressionType then return
1078     * <code>null</code>.
1079     *
1080     * @param expressionType
1081     * the expression type to consider
1082     * @return Collection if there are values for this expression or
1083     * <code>null</code> if this is not possible in the receiver or
1084     * any of it's children
1085     */

1086    public Collection JavaDoc valuesForExpression(String JavaDoc expressionType) {
1087        return root.valuesForExpression(expressionType);
1088    }
1089}
1090
Popular Tags