>> I've spent the better part of a day in the debugger, but ultimately figured it out.
you're bill-able. Put it on the time sheet. :) zahid https://www.backbutton.org ¯\_(ツ)_/¯ ♡۶♡۶ ♡۶ On Fri, 13 Aug 2021, 12:15 Martin Gainty, <mgai...@hotmail.com> wrote: > Assuming you can locate Struts version which supports CollectionConverter > and implementor DefaultTypeConverter codebase > > You will of course need to code at least one testcase to make sure > MyStringToCollectionConverter works > > Once testcase is coded and works > can you submit MyStringToCollectionConverter and TestCase as Struts patch > to CollectionConverter code base? > > Thanks Burton! > M- > > ________________________________ > From: Burton Rhodes <burtonrho...@gmail.com> > Sent: Thursday, August 12, 2021 9:07 AM > To: Struts Users Mailing List <user@struts.apache.org> > Subject: Re: How to implement custom StrutsTypeConverter to convert String > to Collection? > > Thanks Zahid - > I've spent the better part of a day in the debugger, but ultimately figured > it out. Essentially, I first needed to use the DefaultTypeConverter to > parse the individual elements, then use the CollectionConverter to place > the elements into the final Collection needed for the Action. In case > anyone is interested, here is my final code that converts a comma separated > string into a collection using a custom Struts type converter: > > /** > * Converter class to convert comma separated string to a collection > * (e.g. form input value of "[a,b,c]" -> Set<AnyClass>()) > */ > public class MyStringToCollectionConverter extends DefaultTypeConverter { > > private ObjectTypeDeterminer objectTypeDeterminer; > > @Inject > public void setObjectTypeDeterminer(ObjectTypeDeterminer determiner) { > this.objectTypeDeterminer = determiner; > } > > @Override > public Object convertValue(Map<String, Object> context, Object target, > Member member, String propertyName, Object value, Class toType) { > > // Clean up and parse values into [] > String s = ((String[]) value)[0]; > String temp = s.replaceAll("[\\[\\]\"']", ""); > String[] cleanedValues = Arrays.stream(temp.split(",")) > .map(String::trim) > .filter(StringUtils::isNotBlank) > .toArray(String[]::new); > > // Convert values into an Object[] of "memberType" > Class<?> memberType = > objectTypeDeterminer.getElementClass(target.getClass(), propertyName, > null); > Object[] convertedValues = Arrays.stream(cleanedValues) > .map(val -> convertValue(val, memberType)) > .toArray(); > > // Use CollectionConverter to convert values into the expected > collection > CollectionConverter collectionConverter = new > CollectionConverter(); > collectionConverter.setObjectTypeDeterminer(objectTypeDeterminer); > return collectionConverter.convertValue(context, target, member, > propertyName, convertedValues, toType); > } > } > > > On Wed, Aug 11, 2021 at 6:49 PM Zahid Rahman <zahidr1...@gmail.com> wrote: > > > > I have a html form input that submits a string value that needs to be > > converted to a java Collection. > > > > To find the bug in logic > > I would hard code a string which is expected from html input form. > > > > Using an IDE . > > > > Set a break point there to go into debug mode. > > > > Step through the code one step at a time. > > Watch the string values changes > > In the debug window. > > Then you can see the data values change as expected or not at each > step. > > > > > > > > > > zahid > > > > > > > > https://www.backbutton.org > > > > ¯\_(ツ)_/¯ > > ♡۶♡۶ ♡۶ > > > > > > On Wed, 11 Aug 2021, 13:50 Burton Rhodes, <burtonrho...@gmail.com> > wrote: > > > > > I have a html form input that submits a string value that needs to be > > > converted to a java Collection (a Set object in this case). > Specifically > > > the input key/value is: viewTasksFilter.taskStatuses="[OPEN,COMPLETE]". > > > In the "viewTaskFilter" object, "taskStatuses" is defined as a Set > with > > > enum values (Set<TaskStatus> taskStatuses). The custom converter below > > > does convert the input form value to a Set, however it is a Set<String> > > > (not Set<TaskStatus>). This is an issue because the Struts Action > member > > > variable "viewTasksFilter.taskStatuses" now contains a Set of the wrong > > > type. Since I will have other variables that need this logic, I would > > > prefer not to hardcode the Set<TaskStatus> in this converter. Is > there a > > > way to use existing Struts "converter code" to convert the Set<String> > to > > > the appropriate Set<Object>? I know the built-in Struts converters > > already > > > do this, but I am unable to figure out how to do this in a custom > > > converter. Is this possible? Or is this even the right way to solve > > this > > > issue? Any help is appreciated! > > > > > > > > > /** > > > * Converter class to convert comma separated string to a collection > > > */ > > > public class MyStringToCollectionConverter extends StrutsTypeConverter > { > > > > > > @Override > > > public Object convertFromString(Map context, String[] values, Class > > > toClass) { > > > > > > String s = values[0]; > > > String temp = s.replaceAll("[\\[\\]\"']", ""); > > > List<String> cleanedValues = Arrays.stream(temp.split(",")) > > > .map(String::trim) > > > .collect(Collectors.toList()); > > > > > > if (toClass == Set.class) { > > > try { > > > if (cleanedValues.size() == 0) { > > > return null; > > > } else { > > > return new HashSet<>(cleanedValues); > > > } > > > } catch (Exception e) { > > > throw new TypeConversionException("Could not parse to > Set > > > class:" + Arrays.toString(values)); > > > } > > > > > > } else if (toClass == List.class) { > > > try { > > > if (cleanedValues.size() == 0) { > > > return null; > > > } else { > > > return cleanedValues; > > > } > > > } catch (Exception e) { > > > throw new TypeConversionException("Could not parse to > > List > > > class:" + Arrays.toString(values)); > > > } > > > > > > } > > > > > > return null; > > > } > > > > > > @Override > > > public String convertToString(Map context, Object o) { > > > if (o == null) { > > > return null; > > > } else { > > > return o.toString(); > > > } > > > } > > > } > > > > > > >