/** * Creates an iterator that returns an {@link Options} containing each possible parameter set * defined by these {@link * com.biomatters.plugins.barcoding.validator.research.options.BatchOptions}. Note that the {@link * Options} object returned is always the same to save on initializing multiple copies. Each time * {@link java.util.Iterator#next()} is called the next parameter set is set on the {@link * Options}. * * @return An iterator that will iterate over all possible parameter sets specified by this {@link * com.biomatters.plugins.barcoding.validator.research.options.BatchOptions} * @throws DocumentOperationException if there is a problem creating the {@link Options} object */ public Iterator<T> iterator() throws DocumentOperationException { List<Set<OptionToSet>> possibleValues = new ArrayList<Set<OptionToSet>>(); Map<String, MultiValueOption<?>> multiValueOptions = getMultiValueOptions("", options); for (Map.Entry<String, MultiValueOption<?>> entry : multiValueOptions.entrySet()) { possibleValues.add(getOptionsToSet(entry.getKey(), entry.getValue())); } Set<List<OptionToSet>> lists = Sets.cartesianProduct(possibleValues); final Iterator<List<OptionToSet>> possibilityIterator = lists.iterator(); final T template; try { //noinspection unchecked template = (T) options.getClass().newInstance(); // getClass() doesn't return Class<T> :( template.valuesFromXML(options.valuesToXML(XMLSerializable.ROOT_ELEMENT_NAME)); } catch (InstantiationException e) { throw new DocumentOperationException("Failed to create Options: " + e.getMessage(), e); } catch (IllegalAccessException e) { throw new DocumentOperationException("Failed to create Options: " + e.getMessage(), e); } return new Iterator<T>() { @Override public boolean hasNext() { return possibilityIterator.hasNext(); } @Override public T next() { List<OptionToSet> possibility = possibilityIterator.next(); for (OptionToSet optionToSet : possibility) { template.setValue(optionToSet.name, optionToSet.value); } return template; } @Override public void remove() { new UnsupportedOperationException(); } }; }