in src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java [699:1400]
private String getVirtualAccessibleNameFromContext(final AccessibleContext ac) {
if (null != ac) {
/*
Step 1:
=======
Determine if we can obtain the Virtual Accessible Name from the
Accessible Name or Accessible Description of the object.
*/
String nameString = InvocationUtils.invokeAndWait(new Callable<String>() {
@Override
public String call() throws Exception {
return ac.getAccessibleName();
}
}, ac);
if ( ( null != nameString ) && ( 0 != nameString.length () ) ) {
debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from AccessibleContext::getAccessibleName.");
references.increment (nameString);
return nameString;
}
String descriptionString = InvocationUtils.invokeAndWait(new Callable<String>() {
@Override
public String call() throws Exception {
return ac.getAccessibleDescription();
}
}, ac);
if ( ( null != descriptionString ) && ( 0 != descriptionString.length () ) ) {
debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from AccessibleContext::getAccessibleDescription.");
references.increment (descriptionString);
return descriptionString;
}
debugString ("[WARN]: The Virtual Accessible Name was not found using AccessibleContext::getAccessibleDescription. or getAccessibleName");
/*
Step 2:
=======
Decide whether the extended name search algorithm should be
used for this object.
*/
boolean bExtendedSearch = false;
AccessibleRole role = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
@Override
public AccessibleRole call() throws Exception {
return ac.getAccessibleRole();
}
}, ac);
AccessibleContext parentContext = null;
AccessibleRole parentRole = AccessibleRole.UNKNOWN;
if ( extendedVirtualNameSearchRoles.contains (role) ) {
parentContext = getAccessibleParentFromContext (ac);
if ( null != parentContext ) {
final AccessibleContext parentContextInnerTemp = parentContext;
parentRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
@Override
public AccessibleRole call() throws Exception {
return parentContextInnerTemp.getAccessibleRole();
}
}, ac);
if ( AccessibleRole.UNKNOWN != parentRole ) {
bExtendedSearch = true;
if ( noExtendedVirtualNameSearchParentRoles.contains (parentRole) ) {
bExtendedSearch = false;
}
}
}
}
if (false == bExtendedSearch) {
debugString ("[INFO]: bk -- getVirtualAccessibleNameFromContext will not use the extended name search algorithm. role = " + ( role != null ? role.toDisplayString(Locale.US) : "null") );
/*
Step 3:
=======
We have determined that we should not use the extended name
search algorithm for this object (we must obtain the name of
the object from the object itself and not from neighboring
objects). However the object name cannot be obtained from
the Accessible Name or Accessible Description of the object.
Handle several special cases here that might yield a value for
the Virtual Accessible Name. Return null if the object does
not match the criteria for any of these special cases.
*/
if (AccessibleRole.LABEL == role) {
/*
Does the label support the Accessible Text Interface?
*/
final AccessibleText at = InvocationUtils.invokeAndWait(new Callable<AccessibleText>() {
@Override
public AccessibleText call() throws Exception {
return ac.getAccessibleText();
}
}, ac);
if (null != at) {
int charCount = InvocationUtils.invokeAndWait(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return at.getCharCount();
}
}, ac);
String text = getAccessibleTextRangeFromContext (ac, 0, charCount);
if (null != text) {
debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from the Accessible Text of the LABEL object.");
references.increment (text);
return text;
}
}
/*
Does the label support the Accessible Icon Interface?
*/
debugString ("[INFO]: bk -- Attempting to obtain the Virtual Accessible Name from the Accessible Icon information.");
final AccessibleIcon [] ai = InvocationUtils.invokeAndWait(new Callable<AccessibleIcon[]>() {
@Override
public AccessibleIcon[] call() throws Exception {
return ac.getAccessibleIcon();
}
}, ac);
if ( (null != ai) && (ai.length > 0) ) {
String iconDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
@Override
public String call() throws Exception {
return ai[0].getAccessibleIconDescription();
}
}, ac);
if (iconDescription != null){
debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the LABEL object.");
references.increment (iconDescription);
return iconDescription;
}
} else {
parentContext = getAccessibleParentFromContext (ac);
if ( null != parentContext ) {
final AccessibleContext parentContextInnerTemp = parentContext;
parentRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
@Override
public AccessibleRole call() throws Exception {
return parentContextInnerTemp.getAccessibleRole();
}
}, ac);
if ( AccessibleRole.TABLE == parentRole ) {
int indexInParent = InvocationUtils.invokeAndWait(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return ac.getAccessibleIndexInParent();
}
}, ac);
final AccessibleContext acTableCell = getAccessibleChildFromContext (parentContext, indexInParent);
debugString ("[INFO]: bk -- Making a second attempt to obtain the Virtual Accessible Name from the Accessible Icon information for the Table Cell.");
if (acTableCell != null) {
final AccessibleIcon [] aiRet =InvocationUtils.invokeAndWait(new Callable<AccessibleIcon[]>() {
@Override
public AccessibleIcon[] call() throws Exception {
return acTableCell.getAccessibleIcon();
}
}, ac);
if ( (null != aiRet) && (aiRet.length > 0) ) {
String iconDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
@Override
public String call() throws Exception {
return aiRet[0].getAccessibleIconDescription();
}
}, ac);
if (iconDescription != null){
debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the Table Cell object.");
references.increment (iconDescription);
return iconDescription;
}
}
}
}
}
}
} else if ( (AccessibleRole.TOGGLE_BUTTON == role) ||
(AccessibleRole.PUSH_BUTTON == role) ) {
/*
Does the button support the Accessible Icon Interface?
*/
debugString ("[INFO]: bk -- Attempting to obtain the Virtual Accessible Name from the Accessible Icon information.");
final AccessibleIcon [] ai = InvocationUtils.invokeAndWait(new Callable<AccessibleIcon[]>() {
@Override
public AccessibleIcon[] call() throws Exception {
return ac.getAccessibleIcon();
}
}, ac);
if ( (null != ai) && (ai.length > 0) ) {
String iconDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
@Override
public String call() throws Exception {
return ai[0].getAccessibleIconDescription();
}
}, ac);
if (iconDescription != null){
debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the TOGGLE_BUTTON or PUSH_BUTTON object.");
references.increment (iconDescription);
return iconDescription;
}
}
} else if ( AccessibleRole.CHECK_BOX == role ) {
/*
NOTE: The only case I know of in which a check box does not
have a name is when that check box is contained in a table.
In this case it would be appropriate to use the display string
of the check box object as the name (in US English the display
string is typically either "true" or "false").
I am using the AccessibleValue interface to obtain the display
string of the check box. If the Accessible Value is 1, I am
returning Boolean.TRUE.toString (), If the Accessible Value is
0, I am returning Boolean.FALSE.toString (). If the Accessible
Value is some other number, I will return the display string of
the current numerical value of the check box.
*/
final AccessibleValue av = InvocationUtils.invokeAndWait(new Callable<AccessibleValue>() {
@Override
public AccessibleValue call() throws Exception {
return ac.getAccessibleValue();
}
}, ac);
if ( null != av ) {
nameString = null;
Number value = InvocationUtils.invokeAndWait(new Callable<Number>() {
@Override
public Number call() throws Exception {
return av.getCurrentAccessibleValue();
}
}, ac);
if ( null != value ) {
if ( 1 == value.intValue () ) {
nameString = Boolean.TRUE.toString ();
} else if ( 0 == value.intValue () ) {
nameString = Boolean.FALSE.toString ();
} else {
nameString = value.toString ();
}
if ( null != nameString ) {
references.increment (nameString);
return nameString;
}
}
}
}
return null;
}
/*
+
Beginning of the extended name search
+
*/
final AccessibleContext parentContextOuterTemp = parentContext;
String parentName = InvocationUtils.invokeAndWait(new Callable<String>() {
@Override
public String call() throws Exception {
return parentContextOuterTemp.getAccessibleName();
}
}, ac);
String parentDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
@Override
public String call() throws Exception {
return parentContextOuterTemp.getAccessibleDescription();
}
}, ac);
/*
Step 4:
=======
Special case for Slider Bar objects.
*/
if ( (AccessibleRole.SLIDER == role) &&
(AccessibleRole.PANEL == parentRole) &&
(null != parentName) ) {
debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from the Accessible Name of the SLIDER object's parent object.");
references.increment (parentName);
return parentName;
}
boolean bIsEditCombo = false;
AccessibleContext testContext = ac;
/*
Step 5:
=======
Special case for Edit Combo Boxes
*/
if ( (AccessibleRole.TEXT == role) &&
(AccessibleRole.COMBO_BOX == parentRole) ) {
bIsEditCombo = true;
if (null != parentName) {
debugString ("[INFO]: bk -- The Virtual Accessible Name for this Edit Combo box was obtained from the Accessible Name of the object's parent object.");
references.increment (parentName);
return parentName;
} else if (null != parentDescription) {
debugString ("[INFO]: bk -- The Virtual Accessible Name for this Edit Combo box was obtained from the Accessible Description of the object's parent object.");
references.increment (parentDescription);
return parentDescription;
}
testContext = parentContext;
parentRole = AccessibleRole.UNKNOWN;
parentContext = getAccessibleParentFromContext (testContext);
if ( null != parentContext ) {
final AccessibleContext parentContextInnerTemp = parentContext;
parentRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
@Override
public AccessibleRole call() throws Exception {
return parentContextInnerTemp.getAccessibleRole();
}
}, ac);
}
}
/*
Step 6:
=======
Attempt to get the Virtual Accessible Name of the object using the
Accessible Relation Set Info (the LABELED_BY Accessible Relation).
*/
{
final AccessibleContext parentContextTempInner = parentContext;
AccessibleRelationSet ars = InvocationUtils.invokeAndWait(new Callable<AccessibleRelationSet>() {
@Override
public AccessibleRelationSet call() throws Exception {
return parentContextTempInner.getAccessibleRelationSet();
}
}, ac);
if ( ars != null && (ars.size () > 0) && (ars.contains (AccessibleRelation.LABELED_BY)) ) {
AccessibleRelation labeledByRelation = ars.get (AccessibleRelation.LABELED_BY);
if (labeledByRelation != null) {
Object [] targets = labeledByRelation.getTarget ();
Object o = targets [0];
if (o instanceof Accessible) {
AccessibleContext labelContext = ((Accessible)o).getAccessibleContext ();
if (labelContext != null) {
String labelName = labelContext.getAccessibleName ();
String labelDescription = labelContext.getAccessibleDescription ();
if (null != labelName) {
debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained using the LABELED_BY AccessibleRelation -- Name Case.");
references.increment (labelName);
return labelName;
} else if (null != labelDescription) {
debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained using the LABELED_BY AccessibleRelation -- Description Case.");
references.increment (labelDescription);
return labelDescription;
}
}
}
}
}
}
//Note: add AccessibleContext to use InvocationUtils.invokeAndWait
/*
Step 7:
=======
Search for a label object that is positioned either just to the left
or just above the object and get the Accessible Name of the Label
object.
*/
int testIndexMax = 0;
int testX = 0;
int testY = 0;
int testWidth = 0;
int testHeight = 0;
int targetX = 0;
int targetY = 0;
final AccessibleContext tempContext = testContext;
int testIndex = InvocationUtils.invokeAndWait(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return tempContext.getAccessibleIndexInParent();
}
}, ac);
if ( null != parentContext ) {
final AccessibleContext parentContextInnerTemp = parentContext;
testIndexMax = InvocationUtils.invokeAndWait(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return parentContextInnerTemp.getAccessibleChildrenCount() - 1;
}
}, ac);
}
testX = getAccessibleXcoordFromContext (testContext);
testY = getAccessibleYcoordFromContext (testContext);
testWidth = getAccessibleWidthFromContext (testContext);
testHeight = getAccessibleHeightFromContext (testContext);
targetX = testX + 2;
targetY = testY + 2;
int childIndex = testIndex - 1;
/*Accessible child = null;
AccessibleContext childContext = null;
AccessibleRole childRole = AccessibleRole.UNKNOWN;*/
int childX = 0;
int childY = 0;
int childWidth = 0;
int childHeight = 0;
String childName = null;
String childDescription = null;
while (childIndex >= 0) {
final int childIndexTemp = childIndex;
final AccessibleContext parentContextInnerTemp = parentContext;
final Accessible child = InvocationUtils.invokeAndWait(new Callable<Accessible>() {
@Override
public Accessible call() throws Exception {
return parentContextInnerTemp.getAccessibleChild(childIndexTemp);
}
}, ac);
if ( null != child ) {
final AccessibleContext childContext = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
@Override
public AccessibleContext call() throws Exception {
return child.getAccessibleContext();
}
}, ac);
if ( null != childContext ) {
AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
@Override
public AccessibleRole call() throws Exception {
return childContext.getAccessibleRole();
}
}, ac);
if ( AccessibleRole.LABEL == childRole ) {
childX = getAccessibleXcoordFromContext (childContext);
childY = getAccessibleYcoordFromContext (childContext);
childWidth = getAccessibleWidthFromContext (childContext);
childHeight = getAccessibleHeightFromContext (childContext);
if ( (childX < testX) &&
((childY <= targetY) && (targetY <= (childY + childHeight))) ) {
childName = InvocationUtils.invokeAndWait(new Callable<String>() {
@Override
public String call() throws Exception {
return childContext.getAccessibleName();
}
}, ac);
if ( null != childName ) {
debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned to the left of the object.");
references.increment (childName);
return childName;
}
childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
@Override
public String call() throws Exception {
return childContext.getAccessibleDescription();
}
}, ac);
if ( null != childDescription ) {
debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned to the left of the object.");
references.increment (childDescription);
return childDescription;
}
} else if ( (childY < targetY) &&
((childX <= targetX) && (targetX <= (childX + childWidth))) ) {
childName = InvocationUtils.invokeAndWait(new Callable<String>() {
@Override
public String call() throws Exception {
return childContext.getAccessibleName();
}
}, ac);
if ( null != childName ) {
debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned above the object.");
references.increment (childName);
return childName;
}
childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
@Override
public String call() throws Exception {
return childContext.getAccessibleDescription();
}
}, ac);
if ( null != childDescription ) {
debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned above the object.");
references.increment (childDescription);
return childDescription;
}
}
}
}
}
childIndex --;
}
childIndex = testIndex + 1;
while (childIndex <= testIndexMax) {
final int childIndexTemp = childIndex;
final AccessibleContext parentContextInnerTemp = parentContext;
final Accessible child = InvocationUtils.invokeAndWait(new Callable<Accessible>() {
@Override
public Accessible call() throws Exception {
return parentContextInnerTemp.getAccessibleChild(childIndexTemp);
}
}, ac);
if ( null != child ) {
final AccessibleContext childContext = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
@Override
public AccessibleContext call() throws Exception {
return child.getAccessibleContext();
}
}, ac);
if ( null != childContext ) {
AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
@Override
public AccessibleRole call() throws Exception {
return childContext.getAccessibleRole();
}
}, ac);
if ( AccessibleRole.LABEL == childRole ) {
childX = getAccessibleXcoordFromContext (childContext);
childY = getAccessibleYcoordFromContext (childContext);
childWidth = getAccessibleWidthFromContext (childContext);
childHeight = getAccessibleHeightFromContext (childContext);
if ( (childX < testX) &&
((childY <= targetY) && (targetY <= (childY + childHeight))) ) {
childName = InvocationUtils.invokeAndWait(new Callable<String>() {
@Override
public String call() throws Exception {
return childContext.getAccessibleName();
}
}, ac);
if ( null != childName ) {
debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned to the left of the object.");
references.increment (childName);
return childName;
}
childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
@Override
public String call() throws Exception {
return childContext.getAccessibleDescription();
}
}, ac);
if ( null != childDescription ) {
debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned to the left of the object.");
references.increment (childDescription);
return childDescription;
}
} else if ( (childY < targetY) &&
((childX <= targetX) && (targetX <= (childX + childWidth))) ) {
childName = InvocationUtils.invokeAndWait(new Callable<String>() {
@Override
public String call() throws Exception {
return childContext.getAccessibleName();
}
}, ac);
if ( null != childName ) {
debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned above the object.");
references.increment (childName);
return childName;
}
childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
@Override
public String call() throws Exception {
return childContext.getAccessibleDescription();
}
}, ac);
if ( null != childDescription ) {
debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned above the object.");
references.increment (childDescription);
return childDescription;
}
}
}
}
}
childIndex ++;
}
/*
Step 8:
=======
Special case for combo boxes and text objects, based on a
similar special case I found in some of our internal JAWS code.
Search for a button object that is positioned either just to the left
or just above the object and get the Accessible Name of the button
object.
*/
if ( (AccessibleRole.TEXT == role) ||
(AccessibleRole.COMBO_BOX == role) ||
(bIsEditCombo) ) {
childIndex = testIndex - 1;
while (childIndex >= 0) {
final int childIndexTemp = childIndex;
final AccessibleContext parentContextInnerTemp = parentContext;
final Accessible child = InvocationUtils.invokeAndWait(new Callable<Accessible>() {
@Override
public Accessible call() throws Exception {
return parentContextInnerTemp.getAccessibleChild(childIndexTemp);
}
}, ac);
if ( null != child ) {
final AccessibleContext childContext = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
@Override
public AccessibleContext call() throws Exception {
return child.getAccessibleContext();
}
}, ac);
if ( null != childContext ) {
AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
@Override
public AccessibleRole call() throws Exception {
return childContext.getAccessibleRole();
}
}, ac);
if ( ( AccessibleRole.PUSH_BUTTON == childRole ) ||
( AccessibleRole.TOGGLE_BUTTON == childRole )) {
childX = getAccessibleXcoordFromContext (childContext);
childY = getAccessibleYcoordFromContext (childContext);
childWidth = getAccessibleWidthFromContext (childContext);
childHeight = getAccessibleHeightFromContext (childContext);
if ( (childX < testX) &&
((childY <= targetY) && (targetY <= (childY + childHeight))) ) {
childName = InvocationUtils.invokeAndWait(new Callable<String>() {
@Override
public String call() throws Exception {
return childContext.getAccessibleName();
}
}, ac);
if ( null != childName ) {
debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Name of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
references.increment (childName);
return childName;
}
childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
@Override
public String call() throws Exception {
return childContext.getAccessibleDescription();
}
}, ac);
if ( null != childDescription ) {
debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Description of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
references.increment (childDescription);
return childDescription;
}
}
}
}
}
childIndex --;
}
childIndex = testIndex + 1;
while (childIndex <= testIndexMax) {
final int childIndexTemp = childIndex;
final AccessibleContext parentContextInnerTemp = parentContext;
final Accessible child = InvocationUtils.invokeAndWait(new Callable<Accessible>() {
@Override
public Accessible call() throws Exception {
return parentContextInnerTemp.getAccessibleChild(childIndexTemp);
}
}, ac);
if ( null != child ) {
final AccessibleContext childContext = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
@Override
public AccessibleContext call() throws Exception {
return child.getAccessibleContext();
}
}, ac);
if ( null != childContext ) {
AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
@Override
public AccessibleRole call() throws Exception {
return childContext.getAccessibleRole();
}
}, ac);
if ( ( AccessibleRole.PUSH_BUTTON == childRole ) ||
( AccessibleRole.TOGGLE_BUTTON == childRole ) ) {
childX = getAccessibleXcoordFromContext (childContext);
childY = getAccessibleYcoordFromContext (childContext);
childWidth = getAccessibleWidthFromContext (childContext);
childHeight = getAccessibleHeightFromContext (childContext);
if ( (childX < testX) &&
((childY <= targetY) && (targetY <= (childY + childHeight))) ) {
childName = InvocationUtils.invokeAndWait(new Callable<String>() {
@Override
public String call() throws Exception {
return childContext.getAccessibleName();
}
}, ac);
if ( null != childName ) {
debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Name of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
references.increment (childName);
return childName;
}
childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
@Override
public String call() throws Exception {
return childContext.getAccessibleDescription();
}
}, ac);
if ( null != childDescription ) {
debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Description of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
references.increment (childDescription);
return childDescription;
}
}
}
}
}
childIndex ++;
}
}
return null;
} else {
debugString ("[ERROR]: AccessBridge::getVirtualAccessibleNameFromContext error - ac == null.");
return null;
}
}