All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.holonplatform.vaadin.internal.components.MultiSelectField Maven / Gradle / Ivy

There is a newer version: 5.4.0
Show newest version
/*
 * Copyright 2016-2017 Axioma srl.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.holonplatform.vaadin.internal.components;

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;

import com.holonplatform.core.datastore.DataTarget;
import com.holonplatform.core.datastore.Datastore;
import com.holonplatform.core.internal.utils.ObjectUtils;
import com.holonplatform.core.property.PathProperty;
import com.holonplatform.core.property.Property;
import com.holonplatform.core.property.PropertyBox;
import com.holonplatform.core.property.PropertySet;
import com.holonplatform.core.query.QueryConfigurationProvider;
import com.holonplatform.vaadin.components.Field;
import com.holonplatform.vaadin.components.MultiSelect;
import com.holonplatform.vaadin.components.builders.BaseSelectInputBuilder.RenderingMode;
import com.holonplatform.vaadin.components.builders.BaseSelectModeMultiPropertySelectInputBuilder.OptionsModeMultiPropertySelectInputBuilder;
import com.holonplatform.vaadin.components.builders.BaseSelectModeMultiPropertySelectInputBuilder.SelectModeMultiPropertySelectInputBuilder;
import com.holonplatform.vaadin.components.builders.BaseSelectModeMultiSelectInputBuilder.OptionsModeMultiSelectInputBuilder;
import com.holonplatform.vaadin.components.builders.BaseSelectModeMultiSelectInputBuilder.SelectModeMultiSelectInputBuilder;
import com.holonplatform.vaadin.components.builders.MultiPropertySelectInputBuilder;
import com.holonplatform.vaadin.components.builders.MultiPropertySelectInputBuilder.GenericMultiPropertySelectInputBuilder;
import com.holonplatform.vaadin.components.builders.MultiSelectInputBuilder;
import com.holonplatform.vaadin.components.builders.MultiSelectInputBuilder.GenericMultiSelectInputBuilder;
import com.holonplatform.vaadin.data.ItemConverter;
import com.holonplatform.vaadin.data.ItemDataProvider;
import com.holonplatform.vaadin.internal.components.builders.AbstractSelectFieldBuilder;
import com.holonplatform.vaadin.internal.data.PropertyItemIdentifier;
import com.vaadin.data.Converter;
import com.vaadin.data.HasDataProvider;
import com.vaadin.data.provider.DataProvider;
import com.vaadin.data.provider.Query;
import com.vaadin.event.selection.MultiSelectionEvent;
import com.vaadin.server.SerializableFunction;
import com.vaadin.server.SerializablePredicate;
import com.vaadin.ui.AbstractMultiSelect;
import com.vaadin.ui.CheckBoxGroup;
import com.vaadin.ui.ComboBox.CaptionFilter;
import com.vaadin.ui.ListSelect;

/**
 * Default multiple select {@link Field} implementation.
 * 
 * @param  Field type
 * 
 * @since 5.0.0
 */
public class MultiSelectField
		extends AbstractSelectField, T, ITEM, Set, AbstractMultiSelect> implements MultiSelect {

	private static final long serialVersionUID = -7662977233168084151L;

	/**
	 * Constructor
	 * @param type Selection value type
	 * @param renderingMode Rendering mode
	 */
	@SuppressWarnings("unchecked")
	public MultiSelectField(Class type, RenderingMode renderingMode) {
		super((Class>) (Class) Set.class, renderingMode);
	}

	/*
	 * (non-Javadoc)
	 * @see com.holonplatform.vaadin.internal.components.AbstractCustomField#buildInternalField(java.lang.Class)
	 */
	@Override
	protected AbstractMultiSelect buildInternalField(Class> type) {
		RenderingMode mode = getRenderingMode();
		if (mode == null) {
			mode = RenderingMode.OPTIONS;
		}

		if (mode == RenderingMode.OPTIONS) {
			final CheckBoxGroup field = new CheckBoxGroup<>();
			field.setItemCaptionGenerator(i -> generateItemCaption(i));
			field.setItemIconGenerator(i -> generateItemIcon(i));
			field.addSelectionListener(e -> fireSelectionListeners(buildSelectionEvent(e)));
			return field;
		}

		final ListSelect field = new ListSelect<>();
		field.setItemCaptionGenerator(i -> generateItemCaption(i));
		field.addSelectionListener(e -> fireSelectionListeners(buildSelectionEvent(e)));
		return field;
	}

	protected SelectionEvent buildSelectionEvent(MultiSelectionEvent event) {
		return new DefaultSelectionEvent<>(fromInternalValue(event.getAllSelectedItems()), event.isUserOriginated());
	}

	/*
	 * (non-Javadoc)
	 * @see com.holonplatform.vaadin.internal.components.AbstractCustomField#fromInternalValue(java.lang.Object)
	 */
	@Override
	protected Set fromInternalValue(Set value) {
		if (value != null) {
			final Set set = new HashSet<>(value.size());
			value.forEach(v -> set.add(toSelection(v)));
			return set;
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * @see com.holonplatform.vaadin.internal.components.AbstractCustomField#toInternalValue(java.lang.Object)
	 */
	@Override
	protected Set toInternalValue(Set value) {
		if (value != null) {
			final Set set = new HashSet<>(value.size());
			value.forEach(v -> set.add(toItem(v)));
			return set;
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * @see com.holonplatform.vaadin.internal.components.AbstractSelectField#setItems(java.util.Collection)
	 */
	@Override
	public void setItems(Collection items) {
		getInternalField().setItems(items);
	}

	/*
	 * (non-Javadoc)
	 * @see com.holonplatform.vaadin.internal.components.AbstractSelectField#setDataProvider(com.vaadin.data.provider.
	 * DataProvider)
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public void setDataProvider(DataProvider dataProvider) {
		if (getInternalField() instanceof HasDataProvider) {
			((HasDataProvider) getInternalField()).setDataProvider(dataProvider);
		}
	}

	/*
	 * (non-Javadoc)
	 * @see com.holonplatform.vaadin.internal.components.AbstractSelectField#setDataProvider(com.vaadin.data.provider.
	 * DataProvider, com.vaadin.server.SerializableFunction)
	 */
	@Override
	public void setDataProvider(DataProvider dataProvider, SerializableFunction filterConverter) {
		setDataProvider(dataProvider);
	}

	/*
	 * (non-Javadoc)
	 * @see com.holonplatform.vaadin.internal.components.AbstractSelectField#setItems(java.util.Collection,
	 * com.vaadin.ui.ComboBox.CaptionFilter)
	 */
	@Override
	public void setItems(Collection items, CaptionFilter filter) {
		setItems(items);
	}

	/*
	 * (non-Javadoc)
	 * @see com.holonplatform.vaadin.internal.components.AbstractSelectField#getDataProvider()
	 */
	@Override
	public Optional> getDataProvider() {
		return Optional.ofNullable(getInternalField().getDataProvider());
	}

	/*
	 * (non-Javadoc)
	 * @see com.holonplatform.vaadin.components.Selectable#getSelectedItems()
	 */
	@Override
	public Set getSelectedItems() {
		final Set value = getValue();
		return (value != null) ? Collections.unmodifiableSet(value) : Collections.emptySet();
	}

	/*
	 * (non-Javadoc)
	 * @see com.holonplatform.vaadin.components.Selectable#deselectAll()
	 */
	@Override
	public void deselectAll() {
		clear();
	}

	/*
	 * (non-Javadoc)
	 * @see com.holonplatform.vaadin.components.MultiSelect#select(java.lang.Iterable)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void select(Iterable items) {
		ObjectUtils.argumentNotNull(items, "Items to select must be not null");
		final Set set = new HashSet<>();
		items.forEach(i -> {
			ObjectUtils.argumentNotNull(i, "Items to select must be not null");
			set.add(i);
		});
		Set toSelect = toInternalValue(set);
		getInternalField().select((ITEM[]) toSelect.toArray());
	}

	/*
	 * (non-Javadoc)
	 * @see com.holonplatform.vaadin.components.MultiSelect#deselect(java.lang.Iterable)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void deselect(Iterable items) {
		ObjectUtils.argumentNotNull(items, "Items to deselect must be not null");
		final Set set = new HashSet<>();
		items.forEach(i -> {
			if (i != null) {
				set.add(i);
			}
		});
		Set toDeselect = toInternalValue(set);
		getInternalField().deselect((ITEM[]) toDeselect.toArray());
	}

	/*
	 * (non-Javadoc)
	 * @see com.holonplatform.vaadin.components.MultiSelect#selectAll()
	 */
	@Override
	public void selectAll() {
		getDataProvider().ifPresent(dp -> {
			Stream allItemsStream = dp.fetch(new Query<>());
			LinkedHashSet allItems = new LinkedHashSet<>();
			allItemsStream.forEach(allItems::add);
			getInternalField().setValue(allItems);
		});
	}

	public void setRows(int rows) {
		if (getInternalField() instanceof ListSelect) {
			((ListSelect) getInternalField()).setRows(rows);
		}
	}

	public void setHtmlContentAllowed(boolean htmlContentAllowed) {
		if (getInternalField() instanceof CheckBoxGroup) {
			((CheckBoxGroup) getInternalField()).setHtmlContentAllowed(htmlContentAllowed);
		}
	}

	@SuppressWarnings("unchecked")
	public void setItemEnabledProvider(SerializablePredicate itemEnabledProvider) {
		if (getInternalField() instanceof CheckBoxGroup) {
			((CheckBoxGroup) getInternalField()).setItemEnabledProvider(itemEnabledProvider);
		}
	}

	// Builder

	/**
	 * Base {@link MultiSelect} builder.
	 * @param  Selection type
	 */
	public static abstract class Builder>
			extends AbstractSelectFieldBuilder, MultiSelect, T, T, MultiSelectField, B>
			implements MultiSelectInputBuilder {

		/**
		 * Constructor
		 * @param type Selection value type
		 * @param renderingMode Rendering mode
		 */
		public Builder(Class type, RenderingMode renderingMode) {
			super(new MultiSelectField<>(type, renderingMode));
			getInstance().setItemConverter(Converter.identity());
		}

		/*
		 * (non-Javadoc)
		 * @see
		 * com.holonplatform.vaadin.components.builders.MultiSelectFieldBuilder#dataSource(com.holonplatform.vaadin.
		 * data.ItemDataProvider)
		 */
		@Override
		public B dataSource(ItemDataProvider dataProvider) {
			ObjectUtils.argumentNotNull(dataProvider, "Item data provider must be not null");
			this.itemDataProvider = dataProvider;
			return builder();
		}

		/*
		 * (non-Javadoc)
		 * @see
		 * com.holonplatform.vaadin.components.builders.SelectItemDataSourceBuilder#dataSource(com.vaadin.data.provider.
		 * DataProvider)
		 */
		@Override
		public B dataSource(DataProvider dataProvider) {
			this.dataProvider = dataProvider;
			return builder();
		}

		/*
		 * (non-Javadoc)
		 * @see com.holonplatform.vaadin.components.builders.SelectFieldBuilder#items(java.lang.Iterable)
		 */
		@Override
		public B items(Iterable items) {
			ObjectUtils.argumentNotNull(items, "Items must be not null");
			this.items.clear();
			items.forEach(i -> this.items.add(i));
			return builder();
		}

		/*
		 * (non-Javadoc)
		 * @see com.holonplatform.vaadin.components.builders.SelectFieldBuilder#addItem(java.lang.Object)
		 */
		@Override
		public B addItem(T item) {
			ObjectUtils.argumentNotNull(item, "Item must be not null");
			this.items.add(item);
			return builder();
		}

		/*
		 * (non-Javadoc)
		 * @see com.holonplatform.vaadin.internal.components.builders.AbstractSelectFieldBuilder#buildSelect(com.
		 * holonframework.vaadin.internal.components.AbstractSelectField)
		 */
		@Override
		protected MultiSelect buildSelect(MultiSelectField instance) {
			return instance;
		}

		/*
		 * (non-Javadoc)
		 * @see com.holonplatform.vaadin.internal.components.builders.AbstractSelectFieldBuilder#buildSelectAsField(com.
		 * holonplatform.vaadin.internal.components.AbstractSelectField)
		 */
		@Override
		protected Field> buildSelectAsField(MultiSelectField instance) {
			return instance;
		}

	}

	public static class GenericBuilder extends Builder>
			implements GenericMultiSelectInputBuilder {

		public GenericBuilder(Class type, RenderingMode renderingMode) {
			super(type, renderingMode);
		}

		@Override
		protected GenericMultiSelectInputBuilder builder() {
			return this;
		}

	}

	public static class SelectModeBuilder extends Builder>
			implements SelectModeMultiSelectInputBuilder {

		public SelectModeBuilder(Class type) {
			super(type, RenderingMode.SELECT);
		}

		/*
		 * (non-Javadoc)
		 * @see com.holonplatform.vaadin.components.builders.BaseSelectModeMultiSelectInputBuilder.
		 * SelectModeMultiSelectInputBuilder#rows(int)
		 */
		@Override
		public SelectModeMultiSelectInputBuilder rows(int rows) {
			getInstance().setRows(rows);
			return this;
		}

		/*
		 * (non-Javadoc)
		 * @see com.holonplatform.vaadin.internal.components.builders.AbstractComponentConfigurator#builder()
		 */
		@Override
		protected SelectModeMultiSelectInputBuilder builder() {
			return this;
		}

	}

	public static class OptionsModeBuilder extends Builder>
			implements OptionsModeMultiSelectInputBuilder {

		public OptionsModeBuilder(Class type) {
			super(type, RenderingMode.OPTIONS);
		}

		/*
		 * (non-Javadoc)
		 * @see com.holonplatform.vaadin.components.builders.BaseSelectModeMultiSelectInputBuilder.
		 * OptionsModeMultiSelectInputBuilder#htmlContentAllowed(boolean)
		 */
		@Override
		public OptionsModeMultiSelectInputBuilder htmlContentAllowed(boolean htmlContentAllowed) {
			getInstance().setHtmlContentAllowed(htmlContentAllowed);
			return this;
		}

		/*
		 * (non-Javadoc)
		 * @see com.holonplatform.vaadin.components.builders.BaseSelectModeMultiSelectInputBuilder.
		 * OptionsModeMultiSelectInputBuilder#itemEnabledProvider(com.vaadin.server.SerializablePredicate)
		 */
		@Override
		public OptionsModeMultiSelectInputBuilder itemEnabledProvider(SerializablePredicate itemEnabledProvider) {
			ObjectUtils.argumentNotNull(itemEnabledProvider, "ItemEnabledProvider must be not null");
			getInstance().setItemEnabledProvider(itemEnabledProvider);
			return this;
		}

		/*
		 * (non-Javadoc)
		 * @see com.holonplatform.vaadin.internal.components.builders.AbstractComponentConfigurator#builder()
		 */
		@Override
		protected OptionsModeMultiSelectInputBuilder builder() {
			return this;
		}

	}

	// Property

	/**
	 * Base {@link MultiSelect} builder with {@link Property} data source support.
	 * @param  Selection type
	 */
	public static abstract class PropertyBuilder> extends
			AbstractSelectFieldBuilder, MultiSelect, T, PropertyBox, MultiSelectField, B>
			implements MultiPropertySelectInputBuilder {

		private final Property selectProperty;

		/**
		 * Constructor
		 * @param selectProperty Selection (and identifier) property
		 * @param renderingMode Rendering mode
		 */
		@SuppressWarnings({ "unchecked", "rawtypes" })
		public PropertyBuilder(Property selectProperty, RenderingMode renderingMode) {
			super(new MultiSelectField<>(selectProperty.getType(), renderingMode));
			this.selectProperty = selectProperty;
			itemIdentifier = new PropertyItemIdentifier(selectProperty);
		}

		/*
		 * (non-Javadoc)
		 * @see com.holonplatform.vaadin.components.builders.PropertySelectInputBuilder#itemConverter(com.holonplatform.
		 * vaadin.data.ItemConverter)
		 */
		@Override
		public B itemConverter(ItemConverter itemConverter) {
			getInstance().setItemConverter(new ReversiblePropertyBoxConverter<>(selectProperty, itemConverter));
			return builder();
		}

		/*
		 * (non-Javadoc)
		 * @see
		 * com.holonplatform.vaadin.components.builders.PropertySelectFieldBuilder#dataSource(com.holonplatform.vaadin
		 * .data.ItemDataProvider)
		 */
		@Override
		public B dataSource(ItemDataProvider dataProvider) {
			ObjectUtils.argumentNotNull(dataProvider, "ItemDataProvider must be not null");
			this.itemDataProvider = dataProvider;
			return builder();
		}

		/*
		 * (non-Javadoc)
		 * @see
		 * com.holonplatform.vaadin.components.builders.PropertySelectInputBuilder#dataSource(com.holonplatform.core.
		 * datastore.Datastore, com.holonplatform.core.datastore.DataTarget, java.lang.Iterable,
		 * com.holonplatform.core.query.QueryConfigurationProvider[])
		 */
		@Override
		public 

> B dataSource(Datastore datastore, DataTarget dataTarget, Iterable

properties, QueryConfigurationProvider... queryConfigurationProviders) { MultiPropertySelectInputBuilder.super.dataSource(datastore, dataTarget, properties, queryConfigurationProviders); setupItemConverter(datastore, dataTarget, properties); return builder(); } /* * (non-Javadoc) * @see * com.holonplatform.vaadin.components.builders.PropertySelectInputBuilder#dataSource(com.holonplatform.core. * datastore.Datastore, com.holonplatform.core.datastore.DataTarget, com.holonplatform.core.property.Property[]) */ @SuppressWarnings("unchecked") @Override public

> B dataSource(Datastore datastore, DataTarget dataTarget, P... properties) { MultiPropertySelectInputBuilder.super.dataSource(datastore, dataTarget, properties); setupItemConverter(datastore, dataTarget, PropertySet.of(properties)); return builder(); } @SuppressWarnings({ "rawtypes", "unchecked" }) protected

> void setupItemConverter(Datastore datastore, DataTarget dataTarget, Iterable

properties) { if (selectProperty != null && PathProperty.class.isAssignableFrom(selectProperty.getClass()) && !getInstance().getItemConverter().isPresent()) { itemConverter(value -> { if (value != null) { return datastore.query().target(dataTarget).filter(((PathProperty) selectProperty).eq(value)) .findOne(properties).orElse(null); } return null; }); } } /* * (non-Javadoc) * @see * com.holonplatform.vaadin.internal.components.builders.AbstractSelectFieldBuilder#preSetup(com.holonplatform. * vaadin.internal.components.AbstractSelectField) */ @Override protected void preSetup(MultiSelectField instance) { if (!instance.getItemConverter().isPresent()) { instance.setItemConverter(new DefaultPropertyBoxConverter<>(selectProperty)); } super.preSetup(instance); } /* * (non-Javadoc) * @see com.holonplatform.vaadin.internal.components.builders.AbstractSelectFieldBuilder#buildSelect(com. * holonframework.vaadin.internal.components.AbstractSelectField) */ @Override protected MultiSelect buildSelect(MultiSelectField instance) { return instance; } /* * (non-Javadoc) * @see com.holonplatform.vaadin.internal.components.builders.AbstractSelectFieldBuilder#buildSelectAsField(com. * holonplatform.vaadin.internal.components.AbstractSelectField) */ @Override protected Field> buildSelectAsField(MultiSelectField instance) { return instance; } } public static class GenericPropertyBuilder extends PropertyBuilder> implements GenericMultiPropertySelectInputBuilder { public GenericPropertyBuilder(Property selectProperty, RenderingMode renderingMode) { super(selectProperty, renderingMode); } @Override protected GenericMultiPropertySelectInputBuilder builder() { return this; } } public static class SelectModePropertyBuilder extends PropertyBuilder> implements SelectModeMultiPropertySelectInputBuilder { public SelectModePropertyBuilder(Property selectProperty) { super(selectProperty, RenderingMode.SELECT); } /* * (non-Javadoc) * @see com.holonplatform.vaadin.components.builders.BaseSelectModeMultiPropertySelectInputBuilder. * SelectModeMultiPropertySelectInputBuilder#rows(int) */ @Override public SelectModeMultiPropertySelectInputBuilder rows(int rows) { getInstance().setRows(rows); return this; } /* * (non-Javadoc) * @see com.holonplatform.vaadin.internal.components.builders.AbstractComponentConfigurator#builder() */ @Override protected SelectModeMultiPropertySelectInputBuilder builder() { return this; } } public static class OptionsModePropertyBuilder extends PropertyBuilder> implements OptionsModeMultiPropertySelectInputBuilder { public OptionsModePropertyBuilder(Property selectProperty) { super(selectProperty, RenderingMode.OPTIONS); } /* * (non-Javadoc) * @see com.holonplatform.vaadin.components.builders.BaseSelectModeMultiPropertySelectInputBuilder. * OptionsModeMultiPropertySelectInputBuilder#htmlContentAllowed(boolean) */ @Override public OptionsModeMultiPropertySelectInputBuilder htmlContentAllowed(boolean htmlContentAllowed) { getInstance().setHtmlContentAllowed(htmlContentAllowed); return this; } /* * (non-Javadoc) * @see com.holonplatform.vaadin.components.builders.BaseSelectModeMultiPropertySelectInputBuilder. * OptionsModeMultiPropertySelectInputBuilder#itemEnabledProvider(com.vaadin.server.SerializablePredicate) */ @Override public OptionsModeMultiPropertySelectInputBuilder itemEnabledProvider( SerializablePredicate itemEnabledProvider) { ObjectUtils.argumentNotNull(itemEnabledProvider, "ItemEnabledProvider must be not null"); getInstance().setItemEnabledProvider(itemEnabledProvider); return this; } /* * (non-Javadoc) * @see com.holonplatform.vaadin.internal.components.builders.AbstractComponentConfigurator#builder() */ @Override protected OptionsModeMultiPropertySelectInputBuilder builder() { return this; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy