11package org .labkey .test .components .ui .grids ;
22
3- import org .apache . commons . lang3 . mutable . Mutable ;
4- import org .apache . commons . lang3 . mutable . MutableObject ;
3+ import org .jetbrains . annotations . NotNull ;
4+ import org .jetbrains . annotations . Nullable ;
55import org .labkey .test .params .FieldKey ;
66import org .labkey .test .params .WrapsFieldKey ;
7+ import org .labkey .test .util .CachingSupplier ;
78import org .labkey .test .util .selenium .WebElementUtils ;
89import org .openqa .selenium .NoSuchElementException ;
910import org .openqa .selenium .WebElement ;
1011
11- import java .util .Collections ;
1212import java .util .LinkedHashMap ;
1313import java .util .List ;
1414import java .util .Map ;
1515import java .util .Objects ;
16+ import java .util .function .Function ;
1617import java .util .function .Supplier ;
18+ import java .util .stream .Collectors ;
1719
1820public class FieldReferenceManager
1921{
2022 private final List <FieldReference > _fieldReferences ;
21- private final Map <FieldKey , FieldReference > fieldKeys = new LinkedHashMap <>();
22- private final Map <String , FieldReference > fieldLabels = new LinkedHashMap <>();
23+ private final Map <Integer , FieldReference > _fieldsByIndex ;
24+ private final Map <FieldKey , FieldReference > _fieldKeys = new LinkedHashMap <>();
25+ private final Map <String , FieldReference > _fieldLabels = new LinkedHashMap <>();
2326
2427 public <T extends FieldReference > FieldReferenceManager (List <T > columnHeaders )
2528 {
26- this ._fieldReferences = Collections .unmodifiableList (columnHeaders );
29+ _fieldReferences = List .copyOf (columnHeaders );
30+ _fieldsByIndex = columnHeaders .stream ().collect (Collectors .toMap (FieldReference ::getDomIndex , Function .identity ()));
2731 }
2832
2933 public List <FieldReference > getColumnHeaders ()
3034 {
3135 return _fieldReferences ;
3236 }
3337
38+ public FieldReference getColumnHeader (int index )
39+ {
40+ return _fieldsByIndex .get (index );
41+ }
42+
3443 /**
3544 * Find field by uncertain field identifier in order of precedence:
3645 * <ol>
@@ -40,7 +49,7 @@ public List<FieldReference> getColumnHeaders()
4049 * <li>Field Label</li>
4150 * </ol>
4251 */
43- public final FieldReference findFieldReference (CharSequence fieldIdentifier )
52+ public final @ NotNull FieldReference findFieldReference (CharSequence fieldIdentifier )
4453 {
4554 List <Supplier <FieldReference >> options ;
4655
@@ -64,20 +73,32 @@ public final FieldReference findFieldReference(CharSequence fieldIdentifier)
6473 .orElseThrow (() -> new NoSuchElementException ("Unable to locate field: " + fieldIdentifier ));
6574 }
6675
76+ public final @ Nullable FieldReference findFieldReferenceOrNull (CharSequence fieldIdentifier )
77+ {
78+ try
79+ {
80+ return findFieldReference (fieldIdentifier );
81+ }
82+ catch (NoSuchElementException e )
83+ {
84+ return null ;
85+ }
86+ }
87+
6788 private FieldReference findColumnHeaderByFieldKey (FieldKey fieldIdentifier )
6889 {
69- if (fieldKeys .containsKey (fieldIdentifier ))
90+ if (_fieldKeys .containsKey (fieldIdentifier ))
7091 {
71- return fieldKeys .get (fieldIdentifier );
92+ return _fieldKeys .get (fieldIdentifier );
7293 }
73- else if (fieldKeys .size () < _fieldReferences .size ())
94+ else if (_fieldKeys .size () < _fieldReferences .size ())
7495 {
7596 for (FieldReference header : _fieldReferences )
7697 {
77- if (!fieldKeys .containsValue (header ))
98+ if (!_fieldKeys .containsValue (header ))
7899 {
79100 FieldKey fieldKey = header .getFieldKey ();
80- fieldKeys .put (fieldKey , header );
101+ _fieldKeys .put (fieldKey , header );
81102 if (fieldKey .equals (fieldIdentifier ))
82103 {
83104 return header ;
@@ -91,18 +112,18 @@ else if (fieldKeys.size() < _fieldReferences.size())
91112
92113 private FieldReference findColumnHeaderByLabel (String label )
93114 {
94- if (fieldLabels .containsKey (label ))
115+ if (_fieldLabels .containsKey (label ))
95116 {
96- return fieldLabels .get (label );
117+ return _fieldLabels .get (label );
97118 }
98- else if (fieldLabels .size () < _fieldReferences .size ())
119+ else if (_fieldLabels .size () < _fieldReferences .size ())
99120 {
100121 for (FieldReference header : _fieldReferences )
101122 {
102- if (!fieldLabels .containsValue (header ))
123+ if (!_fieldLabels .containsValue (header ))
103124 {
104125 String columnLabel = header .getLabel ();
105- fieldLabels .put (columnLabel , header );
126+ _fieldLabels .put (columnLabel , header );
106127 if (columnLabel .equals (label ))
107128 {
108129 return header ;
@@ -118,8 +139,8 @@ public static class FieldReference
118139 {
119140 private final WebElement _element ;
120141 private final int _domIndex ;
121- private final Mutable <String > _fieldLabel = new MutableObject <>();
122- private final Mutable <FieldKey > _fieldKey = new MutableObject <>();
142+ private final CachingSupplier <String > _fieldLabel = new CachingSupplier <>(this :: labelSupplier );
143+ private final CachingSupplier <FieldKey > _fieldKey = new CachingSupplier <>(this :: fieldKeySupplier );
123144
124145 public FieldReference (WebElement element , int domIndex )
125146 {
@@ -134,34 +155,12 @@ public WebElement getElement()
134155
135156 public FieldKey getFieldKey ()
136157 {
137- if (_fieldKey .getValue () == null )
138- {
139- String path = _element .getDomAttribute ("data-fieldkey" );
140- if (path == null )
141- {
142- // Some grids don't have a field key, but have a similar value in the ID attribute
143- path = _element .getDomAttribute ("id" );
144- }
145-
146- if (path != null )
147- {
148- _fieldKey .setValue (FieldKey .fromFieldKey (path ));
149- }
150- else
151- {
152- _fieldKey .setValue (FieldKey .EMPTY );
153- }
154- }
155- return _fieldKey .getValue ();
158+ return _fieldKey .get ();
156159 }
157160
158161 public String getLabel ()
159162 {
160- if (_fieldLabel .getValue () == null )
161- {
162- _fieldLabel .setValue (WebElementUtils .getTextContent (getElement ()).trim ());
163- }
164- return _fieldLabel .getValue ();
163+ return _fieldLabel .get ();
165164 }
166165
167166 public String getName ()
@@ -173,5 +172,29 @@ public int getDomIndex()
173172 {
174173 return _domIndex ;
175174 }
175+
176+ protected String labelSupplier ()
177+ {
178+ return WebElementUtils .getTextContent (getElement ()).trim ();
179+ }
180+
181+ protected FieldKey fieldKeySupplier ()
182+ {
183+ String path = getElement ().getDomAttribute ("data-fieldkey" );
184+ if (path == null )
185+ {
186+ // Some grids don't have a field key, but have a similar value in the ID attribute
187+ path = getElement ().getDomAttribute ("id" );
188+ }
189+
190+ if (path != null )
191+ {
192+ return FieldKey .fromFieldKey (path );
193+ }
194+ else
195+ {
196+ return FieldKey .EMPTY ;
197+ }
198+ }
176199 }
177200}
0 commit comments