diff options
author | Artur Signell <artur@vaadin.com> | 2016-08-18 22:10:47 +0300 |
---|---|---|
committer | Artur Signell <artur@vaadin.com> | 2016-08-20 00:12:18 +0300 |
commit | fe3dca081a64af892a7f4c0416ecc643aec3ec5a (patch) | |
tree | 1901fb377336d3c5a772335322d9c434a4a75e24 /server | |
parent | 65370e12a0605926cb80e205c2b0e74fefe83e5b (diff) | |
download | vaadin-framework-fe3dca081a64af892a7f4c0416ecc643aec3ec5a.tar.gz vaadin-framework-fe3dca081a64af892a7f4c0416ecc643aec3ec5a.zip |
Move remaining selects and container implementations to compatibility package
Because of dependencies also moves
Calendar, ColorPicker, SQLContainer, container filters
Change-Id: I0594cb24f20486ebbca4be578827fea7cdf92108
Diffstat (limited to 'server')
115 files changed, 4 insertions, 30350 deletions
diff --git a/server/src/main/java/com/vaadin/data/util/AbstractBeanContainer.java b/server/src/main/java/com/vaadin/data/util/AbstractBeanContainer.java deleted file mode 100644 index 995e2f8675..0000000000 --- a/server/src/main/java/com/vaadin/data/util/AbstractBeanContainer.java +++ /dev/null @@ -1,929 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util; - -import java.io.Serializable; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import com.vaadin.data.Container; -import com.vaadin.data.Container.Filterable; -import com.vaadin.data.Container.PropertySetChangeNotifier; -import com.vaadin.data.Container.SimpleFilterable; -import com.vaadin.data.Container.Sortable; -import com.vaadin.data.Item; -import com.vaadin.data.Property; -import com.vaadin.data.Property.ValueChangeEvent; -import com.vaadin.data.Property.ValueChangeListener; -import com.vaadin.data.Property.ValueChangeNotifier; -import com.vaadin.data.util.MethodProperty.MethodException; -import com.vaadin.data.util.filter.SimpleStringFilter; -import com.vaadin.data.util.filter.UnsupportedFilterException; - -/** - * An abstract base class for in-memory containers for JavaBeans. - * - * <p> - * The properties of the container are determined automatically by introspecting - * the used JavaBean class and explicitly adding or removing properties is not - * supported. Only beans of the same type can be added to the container. - * </p> - * - * <p> - * Subclasses should implement any public methods adding items to the container, - * typically calling the protected methods {@link #addItem(Object, Object)}, - * {@link #addItemAfter(Object, Object, Object)} and - * {@link #addItemAt(int, Object, Object)}. - * </p> - * - * @param <IDTYPE> - * The type of the item identifier - * @param <BEANTYPE> - * The type of the Bean - * - * @since 6.5 - */ -public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> - extends AbstractInMemoryContainer<IDTYPE, String, BeanItem<BEANTYPE>> - implements Filterable, SimpleFilterable, Sortable, ValueChangeListener, - PropertySetChangeNotifier { - - /** - * Resolver that maps beans to their (item) identifiers, removing the need - * to explicitly specify item identifiers when there is no need to customize - * this. - * - * Note that beans can also be added with an explicit id even if a resolver - * has been set. - * - * @param <IDTYPE> - * @param <BEANTYPE> - * - * @since 6.5 - */ - public static interface BeanIdResolver<IDTYPE, BEANTYPE> - extends Serializable { - /** - * Return the item identifier for a bean. - * - * @param bean - * @return - */ - public IDTYPE getIdForBean(BEANTYPE bean); - } - - /** - * A item identifier resolver that returns the value of a bean property. - * - * The bean must have a getter for the property, and the getter must return - * an object of type IDTYPE. - */ - protected class PropertyBasedBeanIdResolver - implements BeanIdResolver<IDTYPE, BEANTYPE> { - - private final Object propertyId; - - public PropertyBasedBeanIdResolver(Object propertyId) { - if (propertyId == null) { - throw new IllegalArgumentException( - "Property identifier must not be null"); - } - this.propertyId = propertyId; - } - - @Override - @SuppressWarnings("unchecked") - public IDTYPE getIdForBean(BEANTYPE bean) - throws IllegalArgumentException { - VaadinPropertyDescriptor<BEANTYPE> pd = model.get(propertyId); - if (null == pd) { - throw new IllegalStateException( - "Property " + propertyId + " not found"); - } - try { - Property<IDTYPE> property = (Property<IDTYPE>) pd - .createProperty(bean); - return property.getValue(); - } catch (MethodException e) { - throw new IllegalArgumentException(e); - } - } - - } - - /** - * The resolver that finds the item ID for a bean, or null not to use - * automatic resolving. - * - * Methods that add a bean without specifying an ID must not be called if no - * resolver has been set. - */ - private BeanIdResolver<IDTYPE, BEANTYPE> beanIdResolver = null; - - /** - * Maps all item ids in the container (including filtered) to their - * corresponding BeanItem. - */ - private final Map<IDTYPE, BeanItem<BEANTYPE>> itemIdToItem = new HashMap<IDTYPE, BeanItem<BEANTYPE>>(); - - /** - * The type of the beans in the container. - */ - private final Class<? super BEANTYPE> type; - - /** - * A description of the properties found in beans of type {@link #type}. - * Determines the property ids that are present in the container. - */ - private final LinkedHashMap<String, VaadinPropertyDescriptor<BEANTYPE>> model; - - /** - * Constructs a {@code AbstractBeanContainer} for beans of the given type. - * - * @param type - * the type of the beans that will be added to the container. - * @throws IllegalArgumentException - * If {@code type} is null - */ - protected AbstractBeanContainer(Class<? super BEANTYPE> type) { - if (type == null) { - throw new IllegalArgumentException( - "The bean type passed to AbstractBeanContainer must not be null"); - } - this.type = type; - model = BeanItem.getPropertyDescriptors((Class<BEANTYPE>) type); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#getType(java.lang.Object) - */ - @Override - public Class<?> getType(Object propertyId) { - VaadinPropertyDescriptor<BEANTYPE> descriptor = model.get(propertyId); - if (descriptor == null) { - return null; - } - return descriptor.getPropertyType(); - } - - /** - * Create a BeanItem for a bean using pre-parsed bean metadata (based on - * {@link #getBeanType()}). - * - * @param bean - * @return created {@link BeanItem} or null if bean is null - */ - protected BeanItem<BEANTYPE> createBeanItem(BEANTYPE bean) { - return bean == null ? null : new BeanItem<BEANTYPE>(bean, model); - } - - /** - * Returns the type of beans this Container can contain. - * - * This comes from the bean type constructor parameter, and bean metadata - * (including container properties) is based on this. - * - * @return - */ - public Class<? super BEANTYPE> getBeanType() { - return type; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#getContainerPropertyIds() - */ - @Override - public Collection<String> getContainerPropertyIds() { - return model.keySet(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#removeAllItems() - */ - @Override - public boolean removeAllItems() { - int origSize = size(); - IDTYPE firstItem = getFirstVisibleItem(); - - internalRemoveAllItems(); - - // detach listeners from all Items - for (Item item : itemIdToItem.values()) { - removeAllValueChangeListeners(item); - } - itemIdToItem.clear(); - - // fire event only if the visible view changed, regardless of whether - // filtered out items were removed or not - if (origSize != 0) { - fireItemsRemoved(0, firstItem, origSize); - } - - return true; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#getItem(java.lang.Object) - */ - @Override - public BeanItem<BEANTYPE> getItem(Object itemId) { - // TODO return only if visible? - return getUnfilteredItem(itemId); - } - - @Override - protected BeanItem<BEANTYPE> getUnfilteredItem(Object itemId) { - return itemIdToItem.get(itemId); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#getItemIds() - */ - @Override - @SuppressWarnings("unchecked") - public List<IDTYPE> getItemIds() { - return (List<IDTYPE>) super.getItemIds(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#getContainerProperty(java.lang.Object, - * java.lang.Object) - */ - @Override - public Property getContainerProperty(Object itemId, Object propertyId) { - Item item = getItem(itemId); - if (item == null) { - return null; - } - return item.getItemProperty(propertyId); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#removeItem(java.lang.Object) - */ - @Override - public boolean removeItem(Object itemId) { - // TODO should also remove items that are filtered out - int origSize = size(); - Item item = getItem(itemId); - int position = indexOfId(itemId); - - if (internalRemoveItem(itemId)) { - // detach listeners from Item - removeAllValueChangeListeners(item); - - // remove item - itemIdToItem.remove(itemId); - - // fire event only if the visible view changed, regardless of - // whether filtered out items were removed or not - if (size() != origSize) { - fireItemRemoved(position, itemId); - } - - return true; - } else { - return false; - } - } - - /** - * Re-filter the container when one of the monitored properties changes. - */ - @Override - public void valueChange(ValueChangeEvent event) { - // if a property that is used in a filter is changed, refresh filtering - filterAll(); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.Container.Filterable#addContainerFilter(java.lang.Object, - * java.lang.String, boolean, boolean) - */ - @Override - public void addContainerFilter(Object propertyId, String filterString, - boolean ignoreCase, boolean onlyMatchPrefix) { - try { - addFilter(new SimpleStringFilter(propertyId, filterString, - ignoreCase, onlyMatchPrefix)); - } catch (UnsupportedFilterException e) { - // the filter instance created here is always valid for in-memory - // containers - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Filterable#removeAllContainerFilters() - */ - @Override - public void removeAllContainerFilters() { - if (!getFilters().isEmpty()) { - for (Item item : itemIdToItem.values()) { - removeAllValueChangeListeners(item); - } - removeAllFilters(); - } - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.Container.Filterable#removeContainerFilters(java.lang - * .Object) - */ - @Override - public void removeContainerFilters(Object propertyId) { - Collection<Filter> removedFilters = super.removeFilters(propertyId); - if (!removedFilters.isEmpty()) { - // stop listening to change events for the property - for (Item item : itemIdToItem.values()) { - removeValueChangeListener(item, propertyId); - } - } - } - - @Override - public void addContainerFilter(Filter filter) - throws UnsupportedFilterException { - addFilter(filter); - } - - @Override - public void removeContainerFilter(Filter filter) { - removeFilter(filter); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.AbstractInMemoryContainer#hasContainerFilters() - */ - @Override - public boolean hasContainerFilters() { - return super.hasContainerFilters(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.AbstractInMemoryContainer#getContainerFilters() - */ - @Override - public Collection<Filter> getContainerFilters() { - return super.getContainerFilters(); - } - - /** - * Make this container listen to the given property provided it notifies - * when its value changes. - * - * @param item - * The {@link Item} that contains the property - * @param propertyId - * The id of the property - */ - private void addValueChangeListener(Item item, Object propertyId) { - Property<?> property = item.getItemProperty(propertyId); - if (property instanceof ValueChangeNotifier) { - // avoid multiple notifications for the same property if - // multiple filters are in use - ValueChangeNotifier notifier = (ValueChangeNotifier) property; - notifier.removeListener(this); - notifier.addListener(this); - } - } - - /** - * Remove this container as a listener for the given property. - * - * @param item - * The {@link Item} that contains the property - * @param propertyId - * The id of the property - */ - private void removeValueChangeListener(Item item, Object propertyId) { - Property<?> property = item.getItemProperty(propertyId); - if (property instanceof ValueChangeNotifier) { - ((ValueChangeNotifier) property).removeListener(this); - } - } - - /** - * Remove this contains as a listener for all the properties in the given - * {@link Item}. - * - * @param item - * The {@link Item} that contains the properties - */ - private void removeAllValueChangeListeners(Item item) { - for (Object propertyId : item.getItemPropertyIds()) { - removeValueChangeListener(item, propertyId); - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Sortable#getSortableContainerPropertyIds() - */ - @Override - public Collection<?> getSortableContainerPropertyIds() { - return getSortablePropertyIds(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Sortable#sort(java.lang.Object[], - * boolean[]) - */ - @Override - public void sort(Object[] propertyId, boolean[] ascending) { - sortContainer(propertyId, ascending); - } - - @Override - public ItemSorter getItemSorter() { - return super.getItemSorter(); - } - - @Override - public void setItemSorter(ItemSorter itemSorter) { - super.setItemSorter(itemSorter); - } - - @Override - protected void registerNewItem(int position, IDTYPE itemId, - BeanItem<BEANTYPE> item) { - itemIdToItem.put(itemId, item); - - // add listeners to be able to update filtering on property - // changes - for (Filter filter : getFilters()) { - for (String propertyId : getContainerPropertyIds()) { - if (filter.appliesToProperty(propertyId)) { - // addValueChangeListener avoids adding duplicates - addValueChangeListener(item, propertyId); - } - } - } - } - - /** - * Check that a bean can be added to the container (is of the correct type - * for the container). - * - * @param bean - * @return - */ - private boolean validateBean(BEANTYPE bean) { - return bean != null && getBeanType().isAssignableFrom(bean.getClass()); - } - - /** - * Adds the bean to the Container. - * - * Note: the behavior of this method changed in Vaadin 6.6 - now items are - * added at the very end of the unfiltered container and not after the last - * visible item if filtering is used. - * - * @see com.vaadin.data.Container#addItem(Object) - */ - protected BeanItem<BEANTYPE> addItem(IDTYPE itemId, BEANTYPE bean) { - if (!validateBean(bean)) { - return null; - } - return internalAddItemAtEnd(itemId, createBeanItem(bean), true); - } - - /** - * Adds the bean after the given bean. - * - * @see com.vaadin.data.Container.Ordered#addItemAfter(Object, Object) - */ - protected BeanItem<BEANTYPE> addItemAfter(IDTYPE previousItemId, - IDTYPE newItemId, BEANTYPE bean) { - if (!validateBean(bean)) { - return null; - } - return internalAddItemAfter(previousItemId, newItemId, - createBeanItem(bean), true); - } - - /** - * Adds a new bean at the given index. - * - * The bean is used both as the item contents and as the item identifier. - * - * @param index - * Index at which the bean should be added. - * @param newItemId - * The item id for the bean to add to the container. - * @param bean - * The bean to add to the container. - * - * @return Returns the new BeanItem or null if the operation fails. - */ - protected BeanItem<BEANTYPE> addItemAt(int index, IDTYPE newItemId, - BEANTYPE bean) { - if (!validateBean(bean)) { - return null; - } - return internalAddItemAt(index, newItemId, createBeanItem(bean), true); - } - - /** - * Adds a bean to the container using the bean item id resolver to find its - * identifier. - * - * A bean id resolver must be set before calling this method. - * - * @see #addItem(Object, Object) - * - * @param bean - * the bean to add - * @return BeanItem<BEANTYPE> item added or null - * @throws IllegalStateException - * if no bean identifier resolver has been set - * @throws IllegalArgumentException - * if an identifier cannot be resolved for the bean - */ - protected BeanItem<BEANTYPE> addBean(BEANTYPE bean) - throws IllegalStateException, IllegalArgumentException { - if (bean == null) { - return null; - } - IDTYPE itemId = resolveBeanId(bean); - if (itemId == null) { - throw new IllegalArgumentException( - "Resolved identifier for a bean must not be null"); - } - return addItem(itemId, bean); - } - - /** - * Adds a bean to the container after a specified item identifier, using the - * bean item id resolver to find its identifier. - * - * A bean id resolver must be set before calling this method. - * - * @see #addItemAfter(Object, Object, Object) - * - * @param previousItemId - * the identifier of the bean after which this bean should be - * added, null to add to the beginning - * @param bean - * the bean to add - * @return BeanItem<BEANTYPE> item added or null - * @throws IllegalStateException - * if no bean identifier resolver has been set - * @throws IllegalArgumentException - * if an identifier cannot be resolved for the bean - */ - protected BeanItem<BEANTYPE> addBeanAfter(IDTYPE previousItemId, - BEANTYPE bean) - throws IllegalStateException, IllegalArgumentException { - if (bean == null) { - return null; - } - IDTYPE itemId = resolveBeanId(bean); - if (itemId == null) { - throw new IllegalArgumentException( - "Resolved identifier for a bean must not be null"); - } - return addItemAfter(previousItemId, itemId, bean); - } - - /** - * Adds a bean at a specified (filtered view) position in the container - * using the bean item id resolver to find its identifier. - * - * A bean id resolver must be set before calling this method. - * - * @see #addItemAfter(Object, Object, Object) - * - * @param index - * the index (in the filtered view) at which to add the item - * @param bean - * the bean to add - * @return BeanItem<BEANTYPE> item added or null - * @throws IllegalStateException - * if no bean identifier resolver has been set - * @throws IllegalArgumentException - * if an identifier cannot be resolved for the bean - */ - protected BeanItem<BEANTYPE> addBeanAt(int index, BEANTYPE bean) - throws IllegalStateException, IllegalArgumentException { - if (bean == null) { - return null; - } - IDTYPE itemId = resolveBeanId(bean); - if (itemId == null) { - throw new IllegalArgumentException( - "Resolved identifier for a bean must not be null"); - } - return addItemAt(index, itemId, bean); - } - - /** - * Adds all the beans from a {@link Collection} in one operation using the - * bean item identifier resolver. More efficient than adding them one by - * one. - * - * A bean id resolver must be set before calling this method. - * - * Note: the behavior of this method changed in Vaadin 6.6 - now items are - * added at the very end of the unfiltered container and not after the last - * visible item if filtering is used. - * - * @param collection - * The collection of beans to add. Must not be null. - * @throws IllegalStateException - * if no bean identifier resolver has been set - * @throws IllegalArgumentException - * if the resolver returns a null itemId for one of the beans in - * the collection - */ - protected void addAll(Collection<? extends BEANTYPE> collection) - throws IllegalStateException, IllegalArgumentException { - boolean modified = false; - int origSize = size(); - - for (BEANTYPE bean : collection) { - // TODO skipping invalid beans - should not allow them in javadoc? - if (bean == null - || !getBeanType().isAssignableFrom(bean.getClass())) { - continue; - } - IDTYPE itemId = resolveBeanId(bean); - if (itemId == null) { - throw new IllegalArgumentException( - "Resolved identifier for a bean must not be null"); - } - - if (internalAddItemAtEnd(itemId, createBeanItem(bean), - false) != null) { - modified = true; - } - } - - if (modified) { - // Filter the contents when all items have been added - if (isFiltered()) { - doFilterContainer(!getFilters().isEmpty()); - } - if (visibleNewItemsWasAdded(origSize)) { - // fire event about added items - int firstPosition = origSize; - IDTYPE firstItemId = getVisibleItemIds().get(firstPosition); - int affectedItems = size() - origSize; - fireItemsAdded(firstPosition, firstItemId, affectedItems); - } - } - } - - private boolean visibleNewItemsWasAdded(int origSize) { - return size() > origSize; - } - - /** - * Use the bean resolver to get the identifier for a bean. - * - * @param bean - * @return resolved bean identifier, null if could not be resolved - * @throws IllegalStateException - * if no bean resolver is set - */ - protected IDTYPE resolveBeanId(BEANTYPE bean) { - if (beanIdResolver == null) { - throw new IllegalStateException( - "Bean item identifier resolver is required."); - } - return beanIdResolver.getIdForBean(bean); - } - - /** - * Sets the resolver that finds the item id for a bean, or null not to use - * automatic resolving. - * - * Methods that add a bean without specifying an id must not be called if no - * resolver has been set. - * - * Note that methods taking an explicit id can be used whether a resolver - * has been defined or not. - * - * @param beanIdResolver - * to use or null to disable automatic id resolution - */ - protected void setBeanIdResolver( - BeanIdResolver<IDTYPE, BEANTYPE> beanIdResolver) { - this.beanIdResolver = beanIdResolver; - } - - /** - * Returns the resolver that finds the item ID for a bean. - * - * @return resolver used or null if automatic item id resolving is disabled - */ - public BeanIdResolver<IDTYPE, BEANTYPE> getBeanIdResolver() { - return beanIdResolver; - } - - /** - * Create an item identifier resolver using a named bean property. - * - * @param propertyId - * property identifier, which must map to a getter in BEANTYPE - * @return created resolver - */ - protected BeanIdResolver<IDTYPE, BEANTYPE> createBeanPropertyResolver( - Object propertyId) { - return new PropertyBasedBeanIdResolver(propertyId); - } - - /** - * @deprecated As of 7.0, replaced by {@link #addPropertySetChangeListener} - **/ - @Deprecated - @Override - public void addListener(Container.PropertySetChangeListener listener) { - addPropertySetChangeListener(listener); - } - - @Override - public void addPropertySetChangeListener( - Container.PropertySetChangeListener listener) { - super.addPropertySetChangeListener(listener); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #removePropertySetChangeListener(com.vaadin.data.Container.PropertySetChangeListener)} - **/ - @Deprecated - @Override - public void removeListener(Container.PropertySetChangeListener listener) { - removePropertySetChangeListener(listener); - } - - @Override - public void removePropertySetChangeListener( - Container.PropertySetChangeListener listener) { - super.removePropertySetChangeListener(listener); - } - - @Override - public boolean addContainerProperty(Object propertyId, Class<?> type, - Object defaultValue) throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "Use addNestedContainerProperty(String) to add container properties to a " - + getClass().getSimpleName()); - } - - /** - * Adds a property for the container and all its items. - * - * Primarily for internal use, may change in future versions. - * - * @param propertyId - * @param propertyDescriptor - * @return true if the property was added - */ - protected final boolean addContainerProperty(String propertyId, - VaadinPropertyDescriptor<BEANTYPE> propertyDescriptor) { - if (null == propertyId || null == propertyDescriptor) { - return false; - } - - // Fails if the Property is already present - if (model.containsKey(propertyId)) { - return false; - } - - model.put(propertyId, propertyDescriptor); - for (BeanItem<BEANTYPE> item : itemIdToItem.values()) { - item.addItemProperty(propertyId, - propertyDescriptor.createProperty(item.getBean())); - } - - // Sends a change event - fireContainerPropertySetChange(); - - return true; - } - - /** - * Adds a nested container property for the container, e.g. - * "manager.address.street". - * - * All intermediate getters must exist and should return non-null values - * when the property value is accessed. If an intermediate getter returns - * null, a null value will be returned. - * - * @see NestedMethodProperty - * - * @param propertyId - * @return true if the property was added - */ - public boolean addNestedContainerProperty(String propertyId) { - return addContainerProperty(propertyId, - new NestedPropertyDescriptor(propertyId, type)); - } - - /** - * Adds a nested container properties for all sub-properties of a named - * property to the container. The named property itself is removed from the - * model as its subproperties are added. - * - * All intermediate getters must exist and should return non-null values - * when the property value is accessed. If an intermediate getter returns - * null, a null value will be returned. - * - * @see NestedMethodProperty - * @see #addNestedContainerProperty(String) - * - * @param propertyId - */ - @SuppressWarnings("unchecked") - public void addNestedContainerBean(String propertyId) { - Class<?> propertyType = getType(propertyId); - LinkedHashMap<String, VaadinPropertyDescriptor<Object>> pds = BeanItem - .getPropertyDescriptors((Class<Object>) propertyType); - for (String subPropertyId : pds.keySet()) { - String qualifiedPropertyId = propertyId + "." + subPropertyId; - NestedPropertyDescriptor<BEANTYPE> pd = new NestedPropertyDescriptor<BEANTYPE>( - qualifiedPropertyId, (Class<BEANTYPE>) type); - model.put(qualifiedPropertyId, pd); - model.remove(propertyId); - for (BeanItem<BEANTYPE> item : itemIdToItem.values()) { - item.addItemProperty(qualifiedPropertyId, - pd.createProperty(item.getBean())); - item.removeItemProperty(propertyId); - } - } - - // Sends a change event - fireContainerPropertySetChange(); - } - - @Override - public boolean removeContainerProperty(Object propertyId) - throws UnsupportedOperationException { - // Fails if the Property is not present - if (!model.containsKey(propertyId)) { - return false; - } - - // Removes the Property to Property list and types - model.remove(propertyId); - - // If remove the Property from all Items - for (final Iterator<IDTYPE> i = getAllItemIds().iterator(); i - .hasNext();) { - getUnfilteredItem(i.next()).removeItemProperty(propertyId); - } - - // Sends a change event - fireContainerPropertySetChange(); - - return true; - } - -} diff --git a/server/src/main/java/com/vaadin/data/util/AbstractContainer.java b/server/src/main/java/com/vaadin/data/util/AbstractContainer.java deleted file mode 100644 index 1995102345..0000000000 --- a/server/src/main/java/com/vaadin/data/util/AbstractContainer.java +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util; - -import java.io.Serializable; -import java.util.Collection; -import java.util.Collections; -import java.util.EventObject; -import java.util.LinkedList; - -import com.vaadin.data.Container; - -/** - * Abstract container class that manages event listeners and sending events to - * them ({@link PropertySetChangeNotifier}, {@link ItemSetChangeNotifier}). - * - * Note that this class provides the internal implementations for both types of - * events and notifiers as protected methods, but does not implement the - * {@link PropertySetChangeNotifier} and {@link ItemSetChangeNotifier} - * interfaces directly. This way, subclasses can choose not to implement them. - * Subclasses implementing those interfaces should also override the - * corresponding {@link #addListener()} and {@link #removeListener()} methods to - * make them public. - * - * @since 6.6 - */ -public abstract class AbstractContainer implements Container { - - /** - * List of all Property set change event listeners. - */ - private Collection<Container.PropertySetChangeListener> propertySetChangeListeners = null; - - /** - * List of all container Item set change event listeners. - */ - private Collection<Container.ItemSetChangeListener> itemSetChangeListeners = null; - - /** - * An <code>event</code> object specifying the container whose Property set - * has changed. - * - * This class does not provide information about which properties were - * concerned by the change, but subclasses can provide additional - * information about the changes. - */ - protected static class BasePropertySetChangeEvent extends EventObject - implements Container.PropertySetChangeEvent, Serializable { - - protected BasePropertySetChangeEvent(Container source) { - super(source); - } - - @Override - public Container getContainer() { - return (Container) getSource(); - } - } - - /** - * An <code>event</code> object specifying the container whose Item set has - * changed. - * - * This class does not provide information about the exact changes - * performed, but subclasses can add provide additional information about - * the changes. - */ - protected static class BaseItemSetChangeEvent extends EventObject - implements Container.ItemSetChangeEvent, Serializable { - - protected BaseItemSetChangeEvent(Container source) { - super(source); - } - - @Override - public Container getContainer() { - return (Container) getSource(); - } - } - - // PropertySetChangeNotifier - - /** - * Implementation of the corresponding method in - * {@link PropertySetChangeNotifier}, override with the corresponding public - * method and implement the interface to use this. - * - * @see PropertySetChangeNotifier#addListener(com.vaadin.data.Container.PropertySetChangeListener) - */ - protected void addPropertySetChangeListener( - Container.PropertySetChangeListener listener) { - if (getPropertySetChangeListeners() == null) { - setPropertySetChangeListeners( - new LinkedList<Container.PropertySetChangeListener>()); - } - getPropertySetChangeListeners().add(listener); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #addPropertySetChangeListener(com.vaadin.data.Container.PropertySetChangeListener)} - **/ - @Deprecated - protected void addListener(Container.PropertySetChangeListener listener) { - addPropertySetChangeListener(listener); - } - - /** - * Implementation of the corresponding method in - * {@link PropertySetChangeNotifier}, override with the corresponding public - * method and implement the interface to use this. - * - * @see PropertySetChangeNotifier#removeListener(com.vaadin.data.Container. - * PropertySetChangeListener) - */ - protected void removePropertySetChangeListener( - Container.PropertySetChangeListener listener) { - if (getPropertySetChangeListeners() != null) { - getPropertySetChangeListeners().remove(listener); - } - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #removePropertySetChangeListener(com.vaadin.data.Container.PropertySetChangeListener)} - **/ - @Deprecated - protected void removeListener( - Container.PropertySetChangeListener listener) { - removePropertySetChangeListener(listener); - } - - // ItemSetChangeNotifier - - /** - * Implementation of the corresponding method in - * {@link ItemSetChangeNotifier}, override with the corresponding public - * method and implement the interface to use this. - * - * @see ItemSetChangeNotifier#addListener(com.vaadin.data.Container.ItemSetChangeListener) - */ - protected void addItemSetChangeListener( - Container.ItemSetChangeListener listener) { - if (getItemSetChangeListeners() == null) { - setItemSetChangeListeners( - new LinkedList<Container.ItemSetChangeListener>()); - } - getItemSetChangeListeners().add(listener); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #addItemSetChangeListener(com.vaadin.data.Container.ItemSetChangeListener)} - **/ - @Deprecated - protected void addListener(Container.ItemSetChangeListener listener) { - addItemSetChangeListener(listener); - } - - /** - * Implementation of the corresponding method in - * {@link ItemSetChangeNotifier}, override with the corresponding public - * method and implement the interface to use this. - * - * @see ItemSetChangeNotifier#removeListener(com.vaadin.data.Container.ItemSetChangeListener) - */ - protected void removeItemSetChangeListener( - Container.ItemSetChangeListener listener) { - if (getItemSetChangeListeners() != null) { - getItemSetChangeListeners().remove(listener); - } - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #addItemSetChangeListener(com.vaadin.data.Container.ItemSetChangeListener)} - **/ - @Deprecated - protected void removeListener(Container.ItemSetChangeListener listener) { - removeItemSetChangeListener(listener); - } - - /** - * Sends a simple Property set change event to all interested listeners. - */ - protected void fireContainerPropertySetChange() { - fireContainerPropertySetChange(new BasePropertySetChangeEvent(this)); - } - - /** - * Sends a Property set change event to all interested listeners. - * - * Use {@link #fireContainerPropertySetChange()} instead of this method - * unless additional information about the exact changes is available and - * should be included in the event. - * - * @param event - * the property change event to send, optionally with additional - * information - */ - protected void fireContainerPropertySetChange( - Container.PropertySetChangeEvent event) { - if (getPropertySetChangeListeners() != null) { - final Object[] l = getPropertySetChangeListeners().toArray(); - for (int i = 0; i < l.length; i++) { - ((Container.PropertySetChangeListener) l[i]) - .containerPropertySetChange(event); - } - } - } - - /** - * Sends a simple Item set change event to all interested listeners, - * indicating that anything in the contents may have changed (items added, - * removed etc.). - */ - protected void fireItemSetChange() { - fireItemSetChange(new BaseItemSetChangeEvent(this)); - } - - /** - * Sends an Item set change event to all registered interested listeners. - * - * @param event - * the item set change event to send, optionally with additional - * information - */ - protected void fireItemSetChange(ItemSetChangeEvent event) { - if (getItemSetChangeListeners() != null) { - final Object[] l = getItemSetChangeListeners().toArray(); - for (int i = 0; i < l.length; i++) { - ((Container.ItemSetChangeListener) l[i]) - .containerItemSetChange(event); - } - } - } - - /** - * Sets the property set change listener collection. For internal use only. - * - * @param propertySetChangeListeners - */ - protected void setPropertySetChangeListeners( - Collection<Container.PropertySetChangeListener> propertySetChangeListeners) { - this.propertySetChangeListeners = propertySetChangeListeners; - } - - /** - * Returns the property set change listener collection. For internal use - * only. - */ - protected Collection<Container.PropertySetChangeListener> getPropertySetChangeListeners() { - return propertySetChangeListeners; - } - - /** - * Sets the item set change listener collection. For internal use only. - * - * @param itemSetChangeListeners - */ - protected void setItemSetChangeListeners( - Collection<Container.ItemSetChangeListener> itemSetChangeListeners) { - this.itemSetChangeListeners = itemSetChangeListeners; - } - - /** - * Returns the item set change listener collection. For internal use only. - */ - protected Collection<Container.ItemSetChangeListener> getItemSetChangeListeners() { - return itemSetChangeListeners; - } - - public Collection<?> getListeners(Class<?> eventType) { - if (Container.PropertySetChangeEvent.class - .isAssignableFrom(eventType)) { - if (propertySetChangeListeners == null) { - return Collections.EMPTY_LIST; - } else { - return Collections - .unmodifiableCollection(propertySetChangeListeners); - } - } else if (Container.ItemSetChangeEvent.class - .isAssignableFrom(eventType)) { - if (itemSetChangeListeners == null) { - return Collections.EMPTY_LIST; - } else { - return Collections - .unmodifiableCollection(itemSetChangeListeners); - } - } - - return Collections.EMPTY_LIST; - } -} diff --git a/server/src/main/java/com/vaadin/data/util/AbstractInMemoryContainer.java b/server/src/main/java/com/vaadin/data/util/AbstractInMemoryContainer.java deleted file mode 100644 index 43b65ab75e..0000000000 --- a/server/src/main/java/com/vaadin/data/util/AbstractInMemoryContainer.java +++ /dev/null @@ -1,1165 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util; - -import java.io.Serializable; -import java.util.Collection; -import java.util.Collections; -import java.util.EventObject; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -import com.vaadin.data.Container; -import com.vaadin.data.Container.ItemSetChangeNotifier; -import com.vaadin.data.Item; -import com.vaadin.data.util.filter.SimpleStringFilter; -import com.vaadin.data.util.filter.UnsupportedFilterException; - -/** - * Abstract {@link Container} class that handles common functionality for - * in-memory containers. Concrete in-memory container classes can either inherit - * this class, inherit {@link AbstractContainer}, or implement the - * {@link Container} interface directly. - * - * Adding and removing items (if desired) must be implemented in subclasses by - * overriding the appropriate add*Item() and remove*Item() and removeAllItems() - * methods, calling the corresponding - * {@link #internalAddItemAfter(Object, Object, Item)}, - * {@link #internalAddItemAt(int, Object, Item)}, - * {@link #internalAddItemAtEnd(Object, Item, boolean)}, - * {@link #internalRemoveItem(Object)} and {@link #internalRemoveAllItems()} - * methods. - * - * By default, adding and removing container properties is not supported, and - * subclasses need to implement {@link #getContainerPropertyIds()}. Optionally, - * subclasses can override {@link #addContainerProperty(Object, Class, Object)} - * and {@link #removeContainerProperty(Object)} to implement them. - * - * Features: - * <ul> - * <li>{@link Container.Ordered} - * <li>{@link Container.Indexed} - * <li>{@link Filterable} and {@link SimpleFilterable} (internal implementation, - * does not implement the interface directly) - * <li>{@link Sortable} (internal implementation, does not implement the - * interface directly) - * </ul> - * - * To implement {@link Sortable}, subclasses need to implement - * {@link #getSortablePropertyIds()} and call the superclass method - * {@link #sortContainer(Object[], boolean[])} in the method - * <code>sort(Object[], boolean[])</code>. - * - * To implement {@link Filterable}, subclasses need to implement the methods - * {@link Filterable#addContainerFilter(com.vaadin.data.Container.Filter)} - * (calling {@link #addFilter(Filter)}), - * {@link Filterable#removeAllContainerFilters()} (calling - * {@link #removeAllFilters()}) and - * {@link Filterable#removeContainerFilter(com.vaadin.data.Container.Filter)} - * (calling {@link #removeFilter(com.vaadin.data.Container.Filter)}). - * - * To implement {@link SimpleFilterable}, subclasses also need to implement the - * methods - * {@link SimpleFilterable#addContainerFilter(Object, String, boolean, boolean)} - * and {@link SimpleFilterable#removeContainerFilters(Object)} calling - * {@link #addFilter(com.vaadin.data.Container.Filter)} and - * {@link #removeFilters(Object)} respectively. - * - * @param <ITEMIDTYPE> - * the class of item identifiers in the container, use Object if can - * be any class - * @param <PROPERTYIDCLASS> - * the class of property identifiers for the items in the container, - * use Object if can be any class - * @param <ITEMCLASS> - * the (base) class of the Item instances in the container, use - * {@link Item} if unknown - * - * @since 6.6 - */ -public abstract class AbstractInMemoryContainer<ITEMIDTYPE, PROPERTYIDCLASS, ITEMCLASS extends Item> - extends AbstractContainer - implements ItemSetChangeNotifier, Container.Indexed { - - /** - * An ordered {@link List} of all item identifiers in the container, - * including those that have been filtered out. - * - * Must not be null. - */ - private List<ITEMIDTYPE> allItemIds; - - /** - * An ordered {@link List} of item identifiers in the container after - * filtering, excluding those that have been filtered out. - * - * This is what the external API of the {@link Container} interface and its - * subinterfaces shows (e.g. {@link #size()}, {@link #nextItemId(Object)}). - * - * If null, the full item id list is used instead. - */ - private List<ITEMIDTYPE> filteredItemIds; - - /** - * Filters that are applied to the container to limit the items visible in - * it - */ - private Set<Filter> filters = new HashSet<Filter>(); - - /** - * The item sorter which is used for sorting the container. - */ - private ItemSorter itemSorter = new DefaultItemSorter(); - - // Constructors - - /** - * Constructor for an abstract in-memory container. - */ - protected AbstractInMemoryContainer() { - setAllItemIds(new ListSet<ITEMIDTYPE>()); - } - - // Container interface methods with more specific return class - - // default implementation, can be overridden - @Override - public ITEMCLASS getItem(Object itemId) { - if (containsId(itemId)) { - return getUnfilteredItem(itemId); - } else { - return null; - } - } - - private static abstract class BaseItemAddOrRemoveEvent extends EventObject - implements Serializable { - protected Object itemId; - protected int index; - protected int count; - - public BaseItemAddOrRemoveEvent(Container source, Object itemId, - int index, int count) { - super(source); - this.itemId = itemId; - this.index = index; - this.count = count; - } - - public Container getContainer() { - return (Container) getSource(); - } - - public Object getFirstItemId() { - return itemId; - } - - public int getFirstIndex() { - return index; - } - - public int getAffectedItemsCount() { - return count; - } - } - - /** - * An <code>Event</code> object specifying information about the added - * items. - * - * <p> - * This class provides information about the first added item and the number - * of added items. - * </p> - * - * @since 7.4 - */ - protected static class BaseItemAddEvent extends BaseItemAddOrRemoveEvent - implements Container.Indexed.ItemAddEvent { - - public BaseItemAddEvent(Container source, Object itemId, int index, - int count) { - super(source, itemId, index, count); - } - - @Override - public int getAddedItemsCount() { - return getAffectedItemsCount(); - } - } - - /** - * An <code>Event</code> object specifying information about the removed - * items. - * - * <p> - * This class provides information about the first removed item and the - * number of removed items. - * </p> - * - * @since 7.4 - */ - protected static class BaseItemRemoveEvent extends BaseItemAddOrRemoveEvent - implements Container.Indexed.ItemRemoveEvent { - - public BaseItemRemoveEvent(Container source, Object itemId, int index, - int count) { - super(source, itemId, index, count); - } - - @Override - public int getRemovedItemsCount() { - return getAffectedItemsCount(); - } - } - - /** - * Get an item even if filtered out. - * - * For internal use only. - * - * @param itemId - * @return - */ - protected abstract ITEMCLASS getUnfilteredItem(Object itemId); - - // cannot override getContainerPropertyIds() and getItemIds(): if subclass - // uses Object as ITEMIDCLASS or PROPERTYIDCLASS, Collection<Object> cannot - // be cast to Collection<MyInterface> - - // public abstract Collection<PROPERTYIDCLASS> getContainerPropertyIds(); - // public abstract Collection<ITEMIDCLASS> getItemIds(); - - // Container interface method implementations - - @Override - public int size() { - return getVisibleItemIds().size(); - } - - @Override - public boolean containsId(Object itemId) { - // only look at visible items after filtering - if (itemId == null) { - return false; - } else { - return getVisibleItemIds().contains(itemId); - } - } - - @Override - public List<?> getItemIds() { - return Collections.unmodifiableList(getVisibleItemIds()); - } - - // Container.Ordered - - @Override - public ITEMIDTYPE nextItemId(Object itemId) { - int index = indexOfId(itemId); - if (index >= 0 && index < size() - 1) { - return getIdByIndex(index + 1); - } else { - // out of bounds - return null; - } - } - - @Override - public ITEMIDTYPE prevItemId(Object itemId) { - int index = indexOfId(itemId); - if (index > 0) { - return getIdByIndex(index - 1); - } else { - // out of bounds - return null; - } - } - - @Override - public ITEMIDTYPE firstItemId() { - if (size() > 0) { - return getIdByIndex(0); - } else { - return null; - } - } - - @Override - public ITEMIDTYPE lastItemId() { - if (size() > 0) { - return getIdByIndex(size() - 1); - } else { - return null; - } - } - - @Override - public boolean isFirstId(Object itemId) { - if (itemId == null) { - return false; - } - return itemId.equals(firstItemId()); - } - - @Override - public boolean isLastId(Object itemId) { - if (itemId == null) { - return false; - } - return itemId.equals(lastItemId()); - } - - // Container.Indexed - - @Override - public ITEMIDTYPE getIdByIndex(int index) { - return getVisibleItemIds().get(index); - } - - @Override - public List<ITEMIDTYPE> getItemIds(int startIndex, int numberOfIds) { - if (startIndex < 0) { - throw new IndexOutOfBoundsException( - "Start index cannot be negative! startIndex=" + startIndex); - } - - if (startIndex > getVisibleItemIds().size()) { - throw new IndexOutOfBoundsException( - "Start index exceeds container size! startIndex=" - + startIndex + " containerLastItemIndex=" - + (getVisibleItemIds().size() - 1)); - } - - if (numberOfIds < 1) { - if (numberOfIds == 0) { - return Collections.emptyList(); - } - - throw new IllegalArgumentException( - "Cannot get negative amount of items! numberOfItems=" - + numberOfIds); - } - - int endIndex = startIndex + numberOfIds; - - if (endIndex > getVisibleItemIds().size()) { - endIndex = getVisibleItemIds().size(); - } - - return Collections.unmodifiableList( - getVisibleItemIds().subList(startIndex, endIndex)); - - } - - @Override - public int indexOfId(Object itemId) { - return getVisibleItemIds().indexOf(itemId); - } - - // methods that are unsupported by default, override to support - - @Override - public Object addItemAt(int index) throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "Adding items not supported. Override the relevant addItem*() methods if required as specified in AbstractInMemoryContainer javadoc."); - } - - @Override - public Item addItemAt(int index, Object newItemId) - throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "Adding items not supported. Override the relevant addItem*() methods if required as specified in AbstractInMemoryContainer javadoc."); - } - - @Override - public Object addItemAfter(Object previousItemId) - throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "Adding items not supported. Override the relevant addItem*() methods if required as specified in AbstractInMemoryContainer javadoc."); - } - - @Override - public Item addItemAfter(Object previousItemId, Object newItemId) - throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "Adding items not supported. Override the relevant addItem*() methods if required as specified in AbstractInMemoryContainer javadoc."); - } - - @Override - public Item addItem(Object itemId) throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "Adding items not supported. Override the relevant addItem*() methods if required as specified in AbstractInMemoryContainer javadoc."); - } - - @Override - public Object addItem() throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "Adding items not supported. Override the relevant addItem*() methods if required as specified in AbstractInMemoryContainer javadoc."); - } - - @Override - public boolean removeItem(Object itemId) - throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "Removing items not supported. Override the removeItem() method if required as specified in AbstractInMemoryContainer javadoc."); - } - - @Override - public boolean removeAllItems() throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "Removing items not supported. Override the removeAllItems() method if required as specified in AbstractInMemoryContainer javadoc."); - } - - @Override - public boolean addContainerProperty(Object propertyId, Class<?> type, - Object defaultValue) throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "Adding container properties not supported. Override the addContainerProperty() method if required."); - } - - @Override - public boolean removeContainerProperty(Object propertyId) - throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "Removing container properties not supported. Override the addContainerProperty() method if required."); - } - - // ItemSetChangeNotifier - /** - * @deprecated As of 7.0, replaced by - * {@link #addItemSetChangeListener(com.vaadin.data.Container.ItemSetChangeListener)} - **/ - @Deprecated - @Override - public void addListener(Container.ItemSetChangeListener listener) { - addItemSetChangeListener(listener); - } - - @Override - public void addItemSetChangeListener( - Container.ItemSetChangeListener listener) { - super.addItemSetChangeListener(listener); - } - - @Override - public void removeItemSetChangeListener( - Container.ItemSetChangeListener listener) { - super.removeItemSetChangeListener(listener); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #removeItemSetChangeListener(com.vaadin.data.Container.ItemSetChangeListener)} - **/ - @Deprecated - @Override - public void removeListener(Container.ItemSetChangeListener listener) { - removeItemSetChangeListener(listener); - } - - // internal methods - - // Filtering support - - /** - * Filter the view to recreate the visible item list from the unfiltered - * items, and send a notification if the set of visible items changed in any - * way. - */ - protected void filterAll() { - if (doFilterContainer(!getFilters().isEmpty())) { - fireItemSetChange(); - } - } - - /** - * Filters the data in the container and updates internal data structures. - * This method should reset any internal data structures and then repopulate - * them so {@link #getItemIds()} and other methods only return the filtered - * items. - * - * @param hasFilters - * true if filters has been set for the container, false - * otherwise - * @return true if the item set has changed as a result of the filtering - */ - protected boolean doFilterContainer(boolean hasFilters) { - if (!hasFilters) { - boolean changed = getAllItemIds().size() != getVisibleItemIds() - .size(); - setFilteredItemIds(null); - return changed; - } - - // Reset filtered list - List<ITEMIDTYPE> originalFilteredItemIds = getFilteredItemIds(); - boolean wasUnfiltered = false; - if (originalFilteredItemIds == null) { - originalFilteredItemIds = Collections.emptyList(); - wasUnfiltered = true; - } - setFilteredItemIds(new ListSet<ITEMIDTYPE>()); - - // Filter - boolean equal = true; - Iterator<ITEMIDTYPE> origIt = originalFilteredItemIds.iterator(); - for (final Iterator<ITEMIDTYPE> i = getAllItemIds().iterator(); i - .hasNext();) { - final ITEMIDTYPE id = i.next(); - if (passesFilters(id)) { - // filtered list comes from the full list, can use == - equal = equal && origIt.hasNext() && origIt.next() == id; - getFilteredItemIds().add(id); - } - } - - return (wasUnfiltered && !getAllItemIds().isEmpty()) || !equal - || origIt.hasNext(); - } - - /** - * Checks if the given itemId passes the filters set for the container. The - * caller should make sure the itemId exists in the container. For - * non-existing itemIds the behavior is undefined. - * - * @param itemId - * An itemId that exists in the container. - * @return true if the itemId passes all filters or no filters are set, - * false otherwise. - */ - protected boolean passesFilters(Object itemId) { - ITEMCLASS item = getUnfilteredItem(itemId); - if (getFilters().isEmpty()) { - return true; - } - final Iterator<Filter> i = getFilters().iterator(); - while (i.hasNext()) { - final Filter f = i.next(); - if (!f.passesFilter(itemId, item)) { - return false; - } - } - return true; - } - - /** - * Adds a container filter and re-filter the view. - * - * The filter must implement Filter and its sub-filters (if any) must also - * be in-memory filterable. - * - * This can be used to implement - * {@link Filterable#addContainerFilter(com.vaadin.data.Container.Filter)} - * and optionally also - * {@link SimpleFilterable#addContainerFilter(Object, String, boolean, boolean)} - * (with {@link SimpleStringFilter}). - * - * Note that in some cases, incompatible filters cannot be detected when - * added and an {@link UnsupportedFilterException} may occur when performing - * filtering. - * - * @throws UnsupportedFilterException - * if the filter is detected as not supported by the container - */ - protected void addFilter(Filter filter) throws UnsupportedFilterException { - getFilters().add(filter); - filterAll(); - } - - /** - * Returns true if any filters have been applied to the container. - * - * @return true if the container has filters applied, false otherwise - * @since 7.1 - */ - protected boolean hasContainerFilters() { - return !getContainerFilters().isEmpty(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Filterable#getContainerFilters() - */ - protected Collection<Filter> getContainerFilters() { - return Collections.unmodifiableCollection(filters); - } - - /** - * Remove a specific container filter and re-filter the view (if necessary). - * - * This can be used to implement - * {@link Filterable#removeContainerFilter(com.vaadin.data.Container.Filter)} - * . - */ - protected void removeFilter(Filter filter) { - for (Iterator<Filter> iterator = getFilters().iterator(); iterator - .hasNext();) { - Filter f = iterator.next(); - if (f.equals(filter)) { - iterator.remove(); - filterAll(); - return; - } - } - } - - /** - * Remove all container filters for all properties and re-filter the view. - * - * This can be used to implement - * {@link Filterable#removeAllContainerFilters()}. - */ - protected void removeAllFilters() { - if (getFilters().isEmpty()) { - return; - } - getFilters().clear(); - filterAll(); - } - - /** - * Checks if there is a filter that applies to a given property. - * - * @param propertyId - * @return true if there is an active filter for the property - */ - protected boolean isPropertyFiltered(Object propertyId) { - if (getFilters().isEmpty() || propertyId == null) { - return false; - } - final Iterator<Filter> i = getFilters().iterator(); - while (i.hasNext()) { - final Filter f = i.next(); - if (f.appliesToProperty(propertyId)) { - return true; - } - } - return false; - } - - /** - * Remove all container filters for a given property identifier and - * re-filter the view. This also removes filters applying to multiple - * properties including the one identified by propertyId. - * - * This can be used to implement - * {@link Filterable#removeContainerFilters(Object)}. - * - * @param propertyId - * @return Collection<Filter> removed filters - */ - protected Collection<Filter> removeFilters(Object propertyId) { - if (getFilters().isEmpty() || propertyId == null) { - return Collections.emptyList(); - } - List<Filter> removedFilters = new LinkedList<Filter>(); - for (Iterator<Filter> iterator = getFilters().iterator(); iterator - .hasNext();) { - Filter f = iterator.next(); - if (f.appliesToProperty(propertyId)) { - removedFilters.add(f); - iterator.remove(); - } - } - if (!removedFilters.isEmpty()) { - filterAll(); - return removedFilters; - } - return Collections.emptyList(); - } - - // sorting - - /** - * Returns the ItemSorter used for comparing items in a sort. See - * {@link #setItemSorter(ItemSorter)} for more information. - * - * @return The ItemSorter used for comparing two items in a sort. - */ - protected ItemSorter getItemSorter() { - return itemSorter; - } - - /** - * Sets the ItemSorter used for comparing items in a sort. The - * {@link ItemSorter#compare(Object, Object)} method is called with item ids - * to perform the sorting. A default ItemSorter is used if this is not - * explicitly set. - * - * @param itemSorter - * The ItemSorter used for comparing two items in a sort (not - * null). - */ - protected void setItemSorter(ItemSorter itemSorter) { - this.itemSorter = itemSorter; - } - - /** - * Sort base implementation to be used to implement {@link Sortable}. - * - * Subclasses should call this from a public - * {@link #sort(Object[], boolean[])} method when implementing Sortable. - * - * @see com.vaadin.data.Container.Sortable#sort(java.lang.Object[], - * boolean[]) - */ - protected void sortContainer(Object[] propertyId, boolean[] ascending) { - if (!(this instanceof Sortable)) { - throw new UnsupportedOperationException( - "Cannot sort a Container that does not implement Sortable"); - } - - // Set up the item sorter for the sort operation - getItemSorter().setSortProperties((Sortable) this, propertyId, - ascending); - - // Perform the actual sort - doSort(); - - // Post sort updates - if (isFiltered()) { - filterAll(); - } else { - fireItemSetChange(); - } - - } - - /** - * Perform the sorting of the data structures in the container. This is - * invoked when the <code>itemSorter</code> has been prepared for the sort - * operation. Typically this method calls - * <code>Collections.sort(aCollection, getItemSorter())</code> on all arrays - * (containing item ids) that need to be sorted. - * - */ - protected void doSort() { - Collections.sort(getAllItemIds(), getItemSorter()); - } - - /** - * Returns the sortable property identifiers for the container. Can be used - * to implement {@link Sortable#getSortableContainerPropertyIds()}. - */ - protected Collection<?> getSortablePropertyIds() { - LinkedList<Object> sortables = new LinkedList<Object>(); - for (Object propertyId : getContainerPropertyIds()) { - Class<?> propertyType = getType(propertyId); - if (Comparable.class.isAssignableFrom(propertyType) - || propertyType.isPrimitive()) { - sortables.add(propertyId); - } - } - return sortables; - } - - // removing items - - /** - * Removes all items from the internal data structures of this class. This - * can be used to implement {@link #removeAllItems()} in subclasses. - * - * No notification is sent, the caller has to fire a suitable item set - * change notification. - */ - protected void internalRemoveAllItems() { - // Removes all Items - getAllItemIds().clear(); - if (isFiltered()) { - getFilteredItemIds().clear(); - } - } - - /** - * Removes a single item from the internal data structures of this class. - * This can be used to implement {@link #removeItem(Object)} in subclasses. - * - * No notification is sent, the caller has to fire a suitable item set - * change notification. - * - * @param itemId - * the identifier of the item to remove - * @return true if an item was successfully removed, false if failed to - * remove or no such item - */ - protected boolean internalRemoveItem(Object itemId) { - if (itemId == null) { - return false; - } - - boolean result = getAllItemIds().remove(itemId); - if (result && isFiltered()) { - getFilteredItemIds().remove(itemId); - } - - return result; - } - - // adding items - - /** - * Adds the bean to all internal data structures at the given position. - * Fails if an item with itemId is already in the container. Returns a the - * item if it was added successfully, null otherwise. - * - * <p> - * Caller should initiate filtering after calling this method. - * </p> - * - * For internal use only - subclasses should use - * {@link #internalAddItemAtEnd(Object, Item, boolean)}, - * {@link #internalAddItemAt(int, Object, Item, boolean)} and - * {@link #internalAddItemAfter(Object, Object, Item, boolean)} instead. - * - * @param position - * The position at which the item should be inserted in the - * unfiltered collection of items - * @param itemId - * The item identifier for the item to insert - * @param item - * The item to insert - * - * @return ITEMCLASS if the item was added successfully, null otherwise - */ - private ITEMCLASS internalAddAt(int position, ITEMIDTYPE itemId, - ITEMCLASS item) { - if (position < 0 || position > getAllItemIds().size() || itemId == null - || item == null) { - return null; - } - // Make sure that the item has not been added previously - if (getAllItemIds().contains(itemId)) { - return null; - } - - // "filteredList" will be updated in filterAll() which should be invoked - // by the caller after calling this method. - getAllItemIds().add(position, itemId); - registerNewItem(position, itemId, item); - - return item; - } - - /** - * Add an item at the end of the container, and perform filtering if - * necessary. An event is fired if the filtered view changes. - * - * @param newItemId - * @param item - * new item to add - * @param filter - * true to perform filtering and send event after adding the - * item, false to skip these operations for batch inserts - if - * false, caller needs to make sure these operations are - * performed at the end of the batch - * @return item added or null if no item was added - */ - protected ITEMCLASS internalAddItemAtEnd(ITEMIDTYPE newItemId, - ITEMCLASS item, boolean filter) { - ITEMCLASS newItem = internalAddAt(getAllItemIds().size(), newItemId, - item); - if (newItem != null && filter) { - // TODO filter only this item, use fireItemAdded() - filterAll(); - if (!isFiltered()) { - // TODO hack: does not detect change in filterAll() in this case - fireItemAdded(indexOfId(newItemId), newItemId, item); - } - } - return newItem; - } - - /** - * Add an item after a given (visible) item, and perform filtering. An event - * is fired if the filtered view changes. - * - * The new item is added at the beginning if previousItemId is null. - * - * @param previousItemId - * item id of a visible item after which to add the new item, or - * null to add at the beginning - * @param newItemId - * @param item - * new item to add - * @param filter - * true to perform filtering and send event after adding the - * item, false to skip these operations for batch inserts - if - * false, caller needs to make sure these operations are - * performed at the end of the batch - * @return item added or null if no item was added - */ - protected ITEMCLASS internalAddItemAfter(ITEMIDTYPE previousItemId, - ITEMIDTYPE newItemId, ITEMCLASS item, boolean filter) { - // only add if the previous item is visible - ITEMCLASS newItem = null; - if (previousItemId == null) { - newItem = internalAddAt(0, newItemId, item); - } else if (containsId(previousItemId)) { - newItem = internalAddAt(getAllItemIds().indexOf(previousItemId) + 1, - newItemId, item); - } - if (newItem != null && filter) { - // TODO filter only this item, use fireItemAdded() - filterAll(); - if (!isFiltered()) { - // TODO hack: does not detect change in filterAll() in this case - fireItemAdded(indexOfId(newItemId), newItemId, item); - } - } - return newItem; - } - - /** - * Add an item at a given (visible after filtering) item index, and perform - * filtering. An event is fired if the filtered view changes. - * - * @param index - * position where to add the item (visible/view index) - * @param newItemId - * @param item - * new item to add - * @param filter - * true to perform filtering and send event after adding the - * item, false to skip these operations for batch inserts - if - * false, caller needs to make sure these operations are - * performed at the end of the batch - * @return item added or null if no item was added - */ - protected ITEMCLASS internalAddItemAt(int index, ITEMIDTYPE newItemId, - ITEMCLASS item, boolean filter) { - if (index < 0 || index > size()) { - return null; - } else if (index == 0) { - // add before any item, visible or not - return internalAddItemAfter(null, newItemId, item, filter); - } else { - // if index==size(), adds immediately after last visible item - return internalAddItemAfter(getIdByIndex(index - 1), newItemId, - item, filter); - } - } - - /** - * Registers a new item as having been added to the container. This can - * involve storing the item or any relevant information about it in internal - * container-specific collections if necessary, as well as registering - * listeners etc. - * - * The full identifier list in {@link AbstractInMemoryContainer} has already - * been updated to reflect the new item when this method is called. - * - * @param position - * @param itemId - * @param item - */ - protected void registerNewItem(int position, ITEMIDTYPE itemId, - ITEMCLASS item) { - } - - // item set change notifications - - /** - * Notify item set change listeners that an item has been added to the - * container. - * - * @since 7.4 - * - * @param position - * position of the added item in the view - * @param itemId - * id of the added item - * @param item - * the added item - */ - protected void fireItemAdded(int position, ITEMIDTYPE itemId, - ITEMCLASS item) { - fireItemsAdded(position, itemId, 1); - } - - /** - * Notify item set change listeners that items has been added to the - * container. - * - * @param firstPosition - * position of the first visible added item in the view - * @param firstItemId - * id of the first visible added item - * @param numberOfItems - * the number of visible added items - */ - protected void fireItemsAdded(int firstPosition, ITEMIDTYPE firstItemId, - int numberOfItems) { - BaseItemAddEvent addEvent = new BaseItemAddEvent(this, firstItemId, - firstPosition, numberOfItems); - fireItemSetChange(addEvent); - } - - /** - * Notify item set change listeners that an item has been removed from the - * container. - * - * @since 7.4 - * - * @param position - * position of the removed item in the view prior to removal (if - * was visible) - * @param itemId - * id of the removed item, of type {@link Object} to satisfy - * {@link Container#removeItem(Object)} API - */ - protected void fireItemRemoved(int position, Object itemId) { - fireItemsRemoved(position, itemId, 1); - } - - /** - * Notify item set change listeners that items has been removed from the - * container. - * - * @param firstPosition - * position of the first visible removed item in the view prior - * to removal - * @param firstItemId - * id of the first visible removed item, of type {@link Object} - * to satisfy {@link Container#removeItem(Object)} API - * @param numberOfItems - * the number of removed visible items - * - */ - protected void fireItemsRemoved(int firstPosition, Object firstItemId, - int numberOfItems) { - BaseItemRemoveEvent removeEvent = new BaseItemRemoveEvent(this, - firstItemId, firstPosition, numberOfItems); - fireItemSetChange(removeEvent); - } - - // visible and filtered item identifier lists - - /** - * Returns the internal list of visible item identifiers after filtering. - * - * For internal use only. - */ - protected List<ITEMIDTYPE> getVisibleItemIds() { - if (isFiltered()) { - return getFilteredItemIds(); - } else { - return getAllItemIds(); - } - } - - /** - * Returns the item id of the first visible item after filtering. 'Null' is - * returned if there is no visible items. - * <p> - * For internal use only. - * - * @since 7.4 - * - * @return item id of the first visible item - */ - protected ITEMIDTYPE getFirstVisibleItem() { - if (!getVisibleItemIds().isEmpty()) { - return getVisibleItemIds().get(0); - } - return null; - } - - /** - * Returns true is the container has active filters. - * - * @return true if the container is currently filtered - */ - protected boolean isFiltered() { - return filteredItemIds != null; - } - - /** - * Internal helper method to set the internal list of filtered item - * identifiers. Should not be used outside this class except for - * implementing clone(), may disappear from future versions. - * - * @param filteredItemIds - */ - @Deprecated - protected void setFilteredItemIds(List<ITEMIDTYPE> filteredItemIds) { - this.filteredItemIds = filteredItemIds; - } - - /** - * Internal helper method to get the internal list of filtered item - * identifiers. Should not be used outside this class except for - * implementing clone(), may disappear from future versions - use - * {@link #getVisibleItemIds()} in other contexts. - * - * @return List<ITEMIDTYPE> - */ - protected List<ITEMIDTYPE> getFilteredItemIds() { - return filteredItemIds; - } - - /** - * Internal helper method to set the internal list of all item identifiers. - * Should not be used outside this class except for implementing clone(), - * may disappear from future versions. - * - * @param allItemIds - */ - @Deprecated - protected void setAllItemIds(List<ITEMIDTYPE> allItemIds) { - this.allItemIds = allItemIds; - } - - /** - * Internal helper method to get the internal list of all item identifiers. - * Avoid using this method outside this class, may disappear in future - * versions. - * - * @return List<ITEMIDTYPE> - */ - protected List<ITEMIDTYPE> getAllItemIds() { - return allItemIds; - } - - /** - * Set the internal collection of filters without performing filtering. - * - * This method is mostly for internal use, use - * {@link #addFilter(com.vaadin.data.Container.Filter)} and - * <code>remove*Filter*</code> (which also re-filter the container) instead - * when possible. - * - * @param filters - */ - protected void setFilters(Set<Filter> filters) { - this.filters = filters; - } - - /** - * Returns the internal collection of filters. The returned collection - * should not be modified by callers outside this class. - * - * @return Set<Filter> - */ - protected Set<Filter> getFilters() { - return filters; - } - -} diff --git a/server/src/main/java/com/vaadin/data/util/BeanContainer.java b/server/src/main/java/com/vaadin/data/util/BeanContainer.java deleted file mode 100644 index 01a5256199..0000000000 --- a/server/src/main/java/com/vaadin/data/util/BeanContainer.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util; - -import java.util.Collection; - -/** - * An in-memory container for JavaBeans. - * - * <p> - * The properties of the container are determined automatically by introspecting - * the used JavaBean class. Only beans of the same type can be added to the - * container. - * </p> - * - * <p> - * In BeanContainer (unlike {@link BeanItemContainer}), the item IDs do not have - * to be the beans themselves. The container can be used either with explicit - * item IDs or the item IDs can be generated when adding beans. - * </p> - * - * <p> - * To use explicit item IDs, use the methods {@link #addItem(Object, Object)}, - * {@link #addItemAfter(Object, Object, Object)} and - * {@link #addItemAt(int, Object, Object)}. - * </p> - * - * <p> - * If a bean id resolver is set using - * {@link #setBeanIdResolver(com.vaadin.data.util.AbstractBeanContainer.BeanIdResolver)} - * or {@link #setBeanIdProperty(Object)}, the methods {@link #addBean(Object)}, - * {@link #addBeanAfter(Object, Object)}, {@link #addBeanAt(int, Object)} and - * {@link #addAll(java.util.Collection)} can be used to add items to the - * container. If one of these methods is called, the resolver is used to - * generate an identifier for the item (must not return null). - * </p> - * - * <p> - * Note that explicit item identifiers can also be used when a resolver has been - * set by calling the addItem*() methods - the resolver is only used when adding - * beans using the addBean*() or {@link #addAll(Collection)} methods. - * </p> - * - * <p> - * It is not possible to add additional properties to the container. - * </p> - * - * @param <IDTYPE> - * The type of the item identifier - * @param <BEANTYPE> - * The type of the Bean - * - * @see AbstractBeanContainer - * @see BeanItemContainer - * - * @since 6.5 - */ -public class BeanContainer<IDTYPE, BEANTYPE> - extends AbstractBeanContainer<IDTYPE, BEANTYPE> { - - public BeanContainer(Class<? super BEANTYPE> type) { - super(type); - } - - /** - * Adds the bean to the Container. - * - * @see com.vaadin.data.Container#addItem(Object) - */ - @Override - public BeanItem<BEANTYPE> addItem(IDTYPE itemId, BEANTYPE bean) { - if (itemId != null && bean != null) { - return super.addItem(itemId, bean); - } else { - return null; - } - } - - /** - * Adds the bean after the given item id. - * - * @see com.vaadin.data.Container.Ordered#addItemAfter(Object, Object) - */ - @Override - public BeanItem<BEANTYPE> addItemAfter(IDTYPE previousItemId, - IDTYPE newItemId, BEANTYPE bean) { - if (newItemId != null && bean != null) { - return super.addItemAfter(previousItemId, newItemId, bean); - } else { - return null; - } - } - - /** - * Adds a new bean at the given index. - * - * The bean is used both as the item contents and as the item identifier. - * - * @param index - * Index at which the bean should be added. - * @param newItemId - * The item id for the bean to add to the container. - * @param bean - * The bean to add to the container. - * - * @return Returns the new BeanItem or null if the operation fails. - */ - @Override - public BeanItem<BEANTYPE> addItemAt(int index, IDTYPE newItemId, - BEANTYPE bean) { - if (newItemId != null && bean != null) { - return super.addItemAt(index, newItemId, bean); - } else { - return null; - } - } - - // automatic item id resolution - - /** - * Sets the bean id resolver to use a property of the beans as the - * identifier. - * - * @param propertyId - * the identifier of the property to use to find item identifiers - */ - public void setBeanIdProperty(Object propertyId) { - setBeanIdResolver(createBeanPropertyResolver(propertyId)); - } - - @Override - // overridden to make public - public void setBeanIdResolver( - BeanIdResolver<IDTYPE, BEANTYPE> beanIdResolver) { - super.setBeanIdResolver(beanIdResolver); - } - - @Override - // overridden to make public - public BeanItem<BEANTYPE> addBean(BEANTYPE bean) - throws IllegalStateException, IllegalArgumentException { - return super.addBean(bean); - } - - @Override - // overridden to make public - public BeanItem<BEANTYPE> addBeanAfter(IDTYPE previousItemId, BEANTYPE bean) - throws IllegalStateException, IllegalArgumentException { - return super.addBeanAfter(previousItemId, bean); - } - - @Override - // overridden to make public - public BeanItem<BEANTYPE> addBeanAt(int index, BEANTYPE bean) - throws IllegalStateException, IllegalArgumentException { - return super.addBeanAt(index, bean); - } - - @Override - // overridden to make public - public void addAll(Collection<? extends BEANTYPE> collection) - throws IllegalStateException { - super.addAll(collection); - } - -} diff --git a/server/src/main/java/com/vaadin/data/util/BeanItem.java b/server/src/main/java/com/vaadin/data/util/BeanItem.java deleted file mode 100644 index c0c4fdcaa6..0000000000 --- a/server/src/main/java/com/vaadin/data/util/BeanItem.java +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util; - -import java.beans.PropertyDescriptor; -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * A wrapper class for adding the Item interface to any Java Bean. - * - * @author Vaadin Ltd. - * @since 3.0 - */ -@SuppressWarnings("serial") -public class BeanItem<BT> extends PropertysetItem { - - /** - * The bean which this Item is based on. - */ - private final BT bean; - - /** - * <p> - * Creates a new instance of <code>BeanItem</code> and adds all properties - * of a Java Bean to it. The properties are identified by their respective - * bean names. - * </p> - * - * <p> - * Note : This version only supports introspectable bean properties and - * their getter and setter methods. Stand-alone <code>is</code> and - * <code>are</code> methods are not supported. - * </p> - * - * @param bean - * the Java Bean to copy properties from. - * - */ - public BeanItem(BT bean) { - this(bean, (Class<BT>) bean.getClass()); - } - - /** - * <p> - * Creates a new instance of <code>BeanItem</code> and adds all properties - * of a Java Bean to it. The properties are identified by their respective - * bean names. - * </p> - * - * <p> - * Note : This version only supports introspectable bean properties and - * their getter and setter methods. Stand-alone <code>is</code> and - * <code>are</code> methods are not supported. - * </p> - * - * @since 7.4 - * - * @param bean - * the Java Bean to copy properties from. - * @param beanClass - * class of the {@code bean} - * - */ - public BeanItem(BT bean, Class<BT> beanClass) { - this(bean, getPropertyDescriptors(beanClass)); - } - - /** - * <p> - * Creates a new instance of <code>BeanItem</code> using a pre-computed set - * of properties. The properties are identified by their respective bean - * names. - * </p> - * - * @param bean - * the Java Bean to copy properties from. - * @param propertyDescriptors - * pre-computed property descriptors - */ - BeanItem(BT bean, - Map<String, VaadinPropertyDescriptor<BT>> propertyDescriptors) { - - this.bean = bean; - - for (VaadinPropertyDescriptor<BT> pd : propertyDescriptors.values()) { - addItemProperty(pd.getName(), pd.createProperty(bean)); - } - } - - /** - * <p> - * Creates a new instance of <code>BeanItem</code> and adds all listed - * properties of a Java Bean to it - in specified order. The properties are - * identified by their respective bean names. - * </p> - * - * <p> - * Note : This version only supports introspectable bean properties and - * their getter and setter methods. Stand-alone <code>is</code> and - * <code>are</code> methods are not supported. - * </p> - * - * @param bean - * the Java Bean to copy properties from. - * @param propertyIds - * id of the property. - */ - public BeanItem(BT bean, Collection<?> propertyIds) { - - this.bean = bean; - - // Create bean information - LinkedHashMap<String, VaadinPropertyDescriptor<BT>> pds = getPropertyDescriptors( - (Class<BT>) bean.getClass()); - - // Add all the bean properties as MethodProperties to this Item - for (Object id : propertyIds) { - VaadinPropertyDescriptor<BT> pd = pds.get(id); - if (pd != null) { - addItemProperty(pd.getName(), pd.createProperty(bean)); - } - } - - } - - /** - * <p> - * Creates a new instance of <code>BeanItem</code> and adds all listed - * properties of a Java Bean to it - in specified order. The properties are - * identified by their respective bean names. - * </p> - * - * <p> - * Note : This version only supports introspectable bean properties and - * their getter and setter methods. Stand-alone <code>is</code> and - * <code>are</code> methods are not supported. - * </p> - * - * @param bean - * the Java Bean to copy properties from. - * @param propertyIds - * ids of the properties. - */ - public BeanItem(BT bean, String... propertyIds) { - this(bean, Arrays.asList(propertyIds)); - } - - /** - * <p> - * Perform introspection on a Java Bean class to find its properties. - * </p> - * - * <p> - * Note : This version only supports introspectable bean properties and - * their getter and setter methods. Stand-alone <code>is</code> and - * <code>are</code> methods are not supported. - * </p> - * - * @param beanClass - * the Java Bean class to get properties for. - * @return an ordered map from property names to property descriptors - */ - static <BT> LinkedHashMap<String, VaadinPropertyDescriptor<BT>> getPropertyDescriptors( - final Class<BT> beanClass) { - final LinkedHashMap<String, VaadinPropertyDescriptor<BT>> pdMap = new LinkedHashMap<String, VaadinPropertyDescriptor<BT>>(); - - // Try to introspect, if it fails, we just have an empty Item - try { - List<PropertyDescriptor> propertyDescriptors = BeanUtil - .getBeanPropertyDescriptor(beanClass); - - // Add all the bean properties as MethodProperties to this Item - // later entries on the list overwrite earlier ones - for (PropertyDescriptor pd : propertyDescriptors) { - final Method getMethod = pd.getReadMethod(); - if ((getMethod != null) - && getMethod.getDeclaringClass() != Object.class) { - VaadinPropertyDescriptor<BT> vaadinPropertyDescriptor = new MethodPropertyDescriptor<BT>( - pd.getName(), pd.getPropertyType(), - pd.getReadMethod(), pd.getWriteMethod()); - pdMap.put(pd.getName(), vaadinPropertyDescriptor); - } - } - } catch (final java.beans.IntrospectionException ignored) { - } - - return pdMap; - } - - /** - * Expands nested bean properties by replacing a top-level property with - * some or all of its sub-properties. The expansion is not recursive. - * - * @param propertyId - * property id for the property whose sub-properties are to be - * expanded, - * @param subPropertyIds - * sub-properties to expand, all sub-properties are expanded if - * not specified - */ - public void expandProperty(String propertyId, String... subPropertyIds) { - Set<String> subPropertySet = new HashSet<String>( - Arrays.asList(subPropertyIds)); - - if (0 == subPropertyIds.length) { - // Enumerate all sub-properties - Class<?> propertyType = getItemProperty(propertyId).getType(); - Map<String, ?> pds = getPropertyDescriptors(propertyType); - subPropertySet.addAll(pds.keySet()); - } - - for (String subproperty : subPropertySet) { - String qualifiedPropertyId = propertyId + "." + subproperty; - addNestedProperty(qualifiedPropertyId); - } - - removeItemProperty(propertyId); - } - - /** - * Adds a nested property to the item. The property must not exist in the - * item already and must of form "field1.field2" where field2 is a field in - * the object referenced to by field1. If an intermediate property returns - * null, the property will return a null value - * - * @param nestedPropertyId - * property id to add. - */ - public void addNestedProperty(String nestedPropertyId) { - addItemProperty(nestedPropertyId, - new NestedMethodProperty<Object>(getBean(), nestedPropertyId)); - } - - /** - * Gets the underlying JavaBean object. - * - * @return the bean object. - */ - public BT getBean() { - return bean; - } - -} diff --git a/server/src/main/java/com/vaadin/data/util/BeanItemContainer.java b/server/src/main/java/com/vaadin/data/util/BeanItemContainer.java deleted file mode 100644 index 66e553164d..0000000000 --- a/server/src/main/java/com/vaadin/data/util/BeanItemContainer.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util; - -import java.util.Collection; - -/** - * An in-memory container for JavaBeans. - * - * <p> - * The properties of the container are determined automatically by introspecting - * the used JavaBean class. Only beans of the same type can be added to the - * container. - * </p> - * - * <p> - * BeanItemContainer uses the beans themselves as identifiers. The - * {@link Object#hashCode()} of a bean is used when storing and looking up beans - * so it must not change during the lifetime of the bean (it should not depend - * on any part of the bean that can be modified). Typically this restricts the - * implementation of {@link Object#equals(Object)} as well in order for it to - * fulfill the contract between {@code equals()} and {@code hashCode()}. - * </p> - * - * <p> - * To add items to the container, use the methods {@link #addBean(Object)}, - * {@link #addBeanAfter(Object, Object)} and {@link #addBeanAt(int, Object)}. - * Also {@link #addItem(Object)}, {@link #addItemAfter(Object, Object)} and - * {@link #addItemAt(int, Object)} can be used as synonyms for them. - * </p> - * - * <p> - * It is not possible to add additional properties to the container. - * </p> - * - * @param <BEANTYPE> - * The type of the Bean - * - * @since 5.4 - */ -@SuppressWarnings("serial") -public class BeanItemContainer<BEANTYPE> - extends AbstractBeanContainer<BEANTYPE, BEANTYPE> { - - /** - * Bean identity resolver that returns the bean itself as its item - * identifier. - * - * This corresponds to the old behavior of {@link BeanItemContainer}, and - * requires suitable (identity-based) equals() and hashCode() methods on the - * beans. - * - * @param <BT> - * - * @since 6.5 - */ - private static class IdentityBeanIdResolver<BT> - implements BeanIdResolver<BT, BT> { - - @Override - public BT getIdForBean(BT bean) { - return bean; - } - - } - - /** - * Constructs a {@code BeanItemContainer} for beans of the given type. - * - * @param type - * the type of the beans that will be added to the container. - * @throws IllegalArgumentException - * If {@code type} is null - */ - public BeanItemContainer(Class<? super BEANTYPE> type) - throws IllegalArgumentException { - super(type); - super.setBeanIdResolver(new IdentityBeanIdResolver<BEANTYPE>()); - } - - /** - * Constructs a {@code BeanItemContainer} and adds the given beans to it. - * The collection must not be empty. - * {@link BeanItemContainer#BeanItemContainer(Class)} can be used for - * creating an initially empty {@code BeanItemContainer}. - * - * Note that when using this constructor, the actual class of the first item - * in the collection is used to determine the bean properties supported by - * the container instance, and only beans of that class or its subclasses - * can be added to the collection. If this is problematic or empty - * collections need to be supported, use {@link #BeanItemContainer(Class)} - * and {@link #addAll(Collection)} instead. - * - * @param collection - * a non empty {@link Collection} of beans. - * @throws IllegalArgumentException - * If the collection is null or empty. - * - * @deprecated As of 6.5, use {@link #BeanItemContainer(Class, Collection)} - * instead - */ - @SuppressWarnings("unchecked") - @Deprecated - public BeanItemContainer(Collection<? extends BEANTYPE> collection) - throws IllegalArgumentException { - // must assume the class is BT - // the class information is erased by the compiler - this((Class<BEANTYPE>) getBeanClassForCollection(collection), - collection); - } - - /** - * Internal helper method to support the deprecated {@link Collection} - * container. - * - * @param <BT> - * @param collection - * @return - * @throws IllegalArgumentException - */ - @SuppressWarnings("unchecked") - @Deprecated - private static <BT> Class<? extends BT> getBeanClassForCollection( - Collection<? extends BT> collection) - throws IllegalArgumentException { - if (collection == null || collection.isEmpty()) { - throw new IllegalArgumentException( - "The collection passed to BeanItemContainer constructor must not be null or empty. Use the other BeanItemContainer constructor."); - } - return (Class<? extends BT>) collection.iterator().next().getClass(); - } - - /** - * Constructs a {@code BeanItemContainer} and adds the given beans to it. - * - * @param type - * the type of the beans that will be added to the container. - * @param collection - * a {@link Collection} of beans (can be empty or null). - * @throws IllegalArgumentException - * If {@code type} is null - */ - public BeanItemContainer(Class<? super BEANTYPE> type, - Collection<? extends BEANTYPE> collection) - throws IllegalArgumentException { - super(type); - super.setBeanIdResolver(new IdentityBeanIdResolver<BEANTYPE>()); - - if (collection != null) { - addAll(collection); - } - } - - /** - * Adds all the beans from a {@link Collection} in one go. More efficient - * than adding them one by one. - * - * @param collection - * The collection of beans to add. Must not be null. - */ - @Override - public void addAll(Collection<? extends BEANTYPE> collection) { - super.addAll(collection); - } - - /** - * Adds the bean after the given bean. - * - * The bean is used both as the item contents and as the item identifier. - * - * @param previousItemId - * the bean (of type BT) after which to add newItemId - * @param newItemId - * the bean (of type BT) to add (not null) - * - * @see com.vaadin.data.Container.Ordered#addItemAfter(Object, Object) - */ - @Override - @SuppressWarnings("unchecked") - public BeanItem<BEANTYPE> addItemAfter(Object previousItemId, - Object newItemId) throws IllegalArgumentException { - return super.addBeanAfter((BEANTYPE) previousItemId, - (BEANTYPE) newItemId); - } - - /** - * Adds a new bean at the given index. - * - * The bean is used both as the item contents and as the item identifier. - * - * @param index - * Index at which the bean should be added. - * @param newItemId - * The bean to add to the container. - * @return Returns the new BeanItem or null if the operation fails. - */ - @Override - @SuppressWarnings("unchecked") - public BeanItem<BEANTYPE> addItemAt(int index, Object newItemId) - throws IllegalArgumentException { - return super.addBeanAt(index, (BEANTYPE) newItemId); - } - - /** - * Adds the bean to the Container. - * - * The bean is used both as the item contents and as the item identifier. - * - * @see com.vaadin.data.Container#addItem(Object) - */ - @Override - @SuppressWarnings("unchecked") - public BeanItem<BEANTYPE> addItem(Object itemId) { - return super.addBean((BEANTYPE) itemId); - } - - /** - * Adds the bean to the Container. - * - * The bean is used both as the item contents and as the item identifier. - * - * @see com.vaadin.data.Container#addItem(Object) - */ - @Override - public BeanItem<BEANTYPE> addBean(BEANTYPE bean) { - return addItem(bean); - } - - /** - * Unsupported in BeanItemContainer. - */ - @Override - protected void setBeanIdResolver( - AbstractBeanContainer.BeanIdResolver<BEANTYPE, BEANTYPE> beanIdResolver) - throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "BeanItemContainer always uses an IdentityBeanIdResolver"); - } - -} diff --git a/server/src/main/java/com/vaadin/data/util/ContainerHierarchicalWrapper.java b/server/src/main/java/com/vaadin/data/util/ContainerHierarchicalWrapper.java deleted file mode 100644 index 9e108cd615..0000000000 --- a/server/src/main/java/com/vaadin/data/util/ContainerHierarchicalWrapper.java +++ /dev/null @@ -1,865 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util; - -import java.io.Serializable; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.LinkedList; - -import com.vaadin.data.Container; -import com.vaadin.data.Item; -import com.vaadin.data.Property; - -/** - * <p> - * A wrapper class for adding external hierarchy to containers not implementing - * the {@link com.vaadin.data.Container.Hierarchical} interface. - * </p> - * - * <p> - * If the wrapped container is changed directly (that is, not through the - * wrapper), and does not implement Container.ItemSetChangeNotifier and/or - * Container.PropertySetChangeNotifier the hierarchy information must be updated - * with the {@link #updateHierarchicalWrapper()} method. - * </p> - * - * @author Vaadin Ltd. - * @since 3.0 - */ -@SuppressWarnings("serial") -public class ContainerHierarchicalWrapper implements Container.Hierarchical, - Container.ItemSetChangeNotifier, Container.PropertySetChangeNotifier { - - /** The wrapped container */ - private final Container container; - - /** Set of IDs of those contained Items that can't have children. */ - private HashSet<Object> noChildrenAllowed = null; - - /** Mapping from Item ID to parent Item ID */ - private Hashtable<Object, Object> parent = null; - - /** Mapping from Item ID to a list of child IDs */ - private Hashtable<Object, LinkedList<Object>> children = null; - - /** List that contains all root elements of the container. */ - private LinkedHashSet<Object> roots = null; - - /** Is the wrapped container hierarchical by itself ? */ - private boolean hierarchical; - - /** - * A comparator that sorts the listed items before other items. Otherwise, - * the order is undefined. - */ - private static class ListedItemsFirstComparator - implements Comparator<Object>, Serializable { - private final Collection<?> itemIds; - - private ListedItemsFirstComparator(Collection<?> itemIds) { - this.itemIds = itemIds; - } - - @Override - public int compare(Object o1, Object o2) { - if (o1.equals(o2)) { - return 0; - } - for (Object id : itemIds) { - if (id == o1) { - return -1; - } else if (id == o2) { - return 1; - } - } - return 0; - } - } - - /** - * Constructs a new hierarchical wrapper for an existing Container. Works - * even if the to-be-wrapped container already implements the - * <code>Container.Hierarchical</code> interface. - * - * @param toBeWrapped - * the container that needs to be accessed hierarchically - * @see #updateHierarchicalWrapper() - */ - public ContainerHierarchicalWrapper(Container toBeWrapped) { - - container = toBeWrapped; - hierarchical = container instanceof Container.Hierarchical; - - // Check arguments - if (container == null) { - throw new NullPointerException("Null can not be wrapped"); - } - - // Create initial order if needed - if (!hierarchical) { - noChildrenAllowed = new HashSet<Object>(); - parent = new Hashtable<Object, Object>(); - children = new Hashtable<Object, LinkedList<Object>>(); - roots = new LinkedHashSet<Object>(container.getItemIds()); - } - - updateHierarchicalWrapper(); - - } - - /** - * Updates the wrapper's internal hierarchy data to include all Items in the - * underlying container. If the contents of the wrapped container change - * without the wrapper's knowledge, this method needs to be called to update - * the hierarchy information of the Items. - */ - public void updateHierarchicalWrapper() { - - if (!hierarchical) { - - // Recreate hierarchy and data structures if missing - if (noChildrenAllowed == null || parent == null || children == null - || roots == null) { - noChildrenAllowed = new HashSet<Object>(); - parent = new Hashtable<Object, Object>(); - children = new Hashtable<Object, LinkedList<Object>>(); - roots = new LinkedHashSet<Object>(container.getItemIds()); - } - - // Check that the hierarchy is up-to-date - else { - - // ensure order of root and child lists is same as in wrapped - // container - Collection<?> itemIds = container.getItemIds(); - Comparator<Object> basedOnOrderFromWrappedContainer = new ListedItemsFirstComparator( - itemIds); - - // Calculate the set of all items in the hierarchy - final HashSet<Object> s = new HashSet<Object>(); - s.addAll(parent.keySet()); - s.addAll(children.keySet()); - s.addAll(roots); - - // Remove unnecessary items - for (final Iterator<Object> i = s.iterator(); i.hasNext();) { - final Object id = i.next(); - if (!container.containsId(id)) { - removeFromHierarchyWrapper(id); - } - } - - // Add all the missing items - final Collection<?> ids = container.getItemIds(); - for (final Iterator<?> i = ids.iterator(); i.hasNext();) { - final Object id = i.next(); - if (!s.contains(id)) { - addToHierarchyWrapper(id); - s.add(id); - } - } - - Object[] array = roots.toArray(); - Arrays.sort(array, basedOnOrderFromWrappedContainer); - roots = new LinkedHashSet<Object>(); - for (int i = 0; i < array.length; i++) { - roots.add(array[i]); - } - for (Object object : children.keySet()) { - LinkedList<Object> object2 = children.get(object); - Collections.sort(object2, basedOnOrderFromWrappedContainer); - } - - } - } - } - - /** - * Removes the specified Item from the wrapper's internal hierarchy - * structure. - * <p> - * Note : The Item is not removed from the underlying Container. - * </p> - * - * @param itemId - * the ID of the item to remove from the hierarchy. - */ - private void removeFromHierarchyWrapper(Object itemId) { - - LinkedList<Object> oprhanedChildren = children.remove(itemId); - if (oprhanedChildren != null) { - for (Object object : oprhanedChildren) { - // make orphaned children root nodes - setParent(object, null); - } - } - - roots.remove(itemId); - final Object p = parent.get(itemId); - if (p != null) { - final LinkedList<Object> c = children.get(p); - if (c != null) { - c.remove(itemId); - } - } - parent.remove(itemId); - noChildrenAllowed.remove(itemId); - } - - /** - * Adds the specified Item specified to the internal hierarchy structure. - * The new item is added as a root Item. The underlying container is not - * modified. - * - * @param itemId - * the ID of the item to add to the hierarchy. - */ - private void addToHierarchyWrapper(Object itemId) { - roots.add(itemId); - - } - - /* - * Can the specified Item have any children? Don't add a JavaDoc comment - * here, we use the default documentation from implemented interface. - */ - @Override - public boolean areChildrenAllowed(Object itemId) { - - // If the wrapped container implements the method directly, use it - if (hierarchical) { - return ((Container.Hierarchical) container) - .areChildrenAllowed(itemId); - } - - if (noChildrenAllowed.contains(itemId)) { - return false; - } - - return containsId(itemId); - } - - /* - * Gets the IDs of the children of the specified Item. Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public Collection<?> getChildren(Object itemId) { - - // If the wrapped container implements the method directly, use it - if (hierarchical) { - return ((Container.Hierarchical) container).getChildren(itemId); - } - - final Collection<?> c = children.get(itemId); - if (c == null) { - return null; - } - return Collections.unmodifiableCollection(c); - } - - /* - * Gets the ID of the parent of the specified Item. Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public Object getParent(Object itemId) { - - // If the wrapped container implements the method directly, use it - if (hierarchical) { - return ((Container.Hierarchical) container).getParent(itemId); - } - - return parent.get(itemId); - } - - /* - * Is the Item corresponding to the given ID a leaf node? Don't add a - * JavaDoc comment here, we use the default documentation from implemented - * interface. - */ - @Override - public boolean hasChildren(Object itemId) { - - // If the wrapped container implements the method directly, use it - if (hierarchical) { - return ((Container.Hierarchical) container).hasChildren(itemId); - } - - LinkedList<Object> list = children.get(itemId); - return (list != null && !list.isEmpty()); - } - - /* - * Is the Item corresponding to the given ID a root node? Don't add a - * JavaDoc comment here, we use the default documentation from implemented - * interface. - */ - @Override - public boolean isRoot(Object itemId) { - - // If the wrapped container implements the method directly, use it - if (hierarchical) { - return ((Container.Hierarchical) container).isRoot(itemId); - } - - if (parent.containsKey(itemId)) { - return false; - } - - return containsId(itemId); - } - - /* - * Gets the IDs of the root elements in the container. Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public Collection<?> rootItemIds() { - - // If the wrapped container implements the method directly, use it - if (hierarchical) { - return ((Container.Hierarchical) container).rootItemIds(); - } - - return Collections.unmodifiableCollection(roots); - } - - /** - * <p> - * Sets the given Item's capability to have children. If the Item identified - * with the itemId already has children and the areChildrenAllowed is false - * this method fails and <code>false</code> is returned; the children must - * be first explicitly removed with - * {@link #setParent(Object itemId, Object newParentId)} or - * {@link com.vaadin.data.Container#removeItem(Object itemId)}. - * </p> - * - * @param itemId - * the ID of the Item in the container whose child capability is - * to be set. - * @param childrenAllowed - * the boolean value specifying if the Item can have children or - * not. - * @return <code>true</code> if the operation succeeded, <code>false</code> - * if not - */ - @Override - public boolean setChildrenAllowed(Object itemId, boolean childrenAllowed) { - - // If the wrapped container implements the method directly, use it - if (hierarchical) { - return ((Container.Hierarchical) container) - .setChildrenAllowed(itemId, childrenAllowed); - } - - // Check that the item is in the container - if (!containsId(itemId)) { - return false; - } - - // Update status - if (childrenAllowed) { - noChildrenAllowed.remove(itemId); - } else { - noChildrenAllowed.add(itemId); - } - - return true; - } - - /** - * <p> - * Sets the parent of an Item. The new parent item must exist and be able to - * have children. (<code>canHaveChildren(newParentId) == true</code>). It is - * also possible to detach a node from the hierarchy (and thus make it root) - * by setting the parent <code>null</code>. - * </p> - * - * @param itemId - * the ID of the item to be set as the child of the Item - * identified with newParentId. - * @param newParentId - * the ID of the Item that's to be the new parent of the Item - * identified with itemId. - * @return <code>true</code> if the operation succeeded, <code>false</code> - * if not - */ - @Override - public boolean setParent(Object itemId, Object newParentId) { - - // If the wrapped container implements the method directly, use it - if (hierarchical) { - return ((Container.Hierarchical) container).setParent(itemId, - newParentId); - } - - // Check that the item is in the container - if (!containsId(itemId)) { - return false; - } - - // Get the old parent - final Object oldParentId = parent.get(itemId); - - // Check if no change is necessary - if ((newParentId == null && oldParentId == null) - || (newParentId != null && newParentId.equals(oldParentId))) { - return true; - } - - // Making root - if (newParentId == null) { - - // Remove from old parents children list - final LinkedList<Object> l = children.get(oldParentId); - if (l != null) { - l.remove(itemId); - if (l.isEmpty()) { - children.remove(itemId); - } - } - - // Add to be a root - roots.add(itemId); - - // Update parent - parent.remove(itemId); - - fireItemSetChangeIfAbstractContainer(); - - return true; - } - - // Check that the new parent exists in container and can have - // children - if (!containsId(newParentId) - || noChildrenAllowed.contains(newParentId)) { - return false; - } - - // Check that setting parent doesn't result to a loop - Object o = newParentId; - while (o != null && !o.equals(itemId)) { - o = parent.get(o); - } - if (o != null) { - return false; - } - - // Update parent - parent.put(itemId, newParentId); - LinkedList<Object> pcl = children.get(newParentId); - if (pcl == null) { - pcl = new LinkedList<Object>(); - children.put(newParentId, pcl); - } - pcl.add(itemId); - - // Remove from old parent or root - if (oldParentId == null) { - roots.remove(itemId); - } else { - final LinkedList<Object> l = children.get(oldParentId); - if (l != null) { - l.remove(itemId); - if (l.isEmpty()) { - children.remove(oldParentId); - } - } - } - - fireItemSetChangeIfAbstractContainer(); - - return true; - } - - /** - * inform container (if it is instance of AbstractContainer) about the - * change in hierarchy (#15421) - */ - private void fireItemSetChangeIfAbstractContainer() { - if (container instanceof AbstractContainer) { - ((AbstractContainer) container).fireItemSetChange(); - } - } - - /** - * Creates a new Item into the Container, assigns it an automatic ID, and - * adds it to the hierarchy. - * - * @return the autogenerated ID of the new Item or <code>null</code> if the - * operation failed - * @throws UnsupportedOperationException - * if the addItem is not supported. - */ - @Override - public Object addItem() throws UnsupportedOperationException { - - final Object id = container.addItem(); - if (!hierarchical && id != null) { - addToHierarchyWrapper(id); - } - return id; - } - - /** - * Adds a new Item by its ID to the underlying container and to the - * hierarchy. - * - * @param itemId - * the ID of the Item to be created. - * @return the added Item or <code>null</code> if the operation failed. - * @throws UnsupportedOperationException - * if the addItem is not supported. - */ - @Override - public Item addItem(Object itemId) throws UnsupportedOperationException { - // Null ids are not accepted - if (itemId == null) { - return null; - } - - final Item item = container.addItem(itemId); - if (!hierarchical && item != null) { - addToHierarchyWrapper(itemId); - } - return item; - } - - /** - * Removes all items from the underlying container and from the hierarcy. - * - * @return <code>true</code> if the operation succeeded, <code>false</code> - * if not - * @throws UnsupportedOperationException - * if the removeAllItems is not supported. - */ - @Override - public boolean removeAllItems() throws UnsupportedOperationException { - - final boolean success = container.removeAllItems(); - - if (!hierarchical && success) { - roots.clear(); - parent.clear(); - children.clear(); - noChildrenAllowed.clear(); - } - return success; - } - - /** - * Removes an Item specified by the itemId from the underlying container and - * from the hierarchy. - * - * @param itemId - * the ID of the Item to be removed. - * @return <code>true</code> if the operation succeeded, <code>false</code> - * if not - * @throws UnsupportedOperationException - * if the removeItem is not supported. - */ - @Override - public boolean removeItem(Object itemId) - throws UnsupportedOperationException { - - final boolean success = container.removeItem(itemId); - - if (!hierarchical && success) { - removeFromHierarchyWrapper(itemId); - } - - return success; - } - - /** - * Removes the Item identified by given itemId and all its children. - * - * @see #removeItem(Object) - * @param itemId - * the identifier of the Item to be removed - * @return true if the operation succeeded - */ - public boolean removeItemRecursively(Object itemId) { - return HierarchicalContainer.removeItemRecursively(this, itemId); - } - - /** - * Adds a new Property to all Items in the Container. - * - * @param propertyId - * the ID of the new Property. - * @param type - * the Data type of the new Property. - * @param defaultValue - * the value all created Properties are initialized to. - * @return <code>true</code> if the operation succeeded, <code>false</code> - * if not - * @throws UnsupportedOperationException - * if the addContainerProperty is not supported. - */ - @Override - public boolean addContainerProperty(Object propertyId, Class<?> type, - Object defaultValue) throws UnsupportedOperationException { - - return container.addContainerProperty(propertyId, type, defaultValue); - } - - /** - * Removes the specified Property from the underlying container and from the - * hierarchy. - * <p> - * Note : The Property will be removed from all Items in the Container. - * </p> - * - * @param propertyId - * the ID of the Property to remove. - * @return <code>true</code> if the operation succeeded, <code>false</code> - * if not - * @throws UnsupportedOperationException - * if the removeContainerProperty is not supported. - */ - @Override - public boolean removeContainerProperty(Object propertyId) - throws UnsupportedOperationException { - return container.removeContainerProperty(propertyId); - } - - /* - * Does the container contain the specified Item? Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public boolean containsId(Object itemId) { - return container.containsId(itemId); - } - - /* - * Gets the specified Item from the container. Don't add a JavaDoc comment - * here, we use the default documentation from implemented interface. - */ - @Override - public Item getItem(Object itemId) { - return container.getItem(itemId); - } - - /* - * Gets the ID's of all Items stored in the Container Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public Collection<?> getItemIds() { - return container.getItemIds(); - } - - /* - * Gets the Property identified by the given itemId and propertyId from the - * Container Don't add a JavaDoc comment here, we use the default - * documentation from implemented interface. - */ - @Override - public Property getContainerProperty(Object itemId, Object propertyId) { - return container.getContainerProperty(itemId, propertyId); - } - - /* - * Gets the ID's of all Properties stored in the Container Don't add a - * JavaDoc comment here, we use the default documentation from implemented - * interface. - */ - @Override - public Collection<?> getContainerPropertyIds() { - return container.getContainerPropertyIds(); - } - - /* - * Gets the data type of all Properties identified by the given Property ID. - * Don't add a JavaDoc comment here, we use the default documentation from - * implemented interface. - */ - @Override - public Class<?> getType(Object propertyId) { - return container.getType(propertyId); - } - - /* - * Gets the number of Items in the Container. Don't add a JavaDoc comment - * here, we use the default documentation from implemented interface. - */ - @Override - public int size() { - int size = container.size(); - assert size >= 0; - return size; - } - - /* - * Registers a new Item set change listener for this Container. Don't add a - * JavaDoc comment here, we use the default documentation from implemented - * interface. - */ - @Override - public void addItemSetChangeListener( - Container.ItemSetChangeListener listener) { - if (container instanceof Container.ItemSetChangeNotifier) { - ((Container.ItemSetChangeNotifier) container) - .addItemSetChangeListener(new PiggybackListener(listener)); - } - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #addItemSetChangeListener(com.vaadin.data.Container.ItemSetChangeListener)} - **/ - @Override - @Deprecated - public void addListener(Container.ItemSetChangeListener listener) { - addItemSetChangeListener(listener); - } - - /* - * Removes a Item set change listener from the object. Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public void removeItemSetChangeListener( - Container.ItemSetChangeListener listener) { - if (container instanceof Container.ItemSetChangeNotifier) { - ((Container.ItemSetChangeNotifier) container) - .removeItemSetChangeListener( - new PiggybackListener(listener)); - } - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #removeItemSetChangeListener(com.vaadin.data.Container.ItemSetChangeListener)} - **/ - @Override - @Deprecated - public void removeListener(Container.ItemSetChangeListener listener) { - removeItemSetChangeListener(listener); - } - - /* - * Registers a new Property set change listener for this Container. Don't - * add a JavaDoc comment here, we use the default documentation from - * implemented interface. - */ - @Override - public void addPropertySetChangeListener( - Container.PropertySetChangeListener listener) { - if (container instanceof Container.PropertySetChangeNotifier) { - ((Container.PropertySetChangeNotifier) container) - .addPropertySetChangeListener( - new PiggybackListener(listener)); - } - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #addPropertySetChangeListener(com.vaadin.data.Container.PropertySetChangeListener)} - **/ - @Override - @Deprecated - public void addListener(Container.PropertySetChangeListener listener) { - addPropertySetChangeListener(listener); - } - - /* - * Removes a Property set change listener from the object. Don't add a - * JavaDoc comment here, we use the default documentation from implemented - * interface. - */ - @Override - public void removePropertySetChangeListener( - Container.PropertySetChangeListener listener) { - if (container instanceof Container.PropertySetChangeNotifier) { - ((Container.PropertySetChangeNotifier) container) - .removePropertySetChangeListener( - new PiggybackListener(listener)); - } - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #removePropertySetChangeListener(com.vaadin.data.Container.PropertySetChangeListener)} - **/ - @Override - @Deprecated - public void removeListener(Container.PropertySetChangeListener listener) { - removePropertySetChangeListener(listener); - } - - /** - * This listener 'piggybacks' on the real listener in order to update the - * wrapper when needed. It proxies equals() and hashCode() to the real - * listener so that the correct listener gets removed. - * - */ - private class PiggybackListener - implements Container.PropertySetChangeListener, - Container.ItemSetChangeListener { - - Object listener; - - public PiggybackListener(Object realListener) { - listener = realListener; - } - - @Override - public void containerItemSetChange(ItemSetChangeEvent event) { - updateHierarchicalWrapper(); - ((Container.ItemSetChangeListener) listener) - .containerItemSetChange(event); - - } - - @Override - public void containerPropertySetChange(PropertySetChangeEvent event) { - updateHierarchicalWrapper(); - ((Container.PropertySetChangeListener) listener) - .containerPropertySetChange(event); - - } - - @Override - public boolean equals(Object obj) { - return obj == listener || (obj != null && obj.equals(listener)); - } - - @Override - public int hashCode() { - return listener.hashCode(); - } - - } -} diff --git a/server/src/main/java/com/vaadin/data/util/FilesystemContainer.java b/server/src/main/java/com/vaadin/data/util/FilesystemContainer.java deleted file mode 100644 index 46b4f4bcd4..0000000000 --- a/server/src/main/java/com/vaadin/data/util/FilesystemContainer.java +++ /dev/null @@ -1,924 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util; - -import java.io.File; -import java.io.FilenameFilter; -import java.io.IOException; -import java.io.Serializable; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -import com.vaadin.data.Container; -import com.vaadin.data.Item; -import com.vaadin.data.Property; -import com.vaadin.server.Resource; -import com.vaadin.util.FileTypeResolver; - -/** - * A hierarchical container wrapper for a filesystem. - * - * @author Vaadin Ltd. - * @since 3.0 - */ -@SuppressWarnings("serial") -public class FilesystemContainer implements Container.Hierarchical { - - /** - * String identifier of a file's "name" property. - */ - public static String PROPERTY_NAME = "Name"; - - /** - * String identifier of a file's "size" property. - */ - public static String PROPERTY_SIZE = "Size"; - - /** - * String identifier of a file's "icon" property. - */ - public static String PROPERTY_ICON = "Icon"; - - /** - * String identifier of a file's "last modified" property. - */ - public static String PROPERTY_LASTMODIFIED = "Last Modified"; - - /** - * List of the string identifiers for the available properties. - */ - public static Collection<String> FILE_PROPERTIES; - - private final static Method FILEITEM_LASTMODIFIED; - - private final static Method FILEITEM_NAME; - - private final static Method FILEITEM_ICON; - - private final static Method FILEITEM_SIZE; - - static { - - FILE_PROPERTIES = new ArrayList<String>(); - FILE_PROPERTIES.add(PROPERTY_NAME); - FILE_PROPERTIES.add(PROPERTY_ICON); - FILE_PROPERTIES.add(PROPERTY_SIZE); - FILE_PROPERTIES.add(PROPERTY_LASTMODIFIED); - FILE_PROPERTIES = Collections.unmodifiableCollection(FILE_PROPERTIES); - try { - FILEITEM_LASTMODIFIED = FileItem.class.getMethod("lastModified", - new Class[] {}); - FILEITEM_NAME = FileItem.class.getMethod("getName", new Class[] {}); - FILEITEM_ICON = FileItem.class.getMethod("getIcon", new Class[] {}); - FILEITEM_SIZE = FileItem.class.getMethod("getSize", new Class[] {}); - } catch (final NoSuchMethodException e) { - throw new RuntimeException( - "Internal error finding methods in FilesystemContainer"); - } - } - - private File[] roots = new File[] {}; - - private FilenameFilter filter = null; - - private boolean recursive = true; - - /** - * Constructs a new <code>FileSystemContainer</code> with the specified file - * as the root of the filesystem. The files are included recursively. - * - * @param root - * the root file for the new file-system container. Null values - * are ignored. - */ - public FilesystemContainer(File root) { - if (root != null) { - roots = new File[] { root }; - } - } - - /** - * Constructs a new <code>FileSystemContainer</code> with the specified file - * as the root of the filesystem. The files are included recursively. - * - * @param root - * the root file for the new file-system container. - * @param recursive - * should the container recursively contain subdirectories. - */ - public FilesystemContainer(File root, boolean recursive) { - this(root); - setRecursive(recursive); - } - - /** - * Constructs a new <code>FileSystemContainer</code> with the specified file - * as the root of the filesystem. - * - * @param root - * the root file for the new file-system container. - * @param extension - * the Filename extension (w/o separator) to limit the files in - * container. - * @param recursive - * should the container recursively contain subdirectories. - */ - public FilesystemContainer(File root, String extension, boolean recursive) { - this(root); - this.setFilter(extension); - setRecursive(recursive); - } - - /** - * Constructs a new <code>FileSystemContainer</code> with the specified root - * and recursivity status. - * - * @param root - * the root file for the new file-system container. - * @param filter - * the Filename filter to limit the files in container. - * @param recursive - * should the container recursively contain subdirectories. - */ - public FilesystemContainer(File root, FilenameFilter filter, - boolean recursive) { - this(root); - this.setFilter(filter); - setRecursive(recursive); - } - - /** - * Adds new root file directory. Adds a file to be included as root file - * directory in the <code>FilesystemContainer</code>. - * - * @param root - * the File to be added as root directory. Null values are - * ignored. - */ - public void addRoot(File root) { - if (root != null) { - final File[] newRoots = new File[roots.length + 1]; - for (int i = 0; i < roots.length; i++) { - newRoots[i] = roots[i]; - } - newRoots[roots.length] = root; - roots = newRoots; - } - } - - /** - * Tests if the specified Item in the container may have children. Since a - * <code>FileSystemContainer</code> contains files and directories, this - * method returns <code>true</code> for directory Items only. - * - * @param itemId - * the id of the item. - * @return <code>true</code> if the specified Item is a directory, - * <code>false</code> otherwise. - */ - @Override - public boolean areChildrenAllowed(Object itemId) { - return itemId instanceof File && ((File) itemId).canRead() - && ((File) itemId).isDirectory(); - } - - /* - * Gets the ID's of all Items who are children of the specified Item. Don't - * add a JavaDoc comment here, we use the default documentation from - * implemented interface. - */ - @Override - public Collection<File> getChildren(Object itemId) { - - if (!(itemId instanceof File)) { - return Collections.unmodifiableCollection(new LinkedList<File>()); - } - File[] f; - if (filter != null) { - f = ((File) itemId).listFiles(filter); - } else { - f = ((File) itemId).listFiles(); - } - - if (f == null) { - return Collections.unmodifiableCollection(new LinkedList<File>()); - } - - final List<File> l = Arrays.asList(f); - Collections.sort(l); - - return Collections.unmodifiableCollection(l); - } - - /* - * Gets the parent item of the specified Item. Don't add a JavaDoc comment - * here, we use the default documentation from implemented interface. - */ - @Override - public Object getParent(Object itemId) { - - if (!(itemId instanceof File)) { - return null; - } - return ((File) itemId).getParentFile(); - } - - /* - * Tests if the specified Item has any children. Don't add a JavaDoc comment - * here, we use the default documentation from implemented interface. - */ - @Override - public boolean hasChildren(Object itemId) { - - if (!(itemId instanceof File)) { - return false; - } - String[] l; - if (filter != null) { - l = ((File) itemId).list(filter); - } else { - l = ((File) itemId).list(); - } - return (l != null) && (l.length > 0); - } - - /* - * Tests if the specified Item is the root of the filesystem. Don't add a - * JavaDoc comment here, we use the default documentation from implemented - * interface. - */ - @Override - public boolean isRoot(Object itemId) { - - if (!(itemId instanceof File)) { - return false; - } - for (int i = 0; i < roots.length; i++) { - if (roots[i].equals(itemId)) { - return true; - } - } - return false; - } - - /* - * Gets the ID's of all root Items in the container. Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public Collection<File> rootItemIds() { - - File[] f; - - // in single root case we use children - if (roots.length == 1) { - if (filter != null) { - f = roots[0].listFiles(filter); - } else { - f = roots[0].listFiles(); - } - } else { - f = roots; - } - - if (f == null) { - return Collections.unmodifiableCollection(new LinkedList<File>()); - } - - final List<File> l = Arrays.asList(f); - Collections.sort(l); - - return Collections.unmodifiableCollection(l); - } - - /** - * Returns <code>false</code> when conversion from files to directories is - * not supported. - * - * @param itemId - * the ID of the item. - * @param areChildrenAllowed - * the boolean value specifying if the Item can have children or - * not. - * @return <code>true</code> if the operaton is successful otherwise - * <code>false</code>. - * @throws UnsupportedOperationException - * if the setChildrenAllowed is not supported. - */ - @Override - public boolean setChildrenAllowed(Object itemId, boolean areChildrenAllowed) - throws UnsupportedOperationException { - - throw new UnsupportedOperationException( - "Conversion file to/from directory is not supported"); - } - - /** - * Returns <code>false</code> when moving files around in the filesystem is - * not supported. - * - * @param itemId - * the ID of the item. - * @param newParentId - * the ID of the Item that's to be the new parent of the Item - * identified with itemId. - * @return <code>true</code> if the operation is successful otherwise - * <code>false</code>. - * @throws UnsupportedOperationException - * if the setParent is not supported. - */ - @Override - public boolean setParent(Object itemId, Object newParentId) - throws UnsupportedOperationException { - - throw new UnsupportedOperationException("File moving is not supported"); - } - - /* - * Tests if the filesystem contains the specified Item. Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public boolean containsId(Object itemId) { - - if (!(itemId instanceof File)) { - return false; - } - boolean val = false; - - // Try to match all roots - for (int i = 0; i < roots.length; i++) { - try { - val |= ((File) itemId).getCanonicalPath() - .startsWith(roots[i].getCanonicalPath()); - } catch (final IOException e) { - // Exception ignored - } - - } - if (val && filter != null) { - val &= filter.accept(((File) itemId).getParentFile(), - ((File) itemId).getName()); - } - return val; - } - - /* - * Gets the specified Item from the filesystem. Don't add a JavaDoc comment - * here, we use the default documentation from implemented interface. - */ - @Override - public Item getItem(Object itemId) { - - if (!(itemId instanceof File)) { - return null; - } - return new FileItem((File) itemId); - } - - /** - * Internal recursive method to add the files under the specified directory - * to the collection. - * - * @param col - * the collection where the found items are added - * @param f - * the root file where to start adding files - */ - private void addItemIds(Collection<File> col, File f) { - File[] l; - if (filter != null) { - l = f.listFiles(filter); - } else { - l = f.listFiles(); - } - if (l == null) { - // File.listFiles returns null if File does not exist or if there - // was an IO error (permission denied) - return; - } - final List<File> ll = Arrays.asList(l); - Collections.sort(ll); - - for (final Iterator<File> i = ll.iterator(); i.hasNext();) { - final File lf = i.next(); - col.add(lf); - if (lf.isDirectory()) { - addItemIds(col, lf); - } - } - } - - /* - * Gets the IDs of Items in the filesystem. Don't add a JavaDoc comment - * here, we use the default documentation from implemented interface. - */ - @Override - public Collection<File> getItemIds() { - - if (recursive) { - final Collection<File> col = new ArrayList<File>(); - for (int i = 0; i < roots.length; i++) { - addItemIds(col, roots[i]); - } - return Collections.unmodifiableCollection(col); - } else { - File[] f; - if (roots.length == 1) { - if (filter != null) { - f = roots[0].listFiles(filter); - } else { - f = roots[0].listFiles(); - } - } else { - f = roots; - } - - if (f == null) { - return Collections - .unmodifiableCollection(new LinkedList<File>()); - } - - final List<File> l = Arrays.asList(f); - Collections.sort(l); - return Collections.unmodifiableCollection(l); - } - - } - - /** - * Gets the specified property of the specified file Item. The available - * file properties are "Name", "Size" and "Last Modified". If propertyId is - * not one of those, <code>null</code> is returned. - * - * @param itemId - * the ID of the file whose property is requested. - * @param propertyId - * the property's ID. - * @return the requested property's value, or <code>null</code> - */ - @Override - public Property getContainerProperty(Object itemId, Object propertyId) { - - if (!(itemId instanceof File)) { - return null; - } - - if (propertyId.equals(PROPERTY_NAME)) { - return new MethodProperty<Object>(getType(propertyId), - new FileItem((File) itemId), FILEITEM_NAME, null); - } - - if (propertyId.equals(PROPERTY_ICON)) { - return new MethodProperty<Object>(getType(propertyId), - new FileItem((File) itemId), FILEITEM_ICON, null); - } - - if (propertyId.equals(PROPERTY_SIZE)) { - return new MethodProperty<Object>(getType(propertyId), - new FileItem((File) itemId), FILEITEM_SIZE, null); - } - - if (propertyId.equals(PROPERTY_LASTMODIFIED)) { - return new MethodProperty<Object>(getType(propertyId), - new FileItem((File) itemId), FILEITEM_LASTMODIFIED, null); - } - - return null; - } - - /** - * Gets the collection of available file properties. - * - * @return Unmodifiable collection containing all available file properties. - */ - @Override - public Collection<String> getContainerPropertyIds() { - return FILE_PROPERTIES; - } - - /** - * Gets the specified property's data type. "Name" is a <code>String</code>, - * "Size" is a <code>Long</code>, "Last Modified" is a <code>Date</code>. If - * propertyId is not one of those, <code>null</code> is returned. - * - * @param propertyId - * the ID of the property whose type is requested. - * @return data type of the requested property, or <code>null</code> - */ - @Override - public Class<?> getType(Object propertyId) { - - if (propertyId.equals(PROPERTY_NAME)) { - return String.class; - } - if (propertyId.equals(PROPERTY_ICON)) { - return Resource.class; - } - if (propertyId.equals(PROPERTY_SIZE)) { - return Long.class; - } - if (propertyId.equals(PROPERTY_LASTMODIFIED)) { - return Date.class; - } - return null; - } - - /** - * Internal method to recursively calculate the number of files under a root - * directory. - * - * @param f - * the root to start counting from. - */ - private int getFileCounts(File f) { - File[] l; - if (filter != null) { - l = f.listFiles(filter); - } else { - l = f.listFiles(); - } - - if (l == null) { - return 0; - } - int ret = l.length; - for (int i = 0; i < l.length; i++) { - if (l[i].isDirectory()) { - ret += getFileCounts(l[i]); - } - } - return ret; - } - - /** - * Gets the number of Items in the container. In effect, this is the - * combined amount of files and directories. - * - * @return Number of Items in the container. - */ - @Override - public int size() { - - if (recursive) { - int counts = 0; - for (int i = 0; i < roots.length; i++) { - counts += getFileCounts(roots[i]); - } - return counts; - } else { - File[] f; - if (roots.length == 1) { - if (filter != null) { - f = roots[0].listFiles(filter); - } else { - f = roots[0].listFiles(); - } - } else { - f = roots; - } - - if (f == null) { - return 0; - } - return f.length; - } - } - - /** - * A Item wrapper for files in a filesystem. - * - * @author Vaadin Ltd. - * @since 3.0 - */ - public class FileItem implements Item { - - /** - * The wrapped file. - */ - private final File file; - - /** - * Constructs a FileItem from a existing file. - */ - private FileItem(File file) { - this.file = file; - } - - /* - * Gets the specified property of this file. Don't add a JavaDoc comment - * here, we use the default documentation from implemented interface. - */ - @Override - public Property getItemProperty(Object id) { - return getContainerProperty(file, id); - } - - /* - * Gets the IDs of all properties available for this item Don't add a - * JavaDoc comment here, we use the default documentation from - * implemented interface. - */ - @Override - public Collection<String> getItemPropertyIds() { - return getContainerPropertyIds(); - } - - /** - * Calculates a integer hash-code for the Property that's unique inside - * the Item containing the Property. Two different Properties inside the - * same Item contained in the same list always have different - * hash-codes, though Properties in different Items may have identical - * hash-codes. - * - * @return A locally unique hash-code as integer - */ - @Override - public int hashCode() { - return file.hashCode() ^ FilesystemContainer.this.hashCode(); - } - - /** - * Tests if the given object is the same as the this object. Two - * Properties got from an Item with the same ID are equal. - * - * @param obj - * an object to compare with this object. - * @return <code>true</code> if the given object is the same as this - * object, <code>false</code> if not - */ - @Override - public boolean equals(Object obj) { - if (obj == null || !(obj instanceof FileItem)) { - return false; - } - final FileItem fi = (FileItem) obj; - return fi.getHost() == getHost() && fi.file.equals(file); - } - - /** - * Gets the host of this file. - */ - private FilesystemContainer getHost() { - return FilesystemContainer.this; - } - - /** - * Gets the last modified date of this file. - * - * @return Date - */ - public Date lastModified() { - return new Date(file.lastModified()); - } - - /** - * Gets the name of this file. - * - * @return file name of this file. - */ - public String getName() { - return file.getName(); - } - - /** - * Gets the icon of this file. - * - * @return the icon of this file. - */ - public Resource getIcon() { - return FileTypeResolver.getIcon(file); - } - - /** - * Gets the size of this file. - * - * @return size - */ - public long getSize() { - if (file.isDirectory()) { - return 0; - } - return file.length(); - } - - /** - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - if ("".equals(file.getName())) { - return file.getAbsolutePath(); - } - return file.getName(); - } - - /** - * Filesystem container does not support adding new properties. - * - * @see com.vaadin.data.Item#addItemProperty(Object, Property) - */ - @Override - public boolean addItemProperty(Object id, Property property) - throws UnsupportedOperationException { - throw new UnsupportedOperationException("Filesystem container " - + "does not support adding new properties"); - } - - /** - * Filesystem container does not support removing properties. - * - * @see com.vaadin.data.Item#removeItemProperty(Object) - */ - @Override - public boolean removeItemProperty(Object id) - throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "Filesystem container does not support property removal"); - } - - } - - /** - * Generic file extension filter for displaying only files having certain - * extension. - * - * @author Vaadin Ltd. - * @since 3.0 - */ - public class FileExtensionFilter implements FilenameFilter, Serializable { - - private final String filter; - - /** - * Constructs a new FileExtensionFilter using given extension. - * - * @param fileExtension - * the File extension without the separator (dot). - */ - public FileExtensionFilter(String fileExtension) { - filter = "." + fileExtension; - } - - /** - * Allows only files with the extension and directories. - * - * @see java.io.FilenameFilter#accept(File, String) - */ - @Override - public boolean accept(File dir, String name) { - if (name.endsWith(filter)) { - return true; - } - return new File(dir, name).isDirectory(); - } - - } - - /** - * Returns the file filter used to limit the files in this container. - * - * @return Used filter instance or null if no filter is assigned. - */ - public FilenameFilter getFilter() { - return filter; - } - - /** - * Sets the file filter used to limit the files in this container. - * - * @param filter - * The filter to set. <code>null</code> disables filtering. - */ - public void setFilter(FilenameFilter filter) { - this.filter = filter; - } - - /** - * Sets the file filter used to limit the files in this container. - * - * @param extension - * the Filename extension (w/o separator) to limit the files in - * container. - */ - public void setFilter(String extension) { - filter = new FileExtensionFilter(extension); - } - - /** - * Is this container recursive filesystem. - * - * @return <code>true</code> if container is recursive, <code>false</code> - * otherwise. - */ - public boolean isRecursive() { - return recursive; - } - - /** - * Sets the container recursive property. Set this to false to limit the - * files directly under the root file. - * <p> - * Note : This is meaningful only if the root really is a directory. - * </p> - * - * @param recursive - * the New value for recursive property. - */ - public void setRecursive(boolean recursive) { - this.recursive = recursive; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#addContainerProperty(java.lang.Object, - * java.lang.Class, java.lang.Object) - */ - @Override - public boolean addContainerProperty(Object propertyId, Class<?> type, - Object defaultValue) throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "File system container does not support this operation"); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#addItem() - */ - @Override - public Object addItem() throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "File system container does not support this operation"); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#addItem(java.lang.Object) - */ - @Override - public Item addItem(Object itemId) throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "File system container does not support this operation"); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#removeAllItems() - */ - @Override - public boolean removeAllItems() throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "File system container does not support this operation"); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#removeItem(java.lang.Object) - */ - @Override - public boolean removeItem(Object itemId) - throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "File system container does not support this operation"); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#removeContainerProperty(java.lang.Object ) - */ - @Override - public boolean removeContainerProperty(Object propertyId) - throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "File system container does not support this operation"); - } -} diff --git a/server/src/main/java/com/vaadin/data/util/GeneratedPropertyContainer.java b/server/src/main/java/com/vaadin/data/util/GeneratedPropertyContainer.java deleted file mode 100644 index 8d7a1512f9..0000000000 --- a/server/src/main/java/com/vaadin/data/util/GeneratedPropertyContainer.java +++ /dev/null @@ -1,776 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.vaadin.data.Container; -import com.vaadin.data.Item; -import com.vaadin.data.Property; -import com.vaadin.data.sort.SortOrder; -import com.vaadin.data.util.filter.UnsupportedFilterException; -import com.vaadin.shared.data.sort.SortDirection; - -/** - * Container wrapper that adds support for generated properties. This container - * only supports adding new generated properties. Adding new normal properties - * should be done for the wrapped container. - * - * <p> - * Removing properties from this container does not remove anything from the - * wrapped container but instead only hides them from the results. These - * properties can be returned to this container by calling - * {@link #addContainerProperty(Object, Class, Object)} with same property id - * which was removed. - * - * <p> - * If wrapped container is Filterable and/or Sortable it should only be handled - * through this container as generated properties need to be handled in a - * specific way when sorting/filtering. - * - * <p> - * Items returned by this container do not support adding or removing - * properties. Generated properties are always read-only. Trying to make them - * editable throws an exception. - * - * @since 7.4 - * @author Vaadin Ltd - */ -public class GeneratedPropertyContainer extends AbstractContainer - implements Container.Indexed, Container.Sortable, Container.Filterable, - Container.PropertySetChangeNotifier, Container.ItemSetChangeNotifier { - - private final Container.Indexed wrappedContainer; - private final Map<Object, PropertyValueGenerator<?>> propertyGenerators; - private final Map<Filter, List<Filter>> activeFilters; - private Sortable sortableContainer = null; - private Filterable filterableContainer = null; - - /* Removed properties which are hidden but not actually removed */ - private final Set<Object> removedProperties = new HashSet<Object>(); - - /** - * Property implementation for generated properties - */ - protected static class GeneratedProperty<T> implements Property<T> { - - private Item item; - private Object itemId; - private Object propertyId; - private PropertyValueGenerator<T> generator; - - public GeneratedProperty(Item item, Object propertyId, Object itemId, - PropertyValueGenerator<T> generator) { - this.item = item; - this.itemId = itemId; - this.propertyId = propertyId; - this.generator = generator; - } - - @Override - public T getValue() { - return generator.getValue(item, itemId, propertyId); - } - - @Override - public void setValue(T newValue) throws ReadOnlyException { - throw new ReadOnlyException("Generated properties are read only"); - } - - @Override - public Class<? extends T> getType() { - return generator.getType(); - } - - @Override - public boolean isReadOnly() { - return true; - } - - @Override - public void setReadOnly(boolean newStatus) { - if (newStatus) { - // No-op - return; - } - throw new UnsupportedOperationException( - "Generated properties are read only"); - } - } - - /** - * Item implementation for generated properties, used to wrap the Item that - * belongs to the wrapped container. To reach that Item use - * {@link #getWrappedItem()} - */ - public class GeneratedPropertyItem implements Item { - - private Item wrappedItem; - private Object itemId; - - protected GeneratedPropertyItem(Object itemId, Item item) { - this.itemId = itemId; - wrappedItem = item; - } - - @Override - public Property getItemProperty(Object id) { - if (propertyGenerators.containsKey(id)) { - return createProperty(wrappedItem, id, itemId, - propertyGenerators.get(id)); - } - return wrappedItem.getItemProperty(id); - } - - @Override - public Collection<?> getItemPropertyIds() { - Set<Object> wrappedProperties = new LinkedHashSet<Object>( - wrappedItem.getItemPropertyIds()); - wrappedProperties.removeAll(removedProperties); - wrappedProperties.addAll(propertyGenerators.keySet()); - return wrappedProperties; - } - - @Override - public boolean addItemProperty(Object id, Property property) - throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "GeneratedPropertyItem does not support adding properties"); - } - - @Override - public boolean removeItemProperty(Object id) - throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "GeneratedPropertyItem does not support removing properties"); - } - - /** - * Tests if the given object is the same as the this object. Two Items - * from the same container with the same ID are equal. - * - * @param obj - * an object to compare with this object - * @return <code>true</code> if the given object is the same as this - * object, <code>false</code> if not - */ - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - - if (obj == null - || !obj.getClass().equals(GeneratedPropertyItem.class)) { - return false; - } - final GeneratedPropertyItem li = (GeneratedPropertyItem) obj; - return getContainer() == li.getContainer() - && itemId.equals(li.itemId); - } - - @Override - public int hashCode() { - return itemId.hashCode(); - } - - private GeneratedPropertyContainer getContainer() { - return GeneratedPropertyContainer.this; - } - - /** - * Returns the wrapped Item that belongs to the wrapped container - * - * @return wrapped item. - * @since 7.6.8 - */ - public Item getWrappedItem() { - return wrappedItem; - } - }; - - /** - * Base implementation for item add or remove events. This is used when an - * event is fired from wrapped container and needs to be reconstructed to - * act like it actually came from this container. - */ - protected abstract class GeneratedItemAddOrRemoveEvent - implements Serializable { - - private Object firstItemId; - private int firstIndex; - private int count; - - protected GeneratedItemAddOrRemoveEvent(Object itemId, int first, - int count) { - firstItemId = itemId; - firstIndex = first; - this.count = count; - } - - public Container getContainer() { - return GeneratedPropertyContainer.this; - } - - public Object getFirstItemId() { - return firstItemId; - } - - public int getFirstIndex() { - return firstIndex; - } - - public int getAffectedItemsCount() { - return count; - } - }; - - protected class GeneratedItemRemoveEvent - extends GeneratedItemAddOrRemoveEvent implements ItemRemoveEvent { - - protected GeneratedItemRemoveEvent(ItemRemoveEvent event) { - super(event.getFirstItemId(), event.getFirstIndex(), - event.getRemovedItemsCount()); - } - - @Override - public int getRemovedItemsCount() { - return super.getAffectedItemsCount(); - } - } - - protected class GeneratedItemAddEvent extends GeneratedItemAddOrRemoveEvent - implements ItemAddEvent { - - protected GeneratedItemAddEvent(ItemAddEvent event) { - super(event.getFirstItemId(), event.getFirstIndex(), - event.getAddedItemsCount()); - } - - @Override - public int getAddedItemsCount() { - return super.getAffectedItemsCount(); - } - - } - - /** - * Constructor for GeneratedPropertyContainer. - * - * @param container - * underlying indexed container - */ - public GeneratedPropertyContainer(Container.Indexed container) { - wrappedContainer = container; - propertyGenerators = new HashMap<Object, PropertyValueGenerator<?>>(); - - if (wrappedContainer instanceof Sortable) { - sortableContainer = (Sortable) wrappedContainer; - } - - if (wrappedContainer instanceof Filterable) { - activeFilters = new HashMap<Filter, List<Filter>>(); - filterableContainer = (Filterable) wrappedContainer; - } else { - activeFilters = null; - } - - // ItemSetChangeEvents - if (wrappedContainer instanceof ItemSetChangeNotifier) { - ((ItemSetChangeNotifier) wrappedContainer) - .addItemSetChangeListener(new ItemSetChangeListener() { - - @Override - public void containerItemSetChange( - ItemSetChangeEvent event) { - if (event instanceof ItemAddEvent) { - final ItemAddEvent addEvent = (ItemAddEvent) event; - fireItemSetChange( - new GeneratedItemAddEvent(addEvent)); - } else if (event instanceof ItemRemoveEvent) { - final ItemRemoveEvent removeEvent = (ItemRemoveEvent) event; - fireItemSetChange(new GeneratedItemRemoveEvent( - removeEvent)); - } else { - fireItemSetChange(); - } - } - }); - } - - // PropertySetChangeEvents - if (wrappedContainer instanceof PropertySetChangeNotifier) { - ((PropertySetChangeNotifier) wrappedContainer) - .addPropertySetChangeListener( - new PropertySetChangeListener() { - - @Override - public void containerPropertySetChange( - PropertySetChangeEvent event) { - fireContainerPropertySetChange(); - } - }); - } - } - - /* Functions related to generated properties */ - - /** - * Add a new PropertyValueGenerator with given property id. This will - * override any existing properties with the same property id. Fires a - * PropertySetChangeEvent. - * - * @param propertyId - * property id - * @param generator - * a property value generator - */ - public void addGeneratedProperty(Object propertyId, - PropertyValueGenerator<?> generator) { - propertyGenerators.put(propertyId, generator); - fireContainerPropertySetChange(); - } - - /** - * Removes any possible PropertyValueGenerator with given property id. Fires - * a PropertySetChangeEvent. - * - * @param propertyId - * property id - */ - public void removeGeneratedProperty(Object propertyId) { - if (propertyGenerators.containsKey(propertyId)) { - propertyGenerators.remove(propertyId); - fireContainerPropertySetChange(); - } - } - - private Item createGeneratedPropertyItem(final Object itemId, - final Item item) { - return new GeneratedPropertyItem(itemId, item); - } - - private <T> Property<T> createProperty(final Item item, - final Object propertyId, final Object itemId, - final PropertyValueGenerator<T> generator) { - return new GeneratedProperty<T>(item, propertyId, itemId, generator); - } - - /* Listener functionality */ - - @Override - public void addItemSetChangeListener(ItemSetChangeListener listener) { - super.addItemSetChangeListener(listener); - } - - @Override - public void addListener(ItemSetChangeListener listener) { - super.addListener(listener); - } - - @Override - public void removeItemSetChangeListener(ItemSetChangeListener listener) { - super.removeItemSetChangeListener(listener); - } - - @Override - public void removeListener(ItemSetChangeListener listener) { - super.removeListener(listener); - } - - @Override - public void addPropertySetChangeListener( - PropertySetChangeListener listener) { - super.addPropertySetChangeListener(listener); - } - - @Override - public void addListener(PropertySetChangeListener listener) { - super.addListener(listener); - } - - @Override - public void removePropertySetChangeListener( - PropertySetChangeListener listener) { - super.removePropertySetChangeListener(listener); - } - - @Override - public void removeListener(PropertySetChangeListener listener) { - super.removeListener(listener); - } - - /* Filtering functionality */ - - @Override - public void addContainerFilter(Filter filter) - throws UnsupportedFilterException { - if (filterableContainer == null) { - throw new UnsupportedOperationException( - "Wrapped container is not filterable"); - } - - List<Filter> addedFilters = new ArrayList<Filter>(); - for (Entry<?, PropertyValueGenerator<?>> entry : propertyGenerators - .entrySet()) { - Object property = entry.getKey(); - if (filter.appliesToProperty(property)) { - // Have generated property modify filter to fit the original - // data in the container. - Filter modifiedFilter = entry.getValue().modifyFilter(filter); - filterableContainer.addContainerFilter(modifiedFilter); - // Keep track of added filters - addedFilters.add(modifiedFilter); - } - } - - if (addedFilters.isEmpty()) { - // No generated property modified this filter, use it as is - addedFilters.add(filter); - filterableContainer.addContainerFilter(filter); - } - // Map filter to actually added filters - activeFilters.put(filter, addedFilters); - } - - @Override - public void removeContainerFilter(Filter filter) { - if (filterableContainer == null) { - throw new UnsupportedOperationException( - "Wrapped container is not filterable"); - } - - if (activeFilters.containsKey(filter)) { - for (Filter f : activeFilters.get(filter)) { - filterableContainer.removeContainerFilter(f); - } - activeFilters.remove(filter); - } - } - - @Override - public void removeAllContainerFilters() { - if (filterableContainer == null) { - throw new UnsupportedOperationException( - "Wrapped container is not filterable"); - } - filterableContainer.removeAllContainerFilters(); - activeFilters.clear(); - } - - @Override - public Collection<Filter> getContainerFilters() { - if (filterableContainer == null) { - throw new UnsupportedOperationException( - "Wrapped container is not filterable"); - } - return Collections.unmodifiableSet(activeFilters.keySet()); - } - - /* Sorting functionality */ - - @Override - public void sort(Object[] propertyId, boolean[] ascending) { - if (sortableContainer == null) { - throw new UnsupportedOperationException( - "Wrapped container is not Sortable"); - } - - if (propertyId.length == 0) { - sortableContainer.sort(propertyId, ascending); - return; - } - - List<Object> actualSortProperties = new ArrayList<Object>(); - List<Boolean> actualSortDirections = new ArrayList<Boolean>(); - - for (int i = 0; i < propertyId.length; ++i) { - Object property = propertyId[i]; - SortDirection direction; - boolean isAscending = i < ascending.length ? ascending[i] : true; - if (isAscending) { - direction = SortDirection.ASCENDING; - } else { - direction = SortDirection.DESCENDING; - } - - if (propertyGenerators.containsKey(property)) { - // Sorting by a generated property. Generated property should - // modify sort orders to work with original properties in the - // container. - for (SortOrder s : propertyGenerators.get(property) - .getSortProperties( - new SortOrder(property, direction))) { - actualSortProperties.add(s.getPropertyId()); - actualSortDirections - .add(s.getDirection() == SortDirection.ASCENDING); - } - } else { - actualSortProperties.add(property); - actualSortDirections.add(isAscending); - } - } - - boolean[] actualAscending = new boolean[actualSortDirections.size()]; - for (int i = 0; i < actualAscending.length; ++i) { - actualAscending[i] = actualSortDirections.get(i); - } - - sortableContainer.sort(actualSortProperties.toArray(), actualAscending); - } - - @Override - public Collection<?> getSortableContainerPropertyIds() { - if (sortableContainer == null) { - return Collections.emptySet(); - } - - Set<Object> sortablePropertySet = new HashSet<Object>( - sortableContainer.getSortableContainerPropertyIds()); - for (Entry<?, PropertyValueGenerator<?>> entry : propertyGenerators - .entrySet()) { - Object property = entry.getKey(); - SortOrder order = new SortOrder(property, SortDirection.ASCENDING); - if (entry.getValue().getSortProperties(order).length > 0) { - sortablePropertySet.add(property); - } else { - sortablePropertySet.remove(property); - } - } - - return sortablePropertySet; - } - - /* Item related overrides */ - - @Override - public Item addItemAfter(Object previousItemId, Object newItemId) - throws UnsupportedOperationException { - Item item = wrappedContainer.addItemAfter(previousItemId, newItemId); - if (item == null) { - return null; - } - return createGeneratedPropertyItem(newItemId, item); - } - - @Override - public Item addItem(Object itemId) throws UnsupportedOperationException { - Item item = wrappedContainer.addItem(itemId); - if (item == null) { - return null; - } - return createGeneratedPropertyItem(itemId, item); - } - - @Override - public Item addItemAt(int index, Object newItemId) - throws UnsupportedOperationException { - Item item = wrappedContainer.addItemAt(index, newItemId); - if (item == null) { - return null; - } - return createGeneratedPropertyItem(newItemId, item); - } - - @Override - public Item getItem(Object itemId) { - Item item = wrappedContainer.getItem(itemId); - if (item == null) { - return null; - } - - return createGeneratedPropertyItem(itemId, item); - } - - /* Property related overrides */ - - @Override - public Property<?> getContainerProperty(Object itemId, Object propertyId) { - if (propertyGenerators.keySet().contains(propertyId)) { - return getItem(itemId).getItemProperty(propertyId); - } else if (!removedProperties.contains(propertyId)) { - return wrappedContainer.getContainerProperty(itemId, propertyId); - } - return null; - } - - /** - * Returns a list of propety ids available in this container. This - * collection will contain properties for generated properties. Removed - * properties will not show unless there is a generated property overriding - * those. - */ - @Override - public Collection<?> getContainerPropertyIds() { - Set<Object> wrappedProperties = new LinkedHashSet<Object>( - wrappedContainer.getContainerPropertyIds()); - wrappedProperties.removeAll(removedProperties); - wrappedProperties.addAll(propertyGenerators.keySet()); - return wrappedProperties; - } - - /** - * Adds a previously removed property back to GeneratedPropertyContainer. - * Adding a property that is not previously removed causes an - * UnsupportedOperationException. - */ - @Override - public boolean addContainerProperty(Object propertyId, Class<?> type, - Object defaultValue) throws UnsupportedOperationException { - if (!removedProperties.contains(propertyId)) { - throw new UnsupportedOperationException( - "GeneratedPropertyContainer does not support adding properties."); - } - removedProperties.remove(propertyId); - fireContainerPropertySetChange(); - return true; - } - - /** - * Marks the given property as hidden. This property from wrapped container - * will be removed from {@link #getContainerPropertyIds()} and is no longer - * be available in Items retrieved from this container. - */ - @Override - public boolean removeContainerProperty(Object propertyId) - throws UnsupportedOperationException { - if (wrappedContainer.getContainerPropertyIds().contains(propertyId) - && removedProperties.add(propertyId)) { - fireContainerPropertySetChange(); - return true; - } - return false; - } - - /* Type related overrides */ - - @Override - public Class<?> getType(Object propertyId) { - if (propertyGenerators.containsKey(propertyId)) { - return propertyGenerators.get(propertyId).getType(); - } else { - return wrappedContainer.getType(propertyId); - } - } - - /* Unmodified functions */ - - @Override - public Object nextItemId(Object itemId) { - return wrappedContainer.nextItemId(itemId); - } - - @Override - public Object prevItemId(Object itemId) { - return wrappedContainer.prevItemId(itemId); - } - - @Override - public Object firstItemId() { - return wrappedContainer.firstItemId(); - } - - @Override - public Object lastItemId() { - return wrappedContainer.lastItemId(); - } - - @Override - public boolean isFirstId(Object itemId) { - return wrappedContainer.isFirstId(itemId); - } - - @Override - public boolean isLastId(Object itemId) { - return wrappedContainer.isLastId(itemId); - } - - @Override - public Object addItemAfter(Object previousItemId) - throws UnsupportedOperationException { - return wrappedContainer.addItemAfter(previousItemId); - } - - @Override - public Collection<?> getItemIds() { - return wrappedContainer.getItemIds(); - } - - @Override - public int size() { - return wrappedContainer.size(); - } - - @Override - public boolean containsId(Object itemId) { - return wrappedContainer.containsId(itemId); - } - - @Override - public Object addItem() throws UnsupportedOperationException { - return wrappedContainer.addItem(); - } - - @Override - public boolean removeItem(Object itemId) - throws UnsupportedOperationException { - return wrappedContainer.removeItem(itemId); - } - - @Override - public boolean removeAllItems() throws UnsupportedOperationException { - return wrappedContainer.removeAllItems(); - } - - @Override - public int indexOfId(Object itemId) { - return wrappedContainer.indexOfId(itemId); - } - - @Override - public Object getIdByIndex(int index) { - return wrappedContainer.getIdByIndex(index); - } - - @Override - public List<?> getItemIds(int startIndex, int numberOfItems) { - return wrappedContainer.getItemIds(startIndex, numberOfItems); - } - - @Override - public Object addItemAt(int index) throws UnsupportedOperationException { - return wrappedContainer.addItemAt(index); - } - - /** - * Returns the original underlying container. - * - * @return the original underlying container - */ - public Container.Indexed getWrappedContainer() { - return wrappedContainer; - } -} diff --git a/server/src/main/java/com/vaadin/data/util/HierarchicalContainer.java b/server/src/main/java/com/vaadin/data/util/HierarchicalContainer.java deleted file mode 100644 index 115fd91791..0000000000 --- a/server/src/main/java/com/vaadin/data/util/HierarchicalContainer.java +++ /dev/null @@ -1,860 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.vaadin.data.Container; -import com.vaadin.data.Item; - -/** - * A specialized Container whose contents can be accessed like it was a - * tree-like structure. - * - * @author Vaadin Ltd. - * @since 3.0 - */ -@SuppressWarnings("serial") -public class HierarchicalContainer extends IndexedContainer - implements Container.Hierarchical { - - /** - * Set of IDs of those contained Items that can't have children. - */ - private final HashSet<Object> noChildrenAllowed = new HashSet<Object>(); - - /** - * Mapping from Item ID to parent Item ID. - */ - private final HashMap<Object, Object> parent = new HashMap<Object, Object>(); - - /** - * Mapping from Item ID to parent Item ID for items included in the filtered - * container. - */ - private HashMap<Object, Object> filteredParent = null; - - /** - * Mapping from Item ID to a list of child IDs. - */ - private final HashMap<Object, LinkedList<Object>> children = new HashMap<Object, LinkedList<Object>>(); - - /** - * Mapping from Item ID to a list of child IDs when filtered - */ - private HashMap<Object, LinkedList<Object>> filteredChildren = null; - - /** - * List that contains all root elements of the container. - */ - private final LinkedList<Object> roots = new LinkedList<Object>(); - - /** - * List that contains all filtered root elements of the container. - */ - private LinkedList<Object> filteredRoots = null; - - /** - * Determines how filtering of the container is done. - */ - private boolean includeParentsWhenFiltering = true; - - /** - * Counts how many nested contents change disable calls are in progress. - * - * Pending events are only fired when the counter reaches zero again. - */ - private int contentChangedEventsDisabledCount = 0; - - private boolean contentsChangedEventPending; - - /* - * Can the specified Item have any children? Don't add a JavaDoc comment - * here, we use the default documentation from implemented interface. - */ - @Override - public boolean areChildrenAllowed(Object itemId) { - if (noChildrenAllowed.contains(itemId)) { - return false; - } - return containsId(itemId); - } - - /* - * Gets the IDs of the children of the specified Item. Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public Collection<?> getChildren(Object itemId) { - LinkedList<Object> c; - - if (filteredChildren != null) { - c = filteredChildren.get(itemId); - } else { - c = children.get(itemId); - } - - if (c == null) { - return null; - } - return Collections.unmodifiableCollection(c); - } - - /* - * Gets the ID of the parent of the specified Item. Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public Object getParent(Object itemId) { - if (filteredParent != null) { - return filteredParent.get(itemId); - } - return parent.get(itemId); - } - - /* - * Is the Item corresponding to the given ID a leaf node? Don't add a - * JavaDoc comment here, we use the default documentation from implemented - * interface. - */ - @Override - public boolean hasChildren(Object itemId) { - if (filteredChildren != null) { - return filteredChildren.containsKey(itemId); - } else { - return children.containsKey(itemId); - } - } - - /* - * Is the Item corresponding to the given ID a root node? Don't add a - * JavaDoc comment here, we use the default documentation from implemented - * interface. - */ - @Override - public boolean isRoot(Object itemId) { - // If the container is filtered the itemId must be among filteredRoots - // to be a root. - if (filteredRoots != null) { - if (!filteredRoots.contains(itemId)) { - return false; - } - } else { - // Container is not filtered - if (parent.containsKey(itemId)) { - return false; - } - } - - return containsId(itemId); - } - - /* - * Gets the IDs of the root elements in the container. Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public Collection<?> rootItemIds() { - if (filteredRoots != null) { - return Collections.unmodifiableCollection(filteredRoots); - } else { - return Collections.unmodifiableCollection(roots); - } - } - - /** - * <p> - * Sets the given Item's capability to have children. If the Item identified - * with the itemId already has children and the areChildrenAllowed is false - * this method fails and <code>false</code> is returned; the children must - * be first explicitly removed with - * {@link #setParent(Object itemId, Object newParentId)} or - * {@link com.vaadin.data.Container#removeItem(Object itemId)}. - * </p> - * - * @param itemId - * the ID of the Item in the container whose child capability is - * to be set. - * @param childrenAllowed - * the boolean value specifying if the Item can have children or - * not. - * @return <code>true</code> if the operation succeeded, <code>false</code> - * if not - */ - @Override - public boolean setChildrenAllowed(Object itemId, boolean childrenAllowed) { - - // Checks that the item is in the container - if (!containsId(itemId)) { - return false; - } - - // Updates status - if (childrenAllowed) { - noChildrenAllowed.remove(itemId); - } else { - noChildrenAllowed.add(itemId); - } - - return true; - } - - /** - * <p> - * Sets the parent of an Item. The new parent item must exist and be able to - * have children. (<code>canHaveChildren(newParentId) == true</code>). It is - * also possible to detach a node from the hierarchy (and thus make it root) - * by setting the parent <code>null</code>. - * </p> - * - * @param itemId - * the ID of the item to be set as the child of the Item - * identified with newParentId. - * @param newParentId - * the ID of the Item that's to be the new parent of the Item - * identified with itemId. - * @return <code>true</code> if the operation succeeded, <code>false</code> - * if not - */ - @Override - public boolean setParent(Object itemId, Object newParentId) { - - // Checks that the item is in the container - if (!containsId(itemId)) { - return false; - } - - // Gets the old parent - final Object oldParentId = parent.get(itemId); - - // Checks if no change is necessary - if ((newParentId == null && oldParentId == null) - || ((newParentId != null) && newParentId.equals(oldParentId))) { - return true; - } - - // Making root? - if (newParentId == null) { - // The itemId should become a root so we need to - // - Remove it from the old parent's children list - // - Add it as a root - // - Remove it from the item -> parent list (parent is null for - // roots) - - // Removes from old parents children list - final LinkedList<Object> l = children.get(oldParentId); - if (l != null) { - l.remove(itemId); - if (l.isEmpty()) { - children.remove(oldParentId); - } - - } - - // Add to be a root - roots.add(itemId); - - // Updates parent - parent.remove(itemId); - - if (hasFilters()) { - // Refilter the container if setParent is called when filters - // are applied. Changing parent can change what is included in - // the filtered version (if includeParentsWhenFiltering==true). - doFilterContainer(hasFilters()); - } - - fireItemSetChange(); - - return true; - } - - // We get here when the item should not become a root and we need to - // - Verify the new parent exists and can have children - // - Check that the new parent is not a child of the selected itemId - // - Updated the item -> parent mapping to point to the new parent - // - Remove the item from the roots list if it was a root - // - Remove the item from the old parent's children list if it was not a - // root - - // Checks that the new parent exists in container and can have - // children - if (!containsId(newParentId) - || noChildrenAllowed.contains(newParentId)) { - return false; - } - - // Checks that setting parent doesn't result to a loop - Object o = newParentId; - while (o != null && !o.equals(itemId)) { - o = parent.get(o); - } - if (o != null) { - return false; - } - - // Updates parent - parent.put(itemId, newParentId); - LinkedList<Object> pcl = children.get(newParentId); - if (pcl == null) { - // Create an empty list for holding children if one were not - // previously created - pcl = new LinkedList<Object>(); - children.put(newParentId, pcl); - } - pcl.add(itemId); - - // Removes from old parent or root - if (oldParentId == null) { - roots.remove(itemId); - } else { - final LinkedList<Object> l = children.get(oldParentId); - if (l != null) { - l.remove(itemId); - if (l.isEmpty()) { - children.remove(oldParentId); - } - } - } - - if (hasFilters()) { - // Refilter the container if setParent is called when filters - // are applied. Changing parent can change what is included in - // the filtered version (if includeParentsWhenFiltering==true). - doFilterContainer(hasFilters()); - } - - fireItemSetChange(); - - return true; - } - - private boolean hasFilters() { - return (filteredRoots != null); - } - - /** - * Moves a node (an Item) in the container immediately after a sibling node. - * The two nodes must have the same parent in the container. - * - * @param itemId - * the identifier of the moved node (Item) - * @param siblingId - * the identifier of the reference node (Item), after which the - * other node will be located - */ - public void moveAfterSibling(Object itemId, Object siblingId) { - Object parent2 = getParent(itemId); - LinkedList<Object> childrenList; - if (parent2 == null) { - childrenList = roots; - } else { - childrenList = children.get(parent2); - } - if (siblingId == null) { - childrenList.remove(itemId); - childrenList.addFirst(itemId); - - } else { - int oldIndex = childrenList.indexOf(itemId); - int indexOfSibling = childrenList.indexOf(siblingId); - if (indexOfSibling != -1 && oldIndex != -1) { - int newIndex; - if (oldIndex > indexOfSibling) { - newIndex = indexOfSibling + 1; - } else { - newIndex = indexOfSibling; - } - childrenList.remove(oldIndex); - childrenList.add(newIndex, itemId); - } else { - throw new IllegalArgumentException( - "Given identifiers no not have the same parent."); - } - } - fireItemSetChange(); - - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.IndexedContainer#addItem() - */ - @Override - public Object addItem() { - disableContentsChangeEvents(); - try { - final Object itemId = super.addItem(); - if (itemId == null) { - return null; - } - - if (!roots.contains(itemId)) { - roots.add(itemId); - if (filteredRoots != null) { - if (passesFilters(itemId)) { - filteredRoots.add(itemId); - } - } - } - return itemId; - } finally { - enableAndFireContentsChangeEvents(); - } - } - - @Override - protected void fireItemSetChange( - com.vaadin.data.Container.ItemSetChangeEvent event) { - if (contentsChangeEventsOn()) { - super.fireItemSetChange(event); - } else { - contentsChangedEventPending = true; - } - } - - private boolean contentsChangeEventsOn() { - return contentChangedEventsDisabledCount == 0; - } - - private void disableContentsChangeEvents() { - contentChangedEventsDisabledCount++; - } - - private void enableAndFireContentsChangeEvents() { - if (contentChangedEventsDisabledCount <= 0) { - getLogger().log(Level.WARNING, - "Mismatched calls to disable and enable contents change events in HierarchicalContainer"); - contentChangedEventsDisabledCount = 0; - } else { - contentChangedEventsDisabledCount--; - } - if (contentChangedEventsDisabledCount == 0) { - if (contentsChangedEventPending) { - fireItemSetChange(); - } - contentsChangedEventPending = false; - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.IndexedContainer#addItem(java.lang.Object) - */ - @Override - public Item addItem(Object itemId) { - disableContentsChangeEvents(); - try { - final Item item = super.addItem(itemId); - if (item == null) { - return null; - } - - roots.add(itemId); - - if (filteredRoots != null) { - if (passesFilters(itemId)) { - filteredRoots.add(itemId); - } - } - return item; - } finally { - enableAndFireContentsChangeEvents(); - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.IndexedContainer#removeAllItems() - */ - @Override - public boolean removeAllItems() { - disableContentsChangeEvents(); - try { - final boolean success = super.removeAllItems(); - - if (success) { - roots.clear(); - parent.clear(); - children.clear(); - noChildrenAllowed.clear(); - if (filteredRoots != null) { - filteredRoots = null; - } - if (filteredChildren != null) { - filteredChildren = null; - } - if (filteredParent != null) { - filteredParent = null; - } - } - return success; - } finally { - enableAndFireContentsChangeEvents(); - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.IndexedContainer#removeItem(java.lang.Object ) - */ - @Override - public boolean removeItem(Object itemId) { - disableContentsChangeEvents(); - try { - final boolean success = super.removeItem(itemId); - - if (success) { - // Remove from roots if this was a root - if (roots.remove(itemId)) { - - // If filtering is enabled we might need to remove it from - // the filtered list also - if (filteredRoots != null) { - filteredRoots.remove(itemId); - } - } - - // Clear the children list. Old children will now become root - // nodes - LinkedList<Object> childNodeIds = children.remove(itemId); - if (childNodeIds != null) { - if (filteredChildren != null) { - filteredChildren.remove(itemId); - } - for (Object childId : childNodeIds) { - setParent(childId, null); - } - } - - // Parent of the item that we are removing will contain the item - // id in its children list - final Object parentItemId = parent.get(itemId); - if (parentItemId != null) { - final LinkedList<Object> c = children.get(parentItemId); - if (c != null) { - c.remove(itemId); - - if (c.isEmpty()) { - children.remove(parentItemId); - } - - // Found in the children list so might also be in the - // filteredChildren list - if (filteredChildren != null) { - LinkedList<Object> f = filteredChildren - .get(parentItemId); - if (f != null) { - f.remove(itemId); - if (f.isEmpty()) { - filteredChildren.remove(parentItemId); - } - } - } - } - } - parent.remove(itemId); - if (filteredParent != null) { - // Item id no longer has a parent as the item id is not in - // the container. - filteredParent.remove(itemId); - } - noChildrenAllowed.remove(itemId); - } - - return success; - } finally { - enableAndFireContentsChangeEvents(); - } - } - - /** - * Removes the Item identified by given itemId and all its children. - * - * @see #removeItem(Object) - * @param itemId - * the identifier of the Item to be removed - * @return true if the operation succeeded - */ - public boolean removeItemRecursively(Object itemId) { - disableContentsChangeEvents(); - try { - boolean removeItemRecursively = removeItemRecursively(this, itemId); - return removeItemRecursively; - } finally { - enableAndFireContentsChangeEvents(); - } - } - - /** - * Removes the Item identified by given itemId and all its children from the - * given Container. - * - * @param container - * the container where the item is to be removed - * @param itemId - * the identifier of the Item to be removed - * @return true if the operation succeeded - */ - public static boolean removeItemRecursively( - Container.Hierarchical container, Object itemId) { - boolean success = true; - Collection<?> children2 = container.getChildren(itemId); - if (children2 != null) { - Object[] array = children2.toArray(); - for (int i = 0; i < array.length; i++) { - boolean removeItemRecursively = removeItemRecursively(container, - array[i]); - if (!removeItemRecursively) { - success = false; - } - } - } - // remove the root of subtree if children where succesfully removed - if (success) { - success = container.removeItem(itemId); - } - return success; - - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.IndexedContainer#doSort() - */ - @Override - protected void doSort() { - super.doSort(); - - Collections.sort(roots, getItemSorter()); - for (LinkedList<Object> childList : children.values()) { - Collections.sort(childList, getItemSorter()); - } - } - - /** - * Used to control how filtering works. @see - * {@link #setIncludeParentsWhenFiltering(boolean)} for more information. - * - * @return true if all parents for items that match the filter are included - * when filtering, false if only the matching items are included - */ - public boolean isIncludeParentsWhenFiltering() { - return includeParentsWhenFiltering; - } - - /** - * Controls how the filtering of the container works. Set this to true to - * make filtering include parents for all matched items in addition to the - * items themselves. Setting this to false causes the filtering to only - * include the matching items and make items with excluded parents into root - * items. - * - * @param includeParentsWhenFiltering - * true to include all parents for items that match the filter, - * false to only include the matching items - */ - public void setIncludeParentsWhenFiltering( - boolean includeParentsWhenFiltering) { - this.includeParentsWhenFiltering = includeParentsWhenFiltering; - if (filteredRoots != null) { - // Currently filtered so needs to be re-filtered - doFilterContainer(true); - } - } - - /* - * Overridden to provide filtering for root & children items. - * - * (non-Javadoc) - * - * @see com.vaadin.data.util.IndexedContainer#updateContainerFiltering() - */ - @Override - protected boolean doFilterContainer(boolean hasFilters) { - if (!hasFilters) { - // All filters removed - filteredRoots = null; - filteredChildren = null; - filteredParent = null; - - return super.doFilterContainer(hasFilters); - } - - // Reset data structures - filteredRoots = new LinkedList<Object>(); - filteredChildren = new HashMap<Object, LinkedList<Object>>(); - filteredParent = new HashMap<Object, Object>(); - - if (includeParentsWhenFiltering) { - // Filter so that parents for items that match the filter are also - // included - HashSet<Object> includedItems = new HashSet<Object>(); - for (Object rootId : roots) { - if (filterIncludingParents(rootId, includedItems)) { - filteredRoots.add(rootId); - addFilteredChildrenRecursively(rootId, includedItems); - } - } - // includedItemIds now contains all the item ids that should be - // included. Filter IndexedContainer based on this - filterOverride = includedItems; - super.doFilterContainer(hasFilters); - filterOverride = null; - - return true; - } else { - // Filter by including all items that pass the filter and make items - // with no parent new root items - - // Filter IndexedContainer first so getItemIds return the items that - // match - super.doFilterContainer(hasFilters); - - LinkedHashSet<Object> filteredItemIds = new LinkedHashSet<Object>( - getItemIds()); - - for (Object itemId : filteredItemIds) { - Object itemParent = parent.get(itemId); - if (itemParent == null - || !filteredItemIds.contains(itemParent)) { - // Parent is not included or this was a root, in both cases - // this should be a filtered root - filteredRoots.add(itemId); - } else { - // Parent is included. Add this to the children list (create - // it first if necessary) - addFilteredChild(itemParent, itemId); - } - } - - return true; - } - } - - /** - * Adds the given childItemId as a filteredChildren for the parentItemId and - * sets it filteredParent. - * - * @param parentItemId - * @param childItemId - */ - private void addFilteredChild(Object parentItemId, Object childItemId) { - LinkedList<Object> parentToChildrenList = filteredChildren - .get(parentItemId); - if (parentToChildrenList == null) { - parentToChildrenList = new LinkedList<Object>(); - filteredChildren.put(parentItemId, parentToChildrenList); - } - filteredParent.put(childItemId, parentItemId); - parentToChildrenList.add(childItemId); - - } - - /** - * Recursively adds all items in the includedItems list to the - * filteredChildren map in the same order as they are in the children map. - * Starts from parentItemId and recurses down as long as child items that - * should be included are found. - * - * @param parentItemId - * The item id to start recurse from. Not added to a - * filteredChildren list - * @param includedItems - * Set containing the item ids for the items that should be - * included in the filteredChildren map - */ - private void addFilteredChildrenRecursively(Object parentItemId, - HashSet<Object> includedItems) { - LinkedList<Object> childList = children.get(parentItemId); - if (childList == null) { - return; - } - - for (Object childItemId : childList) { - if (includedItems.contains(childItemId)) { - addFilteredChild(parentItemId, childItemId); - addFilteredChildrenRecursively(childItemId, includedItems); - } - } - } - - /** - * Scans the itemId and all its children for which items should be included - * when filtering. All items which passes the filters are included. - * Additionally all items that have a child node that should be included are - * also themselves included. - * - * @param itemId - * @param includedItems - * @return true if the itemId should be included in the filtered container. - */ - private boolean filterIncludingParents(Object itemId, - HashSet<Object> includedItems) { - boolean toBeIncluded = passesFilters(itemId); - - LinkedList<Object> childList = children.get(itemId); - if (childList != null) { - for (Object childItemId : children.get(itemId)) { - toBeIncluded |= filterIncludingParents(childItemId, - includedItems); - } - } - - if (toBeIncluded) { - includedItems.add(itemId); - } - return toBeIncluded; - } - - private Set<Object> filterOverride = null; - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.util.IndexedContainer#passesFilters(java.lang.Object) - */ - @Override - protected boolean passesFilters(Object itemId) { - if (filterOverride != null) { - return filterOverride.contains(itemId); - } else { - return super.passesFilters(itemId); - } - } - - private static final Logger getLogger() { - return Logger.getLogger(HierarchicalContainer.class.getName()); - } -} diff --git a/server/src/main/java/com/vaadin/data/util/IndexedContainer.java b/server/src/main/java/com/vaadin/data/util/IndexedContainer.java deleted file mode 100644 index 4ff253394a..0000000000 --- a/server/src/main/java/com/vaadin/data/util/IndexedContainer.java +++ /dev/null @@ -1,1201 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.EventObject; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import com.vaadin.data.Container; -import com.vaadin.data.Item; -import com.vaadin.data.Property; -import com.vaadin.data.util.filter.SimpleStringFilter; -import com.vaadin.data.util.filter.UnsupportedFilterException; - -/** - * An implementation of the <code>{@link Container.Indexed}</code> interface - * with all important features. - * </p> - * - * Features: - * <ul> - * <li>{@link Container.Indexed} - * <li>{@link Container.Ordered} - * <li>{@link Container.Sortable} - * <li>{@link Container.Filterable} - * <li>{@link Cloneable} (deprecated, might be removed in the future) - * <li>Sends all needed events on content changes. - * </ul> - * - * @see com.vaadin.data.Container - * - * @author Vaadin Ltd. - * @since 3.0 - */ - -@SuppressWarnings("serial") -// item type is really IndexedContainerItem, but using Item not to show it in -// public API -public class IndexedContainer - extends AbstractInMemoryContainer<Object, Object, Item> - implements Container.PropertySetChangeNotifier, - Property.ValueChangeNotifier, Container.Sortable, Cloneable, - Container.Filterable, Container.SimpleFilterable { - - /* Internal structure */ - - /** - * Linked list of ordered Property IDs. - */ - private ArrayList<Object> propertyIds = new ArrayList<Object>(); - - /** - * Property ID to type mapping. - */ - private Hashtable<Object, Class<?>> types = new Hashtable<Object, Class<?>>(); - - /** - * Hash of Items, where each Item is implemented as a mapping from Property - * ID to Property value. - */ - private Hashtable<Object, Map<Object, Object>> items = new Hashtable<Object, Map<Object, Object>>(); - - /** - * Set of properties that are read-only. - */ - private HashSet<Property<?>> readOnlyProperties = new HashSet<Property<?>>(); - - /** - * List of all Property value change event listeners listening all the - * properties. - */ - private LinkedList<Property.ValueChangeListener> propertyValueChangeListeners = null; - - /** - * Data structure containing all listeners interested in changes to single - * Properties. The data structure is a hashtable mapping Property IDs to a - * hashtable that maps Item IDs to a linked list of listeners listening - * Property identified by given Property ID and Item ID. - */ - private Hashtable<Object, Map<Object, List<Property.ValueChangeListener>>> singlePropertyValueChangeListeners = null; - - private HashMap<Object, Object> defaultPropertyValues; - - private int nextGeneratedItemId = 1; - - /* Container constructors */ - - public IndexedContainer() { - super(); - } - - public IndexedContainer(Collection<?> itemIds) { - this(); - if (items != null) { - for (final Iterator<?> i = itemIds.iterator(); i.hasNext();) { - Object itemId = i.next(); - internalAddItemAtEnd(itemId, new IndexedContainerItem(itemId), - false); - } - filterAll(); - } - } - - /* Container methods */ - - @Override - protected Item getUnfilteredItem(Object itemId) { - if (itemId != null && items.containsKey(itemId)) { - return new IndexedContainerItem(itemId); - } - return null; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#getContainerPropertyIds() - */ - @Override - public Collection<?> getContainerPropertyIds() { - return Collections.unmodifiableCollection(propertyIds); - } - - /** - * Gets the type of a Property stored in the list. - * - * @param id - * the ID of the Property. - * @return Type of the requested Property - */ - @Override - public Class<?> getType(Object propertyId) { - return types.get(propertyId); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#getContainerProperty(java.lang.Object, - * java.lang.Object) - */ - @Override - public Property getContainerProperty(Object itemId, Object propertyId) { - // map lookup more efficient than propertyIds if there are many - // properties - if (!containsId(itemId) || propertyId == null - || !types.containsKey(propertyId)) { - return null; - } - - return new IndexedContainerProperty(itemId, propertyId); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#addContainerProperty(java.lang.Object, - * java.lang.Class, java.lang.Object) - */ - @Override - public boolean addContainerProperty(Object propertyId, Class<?> type, - Object defaultValue) { - - // Fails, if nulls are given - if (propertyId == null || type == null) { - return false; - } - - // Fails if the Property is already present - if (propertyIds.contains(propertyId)) { - return false; - } - - // Adds the Property to Property list and types - propertyIds.add(propertyId); - types.put(propertyId, type); - - // If default value is given, set it - if (defaultValue != null) { - // for existing rows - for (final Iterator<?> i = getAllItemIds().iterator(); i - .hasNext();) { - getItem(i.next()).getItemProperty(propertyId) - .setValue(defaultValue); - } - // store for next rows - if (defaultPropertyValues == null) { - defaultPropertyValues = new HashMap<Object, Object>(); - } - defaultPropertyValues.put(propertyId, defaultValue); - } - - // Sends a change event - fireContainerPropertySetChange(); - - return true; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#removeAllItems() - */ - @Override - public boolean removeAllItems() { - int origSize = size(); - Object firstItem = getFirstVisibleItem(); - - internalRemoveAllItems(); - - items.clear(); - - // fire event only if the visible view changed, regardless of whether - // filtered out items were removed or not - if (origSize != 0) { - // Sends a change event - fireItemsRemoved(0, firstItem, origSize); - } - - return true; - } - - /** - * {@inheritDoc} - * <p> - * The item ID is generated from a sequence of Integers. The id of the first - * added item is 1. - */ - @Override - public Object addItem() { - - // Creates a new id - final Object id = generateId(); - - // Adds the Item into container - addItem(id); - - return id; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#addItem(java.lang.Object) - */ - @Override - public Item addItem(Object itemId) { - Item item = internalAddItemAtEnd(itemId, - new IndexedContainerItem(itemId), false); - if (item == null) { - return null; - } else if (!isFiltered()) { - // always the last item - fireItemAdded(size() - 1, itemId, item); - } else if (passesFilters(itemId) && !containsId(itemId)) { - getFilteredItemIds().add(itemId); - // always the last item - fireItemAdded(size() - 1, itemId, item); - } - return item; - } - - /** - * Helper method to add default values for items if available - * - * @param t - * data table of added item - */ - private void addDefaultValues(Hashtable<Object, Object> t) { - if (defaultPropertyValues != null) { - for (Object key : defaultPropertyValues.keySet()) { - t.put(key, defaultPropertyValues.get(key)); - } - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#removeItem(java.lang.Object) - */ - @Override - public boolean removeItem(Object itemId) { - if (itemId == null || items.remove(itemId) == null) { - return false; - } - int origSize = size(); - int position = indexOfId(itemId); - if (internalRemoveItem(itemId)) { - // fire event only if the visible view changed, regardless of - // whether filtered out items were removed or not - if (size() != origSize) { - fireItemRemoved(position, itemId); - } - - return true; - } else { - return false; - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#removeContainerProperty(java.lang.Object ) - */ - @Override - public boolean removeContainerProperty(Object propertyId) { - - // Fails if the Property is not present - if (!propertyIds.contains(propertyId)) { - return false; - } - - // Removes the Property to Property list and types - propertyIds.remove(propertyId); - types.remove(propertyId); - if (defaultPropertyValues != null) { - defaultPropertyValues.remove(propertyId); - } - - // If remove the Property from all Items - for (final Iterator<Object> i = getAllItemIds().iterator(); i - .hasNext();) { - items.get(i.next()).remove(propertyId); - } - - // Sends a change event - fireContainerPropertySetChange(); - - return true; - } - - /* Container.Ordered methods */ - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object, - * java.lang.Object) - */ - @Override - public Item addItemAfter(Object previousItemId, Object newItemId) { - return internalAddItemAfter(previousItemId, newItemId, - new IndexedContainerItem(newItemId), true); - } - - /** - * {@inheritDoc} - * <p> - * The item ID is generated from a sequence of Integers. The id of the first - * added item is 1. - */ - @Override - public Object addItemAfter(Object previousItemId) { - - // Creates a new id - final Object id = generateId(); - - if (addItemAfter(previousItemId, id) != null) { - return id; - } else { - return null; - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Indexed#addItemAt(int, java.lang.Object) - */ - @Override - public Item addItemAt(int index, Object newItemId) { - return internalAddItemAt(index, newItemId, - new IndexedContainerItem(newItemId), true); - } - - /** - * {@inheritDoc} - * <p> - * The item ID is generated from a sequence of Integers. The id of the first - * added item is 1. - */ - @Override - public Object addItemAt(int index) { - - // Creates a new id - final Object id = generateId(); - - // Adds the Item into container - addItemAt(index, id); - - return id; - } - - /** - * Generates an unique identifier for use as an item id. Guarantees that the - * generated id is not currently used as an id. - * - * @return - */ - private Serializable generateId() { - Serializable id; - do { - id = Integer.valueOf(nextGeneratedItemId++); - } while (items.containsKey(id)); - - return id; - } - - @Override - protected void registerNewItem(int index, Object newItemId, Item item) { - Hashtable<Object, Object> t = new Hashtable<Object, Object>(); - items.put(newItemId, t); - addDefaultValues(t); - } - - /* Event notifiers */ - - /** - * An <code>event</code> object specifying the list whose Item set has - * changed. - * - * @author Vaadin Ltd. - * @since 3.0 - */ - public static class ItemSetChangeEvent extends BaseItemSetChangeEvent { - - private final int addedItemIndex; - - private ItemSetChangeEvent(IndexedContainer source, - int addedItemIndex) { - super(source); - this.addedItemIndex = addedItemIndex; - } - - /** - * Iff one item is added, gives its index. - * - * @return -1 if either multiple items are changed or some other change - * than add is done. - */ - public int getAddedItemIndex() { - return addedItemIndex; - } - - } - - /** - * An <code>event</code> object specifying the Property in a list whose - * value has changed. - * - * @author Vaadin Ltd. - * @since 3.0 - */ - private static class PropertyValueChangeEvent extends EventObject - implements Property.ValueChangeEvent, Serializable { - - private PropertyValueChangeEvent(Property source) { - super(source); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Property.ValueChangeEvent#getProperty() - */ - @Override - public Property getProperty() { - return (Property) getSource(); - } - - } - - @Override - public void addPropertySetChangeListener( - Container.PropertySetChangeListener listener) { - super.addPropertySetChangeListener(listener); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #addPropertySetChangeListener(com.vaadin.data.Container.PropertySetChangeListener)} - **/ - @Deprecated - @Override - public void addListener(Container.PropertySetChangeListener listener) { - addPropertySetChangeListener(listener); - } - - @Override - public void removePropertySetChangeListener( - Container.PropertySetChangeListener listener) { - super.removePropertySetChangeListener(listener); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #removePropertySetChangeListener(com.vaadin.data.Container.PropertySetChangeListener)} - **/ - @Deprecated - @Override - public void removeListener(Container.PropertySetChangeListener listener) { - removePropertySetChangeListener(listener); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Property.ValueChangeNotifier#addListener(com. - * vaadin.data.Property.ValueChangeListener) - */ - @Override - public void addValueChangeListener(Property.ValueChangeListener listener) { - if (propertyValueChangeListeners == null) { - propertyValueChangeListeners = new LinkedList<Property.ValueChangeListener>(); - } - propertyValueChangeListeners.add(listener); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #addValueChangeListener(com.vaadin.data.Property.ValueChangeListener)} - **/ - @Override - @Deprecated - public void addListener(Property.ValueChangeListener listener) { - addValueChangeListener(listener); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Property.ValueChangeNotifier#removeListener(com - * .vaadin.data.Property.ValueChangeListener) - */ - @Override - public void removeValueChangeListener( - Property.ValueChangeListener listener) { - if (propertyValueChangeListeners != null) { - propertyValueChangeListeners.remove(listener); - } - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #removeValueChangeListener(com.vaadin.data.Property.ValueChangeListener)} - **/ - @Override - @Deprecated - public void removeListener(Property.ValueChangeListener listener) { - removeValueChangeListener(listener); - } - - /** - * Sends a Property value change event to all interested listeners. - * - * @param source - * the IndexedContainerProperty object. - */ - private void firePropertyValueChange(IndexedContainerProperty source) { - - // Sends event to listeners listening all value changes - if (propertyValueChangeListeners != null) { - final Object[] l = propertyValueChangeListeners.toArray(); - final Property.ValueChangeEvent event = new IndexedContainer.PropertyValueChangeEvent( - source); - for (int i = 0; i < l.length; i++) { - ((Property.ValueChangeListener) l[i]).valueChange(event); - } - } - - // Sends event to single property value change listeners - if (singlePropertyValueChangeListeners != null) { - final Map<Object, List<Property.ValueChangeListener>> propertySetToListenerListMap = singlePropertyValueChangeListeners - .get(source.propertyId); - if (propertySetToListenerListMap != null) { - final List<Property.ValueChangeListener> listenerList = propertySetToListenerListMap - .get(source.itemId); - if (listenerList != null) { - final Property.ValueChangeEvent event = new IndexedContainer.PropertyValueChangeEvent( - source); - Object[] listeners = listenerList.toArray(); - for (int i = 0; i < listeners.length; i++) { - ((Property.ValueChangeListener) listeners[i]) - .valueChange(event); - } - } - } - } - - } - - @Override - public Collection<?> getListeners(Class<?> eventType) { - if (Property.ValueChangeEvent.class.isAssignableFrom(eventType)) { - if (propertyValueChangeListeners == null) { - return Collections.EMPTY_LIST; - } else { - return Collections - .unmodifiableCollection(propertyValueChangeListeners); - } - } - return super.getListeners(eventType); - } - - @Override - protected void fireItemAdded(int position, Object itemId, Item item) { - if (position >= 0) { - super.fireItemAdded(position, itemId, item); - } - } - - @Override - protected void fireItemSetChange() { - fireItemSetChange(new IndexedContainer.ItemSetChangeEvent(this, -1)); - } - - /** - * Adds new single Property change listener. - * - * @param propertyId - * the ID of the Property to add. - * @param itemId - * the ID of the Item . - * @param listener - * the listener to be added. - */ - private void addSinglePropertyChangeListener(Object propertyId, - Object itemId, Property.ValueChangeListener listener) { - if (listener != null) { - if (singlePropertyValueChangeListeners == null) { - singlePropertyValueChangeListeners = new Hashtable<Object, Map<Object, List<Property.ValueChangeListener>>>(); - } - Map<Object, List<Property.ValueChangeListener>> propertySetToListenerListMap = singlePropertyValueChangeListeners - .get(propertyId); - if (propertySetToListenerListMap == null) { - propertySetToListenerListMap = new Hashtable<Object, List<Property.ValueChangeListener>>(); - singlePropertyValueChangeListeners.put(propertyId, - propertySetToListenerListMap); - } - List<Property.ValueChangeListener> listenerList = propertySetToListenerListMap - .get(itemId); - if (listenerList == null) { - listenerList = new LinkedList<Property.ValueChangeListener>(); - propertySetToListenerListMap.put(itemId, listenerList); - } - listenerList.add(listener); - } - } - - /** - * Removes a previously registered single Property change listener. - * - * @param propertyId - * the ID of the Property to remove. - * @param itemId - * the ID of the Item. - * @param listener - * the listener to be removed. - */ - private void removeSinglePropertyChangeListener(Object propertyId, - Object itemId, Property.ValueChangeListener listener) { - if (listener != null && singlePropertyValueChangeListeners != null) { - final Map<Object, List<Property.ValueChangeListener>> propertySetToListenerListMap = singlePropertyValueChangeListeners - .get(propertyId); - if (propertySetToListenerListMap != null) { - final List<Property.ValueChangeListener> listenerList = propertySetToListenerListMap - .get(itemId); - if (listenerList != null) { - listenerList.remove(listener); - if (listenerList.isEmpty()) { - propertySetToListenerListMap.remove(itemId); - } - } - if (propertySetToListenerListMap.isEmpty()) { - singlePropertyValueChangeListeners.remove(propertyId); - } - } - if (singlePropertyValueChangeListeners.isEmpty()) { - singlePropertyValueChangeListeners = null; - } - } - } - - /* Internal Item and Property implementations */ - - /* - * A class implementing the com.vaadin.data.Item interface to be contained - * in the list. - * - * @author Vaadin Ltd. - * - * - * @since 3.0 - */ - class IndexedContainerItem implements Item { - - /** - * Item ID in the host container for this Item. - */ - private final Object itemId; - - /** - * Constructs a new ListItem instance and connects it to a host - * container. - * - * @param itemId - * the Item ID of the new Item. - */ - private IndexedContainerItem(Object itemId) { - this.itemId = itemId; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Item#getItemProperty(java.lang.Object) - */ - @Override - public Property getItemProperty(Object id) { - if (!propertyIds.contains(id)) { - return null; - } - - return new IndexedContainerProperty(itemId, id); - } - - @Override - public Collection<?> getItemPropertyIds() { - return Collections.unmodifiableCollection(propertyIds); - } - - /** - * Gets the <code>String</code> representation of the contents of the - * Item. The format of the string is a space separated catenation of the - * <code>String</code> representations of the values of the Properties - * contained by the Item. - * - * @return <code>String</code> representation of the Item contents - */ - @Override - public String toString() { - String retValue = ""; - - for (final Iterator<?> i = propertyIds.iterator(); i.hasNext();) { - final Object propertyId = i.next(); - retValue += getItemProperty(propertyId).getValue(); - if (i.hasNext()) { - retValue += " "; - } - } - - return retValue; - } - - /** - * Calculates a integer hash-code for the Item that's unique inside the - * list. Two Items inside the same list have always different - * hash-codes, though Items in different lists may have identical - * hash-codes. - * - * @return A locally unique hash-code as integer - */ - @Override - public int hashCode() { - return itemId.hashCode(); - } - - /** - * Tests if the given object is the same as the this object. Two Items - * got from a list container with the same ID are equal. - * - * @param obj - * an object to compare with this object - * @return <code>true</code> if the given object is the same as this - * object, <code>false</code> if not - */ - @Override - public boolean equals(Object obj) { - if (obj == null - || !obj.getClass().equals(IndexedContainerItem.class)) { - return false; - } - final IndexedContainerItem li = (IndexedContainerItem) obj; - return getHost() == li.getHost() && itemId.equals(li.itemId); - } - - private IndexedContainer getHost() { - return IndexedContainer.this; - } - - /** - * IndexedContainerItem does not support adding new properties. Add - * properties at container level. See - * {@link IndexedContainer#addContainerProperty(Object, Class, Object)} - * - * @see com.vaadin.data.Item#addProperty(Object, Property) - */ - @Override - public boolean addItemProperty(Object id, Property property) - throws UnsupportedOperationException { - throw new UnsupportedOperationException("Indexed container item " - + "does not support adding new properties"); - } - - /** - * Indexed container does not support removing properties. Remove - * properties at container level. See - * {@link IndexedContainer#removeContainerProperty(Object)} - * - * @see com.vaadin.data.Item#removeProperty(Object) - */ - @Override - public boolean removeItemProperty(Object id) - throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "Indexed container item does not support property removal"); - } - - } - - /** - * A class implementing the {@link Property} interface to be contained in - * the {@link IndexedContainerItem} contained in the - * {@link IndexedContainer}. - * - * @author Vaadin Ltd. - * - * @since 3.0 - */ - private class IndexedContainerProperty<T> - implements Property<T>, Property.ValueChangeNotifier { - - /** - * ID of the Item, where this property resides. - */ - private final Object itemId; - - /** - * Id of the Property. - */ - private final Object propertyId; - - /** - * Constructs a new {@link IndexedContainerProperty} object. - * - * @param itemId - * the ID of the Item to connect the new Property to. - * @param propertyId - * the Property ID of the new Property. - * @param host - * the list that contains the Item to contain the new - * Property. - */ - private IndexedContainerProperty(Object itemId, Object propertyId) { - if (itemId == null || propertyId == null) { - // Null ids are not accepted - throw new NullPointerException( - "Container item or property ids can not be null"); - } - this.propertyId = propertyId; - this.itemId = itemId; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Property#getType() - */ - @Override - public Class<T> getType() { - return (Class<T>) types.get(propertyId); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Property#getValue() - */ - @Override - public T getValue() { - return (T) items.get(itemId).get(propertyId); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Property#isReadOnly() - */ - @Override - public boolean isReadOnly() { - return readOnlyProperties.contains(this); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Property#setReadOnly(boolean) - */ - @Override - public void setReadOnly(boolean newStatus) { - if (newStatus) { - readOnlyProperties.add(this); - } else { - readOnlyProperties.remove(this); - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Property#setValue(java.lang.Object) - */ - @Override - public void setValue(Object newValue) - throws Property.ReadOnlyException { - // Gets the Property set - final Map<Object, Object> propertySet = items.get(itemId); - - // Support null values on all types - if (newValue == null) { - propertySet.remove(propertyId); - } else if (getType().isAssignableFrom(newValue.getClass())) { - propertySet.put(propertyId, newValue); - } else { - throw new IllegalArgumentException( - "Value is of invalid type, got " - + newValue.getClass().getName() + " but " - + getType().getName() + " was expected"); - } - - // update the container filtering if this property is being filtered - if (isPropertyFiltered(propertyId)) { - filterAll(); - } - - firePropertyValueChange(this); - } - - /** - * Calculates a integer hash-code for the Property that's unique inside - * the Item containing the Property. Two different Properties inside the - * same Item contained in the same list always have different - * hash-codes, though Properties in different Items may have identical - * hash-codes. - * - * @return A locally unique hash-code as integer - */ - @Override - public int hashCode() { - return itemId.hashCode() ^ propertyId.hashCode(); - } - - /** - * Tests if the given object is the same as the this object. Two - * Properties got from an Item with the same ID are equal. - * - * @param obj - * an object to compare with this object - * @return <code>true</code> if the given object is the same as this - * object, <code>false</code> if not - */ - @Override - public boolean equals(Object obj) { - if (obj == null - || !obj.getClass().equals(IndexedContainerProperty.class)) { - return false; - } - final IndexedContainerProperty lp = (IndexedContainerProperty) obj; - return lp.getHost() == getHost() && lp.propertyId.equals(propertyId) - && lp.itemId.equals(itemId); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Property.ValueChangeNotifier#addListener( - * com.vaadin.data.Property.ValueChangeListener) - */ - @Override - public void addValueChangeListener( - Property.ValueChangeListener listener) { - addSinglePropertyChangeListener(propertyId, itemId, listener); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #addValueChangeListener(com.vaadin.data.Property.ValueChangeListener)} - **/ - @Override - @Deprecated - public void addListener(Property.ValueChangeListener listener) { - addValueChangeListener(listener); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Property.ValueChangeNotifier#removeListener - * (com.vaadin.data.Property.ValueChangeListener) - */ - @Override - public void removeValueChangeListener( - Property.ValueChangeListener listener) { - removeSinglePropertyChangeListener(propertyId, itemId, listener); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #removeValueChangeListener(com.vaadin.data.Property.ValueChangeListener)} - **/ - @Override - @Deprecated - public void removeListener(Property.ValueChangeListener listener) { - removeValueChangeListener(listener); - } - - private IndexedContainer getHost() { - return IndexedContainer.this; - } - - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Sortable#sort(java.lang.Object[], - * boolean[]) - */ - @Override - public void sort(Object[] propertyId, boolean[] ascending) { - sortContainer(propertyId, ascending); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Sortable#getSortableContainerPropertyIds - * () - */ - @Override - public Collection<?> getSortableContainerPropertyIds() { - return getSortablePropertyIds(); - } - - @Override - public ItemSorter getItemSorter() { - return super.getItemSorter(); - } - - @Override - public void setItemSorter(ItemSorter itemSorter) { - super.setItemSorter(itemSorter); - } - - /** - * Supports cloning of the IndexedContainer cleanly. - * - * @throws CloneNotSupportedException - * if an object cannot be cloned. . - * - * @deprecated As of 6.6. Cloning support might be removed from - * IndexedContainer in the future - */ - @Deprecated - @Override - public Object clone() throws CloneNotSupportedException { - - // Creates the clone - final IndexedContainer nc = new IndexedContainer(); - - // Clone the shallow properties - nc.setAllItemIds(getAllItemIds() != null - ? (ListSet<Object>) ((ListSet<Object>) getAllItemIds()).clone() - : null); - nc.setItemSetChangeListeners(getItemSetChangeListeners() != null - ? new LinkedList<Container.ItemSetChangeListener>( - getItemSetChangeListeners()) - : null); - nc.propertyIds = propertyIds != null - ? (ArrayList<Object>) propertyIds.clone() : null; - nc.setPropertySetChangeListeners(getPropertySetChangeListeners() != null - ? new LinkedList<Container.PropertySetChangeListener>( - getPropertySetChangeListeners()) - : null); - nc.propertyValueChangeListeners = propertyValueChangeListeners != null - ? (LinkedList<Property.ValueChangeListener>) propertyValueChangeListeners - .clone() - : null; - nc.readOnlyProperties = readOnlyProperties != null - ? (HashSet<Property<?>>) readOnlyProperties.clone() : null; - nc.singlePropertyValueChangeListeners = singlePropertyValueChangeListeners != null - ? (Hashtable<Object, Map<Object, List<Property.ValueChangeListener>>>) singlePropertyValueChangeListeners - .clone() - : null; - - nc.types = types != null ? (Hashtable<Object, Class<?>>) types.clone() - : null; - - nc.setFilters( - (HashSet<Filter>) ((HashSet<Filter>) getFilters()).clone()); - - nc.setFilteredItemIds(getFilteredItemIds() == null ? null - : (ListSet<Object>) ((ListSet<Object>) getFilteredItemIds()) - .clone()); - - // Clone property-values - if (items == null) { - nc.items = null; - } else { - nc.items = new Hashtable<Object, Map<Object, Object>>(); - for (final Iterator<?> i = items.keySet().iterator(); i - .hasNext();) { - final Object id = i.next(); - final Hashtable<Object, Object> it = (Hashtable<Object, Object>) items - .get(id); - nc.items.put(id, (Map<Object, Object>) it.clone()); - } - } - - return nc; - } - - @Override - public void addContainerFilter(Object propertyId, String filterString, - boolean ignoreCase, boolean onlyMatchPrefix) { - try { - addFilter(new SimpleStringFilter(propertyId, filterString, - ignoreCase, onlyMatchPrefix)); - } catch (UnsupportedFilterException e) { - // the filter instance created here is always valid for in-memory - // containers - } - } - - @Override - public void removeAllContainerFilters() { - removeAllFilters(); - } - - @Override - public void removeContainerFilters(Object propertyId) { - removeFilters(propertyId); - } - - @Override - public void addContainerFilter(Filter filter) - throws UnsupportedFilterException { - addFilter(filter); - } - - @Override - public void removeContainerFilter(Filter filter) { - removeFilter(filter); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.AbstractInMemoryContainer#getContainerFilters() - */ - @Override - public boolean hasContainerFilters() { - return super.hasContainerFilters(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.AbstractInMemoryContainer#getContainerFilters() - */ - @Override - public Collection<Filter> getContainerFilters() { - return super.getContainerFilters(); - } - -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java deleted file mode 100644 index d3559b5652..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer; - -import java.io.Serializable; -import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.List; - -import com.vaadin.data.util.sqlcontainer.query.FreeformQuery; -import com.vaadin.data.util.sqlcontainer.query.QueryDelegate; -import com.vaadin.data.util.sqlcontainer.query.TableQuery; - -/** - * CacheFlushNotifier is a simple static notification mechanism to inform other - * SQLContainers that the contents of their caches may have become stale. - */ -class CacheFlushNotifier implements Serializable { - /* - * SQLContainer instance reference list and dead reference queue. Used for - * the cache flush notification feature. - */ - private static List<WeakReference<SQLContainer>> allInstances = new ArrayList<WeakReference<SQLContainer>>(); - private static ReferenceQueue<SQLContainer> deadInstances = new ReferenceQueue<SQLContainer>(); - - /** - * Adds the given SQLContainer to the cache flush notification receiver list - * - * @param c - * Container to add - */ - public static void addInstance(SQLContainer c) { - removeDeadReferences(); - if (c != null) { - allInstances.add(new WeakReference<SQLContainer>(c, deadInstances)); - } - } - - /** - * Removes dead references from instance list - */ - private static void removeDeadReferences() { - java.lang.ref.Reference<? extends SQLContainer> dead = deadInstances - .poll(); - while (dead != null) { - allInstances.remove(dead); - dead = deadInstances.poll(); - } - } - - /** - * Iterates through the instances and notifies containers which are - * connected to the same table or are using the same query string. - * - * @param c - * SQLContainer that issued the cache flush notification - */ - public static void notifyOfCacheFlush(SQLContainer c) { - removeDeadReferences(); - for (WeakReference<SQLContainer> wr : allInstances) { - if (wr.get() != null) { - SQLContainer wrc = wr.get(); - if (wrc == null) { - continue; - } - /* - * If the reference points to the container sending the - * notification, do nothing. - */ - if (wrc.equals(c)) { - continue; - } - /* Compare QueryDelegate types and tableName/queryString */ - QueryDelegate wrQd = wrc.getQueryDelegate(); - QueryDelegate qd = c.getQueryDelegate(); - if (wrQd instanceof TableQuery && qd instanceof TableQuery - && ((TableQuery) wrQd).getTableName() - .equals(((TableQuery) qd).getTableName())) { - wrc.refresh(); - } else if (wrQd instanceof FreeformQuery - && qd instanceof FreeformQuery - && ((FreeformQuery) wrQd).getQueryString().equals( - ((FreeformQuery) qd).getQueryString())) { - wrc.refresh(); - } - } - } - } -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/CacheMap.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/CacheMap.java deleted file mode 100644 index 77919f72b2..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/CacheMap.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer; - -import java.util.LinkedHashMap; -import java.util.Map; - -/** - * CacheMap extends LinkedHashMap, adding the possibility to adjust maximum - * number of items. In SQLContainer this is used for RowItem -cache. Cache size - * will be two times the page length parameter of the container. - */ -class CacheMap<K, V> extends LinkedHashMap<K, V> { - private static final long serialVersionUID = 679999766473555231L; - private int cacheLimit = SQLContainer.CACHE_RATIO - * SQLContainer.DEFAULT_PAGE_LENGTH; - - @Override - protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { - return size() > cacheLimit; - } - - void setCacheLimit(int limit) { - cacheLimit = limit > 0 ? limit : SQLContainer.DEFAULT_PAGE_LENGTH; - } - - int getCacheLimit() { - return cacheLimit; - } -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/ColumnProperty.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/ColumnProperty.java deleted file mode 100644 index e7d83e118d..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/ColumnProperty.java +++ /dev/null @@ -1,357 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer; - -import java.sql.Date; -import java.sql.Time; -import java.sql.Timestamp; -import java.util.logging.Logger; - -import com.vaadin.data.Property; -import com.vaadin.v7.data.util.converter.LegacyConverter.ConversionException; - -/** - * ColumnProperty represents the value of one column in a RowItem. In addition - * to the value, ColumnProperty also contains some basic column attributes such - * as nullability status, read-only status and data type. - * - * Note that depending on the QueryDelegate in use this does not necessarily map - * into an actual column in a database table. - */ -final public class ColumnProperty implements Property { - private static final long serialVersionUID = -3694463129581802457L; - - private RowItem owner; - - private String propertyId; - - private boolean readOnly; - private boolean allowReadOnlyChange = true; - private boolean nullable = true; - - private Object value; - private Object changedValue; - private Class<?> type; - - private boolean modified; - - private boolean versionColumn; - private boolean primaryKey = false; - - /** - * Prevent instantiation without required parameters. - */ - @SuppressWarnings("unused") - private ColumnProperty() { - } - - /** - * Deprecated constructor for ColumnProperty. If this is used the primary - * keys are not identified correctly in some cases for some databases (i.e. - * Oracle). See http://dev.vaadin.com/ticket/9145. - * - * @param propertyId - * @param readOnly - * @param allowReadOnlyChange - * @param nullable - * @param value - * @param type - * - * @deprecated As of 7.0. Use - * {@link #ColumnProperty(String, boolean, boolean, boolean, boolean, Object, Class) - * instead - */ - @Deprecated - public ColumnProperty(String propertyId, boolean readOnly, - boolean allowReadOnlyChange, boolean nullable, Object value, - Class<?> type) { - this(propertyId, readOnly, allowReadOnlyChange, nullable, false, value, - type); - } - - /** - * Creates a new ColumnProperty instance. - * - * @param propertyId - * The ID of this property. - * @param readOnly - * Whether this property is read-only. - * @param allowReadOnlyChange - * Whether the read-only status of this property can be changed. - * @param nullable - * Whether this property accepts null values. - * @param primaryKey - * Whether this property corresponds to a database primary key. - * @param value - * The value of this property. - * @param type - * The type of this property. - */ - public ColumnProperty(String propertyId, boolean readOnly, - boolean allowReadOnlyChange, boolean nullable, boolean primaryKey, - Object value, Class<?> type) { - - if (propertyId == null) { - throw new IllegalArgumentException("Properties must be named."); - } - if (type == null) { - throw new IllegalArgumentException("Property type must be set."); - } - this.propertyId = propertyId; - this.type = type; - this.value = value; - - this.allowReadOnlyChange = allowReadOnlyChange; - this.nullable = nullable; - this.readOnly = readOnly; - this.primaryKey = primaryKey; - } - - /** - * Returns the current value for this property. To get the previous value - * (if one exists) for a modified property use {@link #getOldValue()}. - * - * @return - */ - @Override - public Object getValue() { - if (isModified()) { - return changedValue; - } - return value; - } - - /** - * Returns the original non-modified value of this property if it has been - * modified. - * - * @return The original value if <code>isModified()</code> is true, - * <code>getValue()</code> otherwise. - */ - public Object getOldValue() { - return value; - } - - @Override - public void setValue(Object newValue) - throws ReadOnlyException, ConversionException { - if (newValue == null && !nullable) { - throw new NotNullableException( - "Null values are not allowed for this property."); - } - if (readOnly) { - throw new ReadOnlyException( - "Cannot set value for read-only property."); - } - - /* Check if this property is a date property. */ - boolean isDateProperty = Time.class.equals(getType()) - || Date.class.equals(getType()) - || Timestamp.class.equals(getType()); - - if (newValue != null) { - /* Handle SQL dates, times and Timestamps given as java.util.Date */ - if (isDateProperty) { - /* - * Try to get the millisecond value from the new value of this - * property. Possible type to convert from is java.util.Date. - */ - long millis = 0; - if (newValue instanceof java.util.Date) { - millis = ((java.util.Date) newValue).getTime(); - /* - * Create the new object based on the millisecond value, - * according to the type of this property. - */ - if (Time.class.equals(getType())) { - newValue = new Time(millis); - } else if (Date.class.equals(getType())) { - newValue = new Date(millis); - } else if (Timestamp.class.equals(getType())) { - newValue = new Timestamp(millis); - } - } - } - - if (!getType().isAssignableFrom(newValue.getClass())) { - throw new IllegalArgumentException( - "Illegal value type for ColumnProperty"); - } - - /* - * If the value to be set is the same that has already been set, do - * not set it again. - */ - if (isValueAlreadySet(newValue)) { - return; - } - } - - /* Set the new value and notify container of the change. */ - changedValue = newValue; - modified = true; - owner.getContainer().itemChangeNotification(owner); - } - - private boolean isValueAlreadySet(Object newValue) { - Object referenceValue = isModified() ? changedValue : value; - - return (isNullable() && newValue == null && referenceValue == null) - || newValue.equals(referenceValue); - } - - @Override - public Class<?> getType() { - return type; - } - - @Override - public boolean isReadOnly() { - return readOnly; - } - - /** - * Returns whether the read-only status of this property can be changed - * using {@link #setReadOnly(boolean)}. - * <p> - * Used to prevent setting to read/write mode a property that is not allowed - * to be written by the underlying database. Also used for values like - * VERSION and AUTO_INCREMENT fields that might be set to read-only by the - * container but the database still allows writes. - * - * @return true if the read-only status can be changed, false otherwise. - */ - public boolean isReadOnlyChangeAllowed() { - return allowReadOnlyChange; - } - - @Override - public void setReadOnly(boolean newStatus) { - if (allowReadOnlyChange) { - readOnly = newStatus; - } - } - - public boolean isPrimaryKey() { - return primaryKey; - } - - public String getPropertyId() { - return propertyId; - } - - private static Logger getLogger() { - return Logger.getLogger(ColumnProperty.class.getName()); - } - - public void setOwner(RowItem owner) { - if (owner == null) { - throw new IllegalArgumentException("Owner can not be set to null."); - } - if (this.owner != null) { - throw new IllegalStateException( - "ColumnProperties can only be bound once."); - } - this.owner = owner; - } - - public boolean isModified() { - return modified; - } - - public boolean isVersionColumn() { - return versionColumn; - } - - public void setVersionColumn(boolean versionColumn) { - this.versionColumn = versionColumn; - } - - public boolean isNullable() { - return nullable; - } - - /** - * Return whether the value of this property should be persisted to the - * database. - * - * @return true if the value should be written to the database, false - * otherwise. - */ - public boolean isPersistent() { - if (isVersionColumn()) { - return false; - } else if (isReadOnlyChangeAllowed() && !isReadOnly()) { - return true; - } else { - return false; - } - } - - /** - * Returns whether or not this property is used as a row identifier. - * - * @return true if the property is a row identifier, false otherwise. - */ - public boolean isRowIdentifier() { - return isPrimaryKey() || isVersionColumn(); - } - - /** - * An exception that signals that a <code>null</code> value was passed to - * the <code>setValue</code> method, but the value of this property can not - * be set to <code>null</code>. - */ - @SuppressWarnings("serial") - public class NotNullableException extends RuntimeException { - - /** - * Constructs a new <code>NotNullableException</code> without a detail - * message. - */ - public NotNullableException() { - } - - /** - * Constructs a new <code>NotNullableException</code> with the specified - * detail message. - * - * @param msg - * the detail message - */ - public NotNullableException(String msg) { - super(msg); - } - - /** - * Constructs a new <code>NotNullableException</code> from another - * exception. - * - * @param cause - * The cause of the failure - */ - public NotNullableException(Throwable cause) { - super(cause); - } - } - - public void commit() { - if (isModified()) { - modified = false; - value = changedValue; - } - } -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/OptimisticLockException.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/OptimisticLockException.java deleted file mode 100644 index 1a29d531bc..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/OptimisticLockException.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer; - -import com.vaadin.data.util.sqlcontainer.query.TableQuery; - -/** - * An OptimisticLockException is thrown when trying to update or delete a row - * that has been changed since last read from the database. - * - * OptimisticLockException is a runtime exception because optimistic locking is - * turned off by default, and as such will never be thrown in a default - * configuration. In order to turn on optimistic locking, you need to specify - * the version column in your TableQuery instance. - * - * @see TableQuery#setVersionColumn(String) - * - * @author Jonatan Kronqvist / Vaadin Ltd - */ -public class OptimisticLockException extends RuntimeException { - - private final RowId rowId; - - public OptimisticLockException(RowId rowId) { - super(); - this.rowId = rowId; - } - - public OptimisticLockException(String msg, RowId rowId) { - super(msg); - this.rowId = rowId; - } - - public RowId getRowId() { - return rowId; - } -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/ReadOnlyRowId.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/ReadOnlyRowId.java deleted file mode 100644 index 367135782f..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/ReadOnlyRowId.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer; - -public class ReadOnlyRowId extends RowId { - private static final long serialVersionUID = -2626764781642012467L; - private final Integer rowNum; - - public ReadOnlyRowId(int rowNum) { - super(); - this.rowNum = rowNum; - } - - @Override - public int hashCode() { - return getRowNum(); - } - - @Override - public boolean equals(Object obj) { - if (obj == null || !(ReadOnlyRowId.class.equals(obj.getClass()))) { - return false; - } - return getRowNum() == (((ReadOnlyRowId) obj).getRowNum()); - } - - public int getRowNum() { - return rowNum; - } - - @Override - public String toString() { - return String.valueOf(getRowNum()); - } -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/Reference.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/Reference.java deleted file mode 100644 index ce6680089d..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/Reference.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer; - -import java.io.Serializable; - -/** - * The reference class represents a simple [usually foreign key] reference to - * another SQLContainer. Actual foreign key reference in the database is not - * required, but it is recommended to make sure that certain constraints are - * followed. - */ -@SuppressWarnings("serial") -class Reference implements Serializable { - - /** - * The SQLContainer that this reference points to. - */ - private SQLContainer referencedContainer; - - /** - * The column ID/name in the referencing SQLContainer that contains the key - * used for the reference. - */ - private String referencingColumn; - - /** - * The column ID/name in the referenced SQLContainer that contains the key - * used for the reference. - */ - private String referencedColumn; - - /** - * Constructs a new reference to be used within the SQLContainer to - * reference another SQLContainer. - */ - Reference(SQLContainer referencedContainer, String referencingColumn, - String referencedColumn) { - this.referencedContainer = referencedContainer; - this.referencingColumn = referencingColumn; - this.referencedColumn = referencedColumn; - } - - SQLContainer getReferencedContainer() { - return referencedContainer; - } - - String getReferencingColumn() { - return referencingColumn; - } - - String getReferencedColumn() { - return referencedColumn; - } -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/RowId.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/RowId.java deleted file mode 100644 index 5f78df79e1..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/RowId.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer; - -import java.io.Serializable; -import java.util.Arrays; - -/** - * RowId represents identifiers of a single database result set row. - * - * The data structure of a RowId is an Object array which contains the values of - * the primary key columns of the identified row. This allows easy equals() - * -comparison of RowItems. - */ -public class RowId implements Serializable { - private static final long serialVersionUID = -3161778404698901258L; - protected Object[] id; - - /** - * Prevent instantiation without required parameters. - */ - protected RowId() { - } - - public RowId(Object... id) { - if (id == null) { - throw new IllegalArgumentException( - "id parameter must not be null!"); - } - this.id = id; - } - - public Object[] getId() { - return id; - } - - @Override - public int hashCode() { - return Arrays.hashCode(getId()); - } - - @Override - public boolean equals(Object obj) { - if (obj == null || !(RowId.class.equals(obj.getClass()))) { - return false; - } - return Arrays.equals(getId(), ((RowId) obj).getId()); - } - - @Override - public String toString() { - if (getId() == null) { - return ""; - } - StringBuilder builder = new StringBuilder(); - for (Object id : getId()) { - builder.append(id); - builder.append('/'); - } - if (builder.length() > 0) { - return builder.substring(0, builder.length() - 1); - } - return builder.toString(); - } -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/RowItem.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/RowItem.java deleted file mode 100644 index ffc8bfc6f7..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/RowItem.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; - -import com.vaadin.data.Item; -import com.vaadin.data.Property; - -/** - * RowItem represents one row of a result set obtained from a QueryDelegate. - * - * Note that depending on the QueryDelegate in use this does not necessarily map - * into an actual row in a database table. - */ -public final class RowItem implements Item { - private static final long serialVersionUID = -6228966439127951408L; - private SQLContainer container; - private RowId id; - private Collection<ColumnProperty> properties; - - /** - * Prevent instantiation without required parameters. - */ - @SuppressWarnings("unused") - private RowItem() { - } - - public RowItem(SQLContainer container, RowId id, - Collection<ColumnProperty> properties) { - if (container == null) { - throw new IllegalArgumentException("Container cannot be null."); - } - if (id == null) { - throw new IllegalArgumentException("Row ID cannot be null."); - } - this.container = container; - this.properties = properties; - /* Set this RowItem as owner to the properties */ - if (properties != null) { - for (ColumnProperty p : properties) { - p.setOwner(this); - } - } - this.id = id; - } - - @Override - public Property getItemProperty(Object id) { - if (id instanceof String && id != null) { - for (ColumnProperty cp : properties) { - if (id.equals(cp.getPropertyId())) { - return cp; - } - } - } - return null; - } - - @Override - public Collection<?> getItemPropertyIds() { - Collection<String> ids = new ArrayList<String>(properties.size()); - for (ColumnProperty cp : properties) { - ids.add(cp.getPropertyId()); - } - return Collections.unmodifiableCollection(ids); - } - - /** - * Adding properties is not supported. Properties are generated by - * SQLContainer. - */ - @Override - public boolean addItemProperty(Object id, Property property) - throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - /** - * Removing properties is not supported. Properties are generated by - * SQLContainer. - */ - @Override - public boolean removeItemProperty(Object id) - throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - public RowId getId() { - return id; - } - - public SQLContainer getContainer() { - return container; - } - - public boolean isModified() { - if (properties != null) { - for (ColumnProperty p : properties) { - if (p.isModified()) { - return true; - } - } - } - return false; - } - - @Override - public String toString() { - StringBuffer s = new StringBuffer(); - s.append("ID:"); - s.append(getId().toString()); - for (Object propId : getItemPropertyIds()) { - s.append("|"); - s.append(propId.toString()); - s.append(":"); - Object value = getItemProperty(propId).getValue(); - s.append((null != value) ? value.toString() : null); - } - return s.toString(); - } - - public void commit() { - if (properties != null) { - for (ColumnProperty p : properties) { - p.commit(); - } - } - } -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/SQLContainer.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/SQLContainer.java deleted file mode 100644 index dde57d3610..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/SQLContainer.java +++ /dev/null @@ -1,1875 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer; - -import java.io.IOException; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.ConcurrentModificationException; -import java.util.Date; -import java.util.EventObject; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.vaadin.data.Container; -import com.vaadin.data.ContainerHelpers; -import com.vaadin.data.Item; -import com.vaadin.data.Property; -import com.vaadin.data.util.filter.Compare.Equal; -import com.vaadin.data.util.filter.Like; -import com.vaadin.data.util.filter.UnsupportedFilterException; -import com.vaadin.data.util.sqlcontainer.query.OrderBy; -import com.vaadin.data.util.sqlcontainer.query.QueryDelegate; -import com.vaadin.data.util.sqlcontainer.query.QueryDelegate.RowIdChangeListener; -import com.vaadin.data.util.sqlcontainer.query.TableQuery; -import com.vaadin.data.util.sqlcontainer.query.generator.MSSQLGenerator; -import com.vaadin.data.util.sqlcontainer.query.generator.OracleGenerator; - -public class SQLContainer implements Container, Container.Filterable, - Container.Indexed, Container.Sortable, Container.ItemSetChangeNotifier { - - /** Query delegate */ - private QueryDelegate queryDelegate; - /** Auto commit mode, default = false */ - private boolean autoCommit = false; - - /** Page length = number of items contained in one page */ - private int pageLength = DEFAULT_PAGE_LENGTH; - public static final int DEFAULT_PAGE_LENGTH = 100; - - /** Number of items to cache = CACHE_RATIO x pageLength */ - public static final int CACHE_RATIO = 2; - - /** Amount of cache to overlap with previous page */ - private int cacheOverlap = pageLength; - - /** Item and index caches */ - private final Map<Integer, RowId> itemIndexes = new HashMap<Integer, RowId>(); - private final CacheMap<RowId, RowItem> cachedItems = new CacheMap<RowId, RowItem>(); - - /** Container properties = column names, data types and statuses */ - private final List<String> propertyIds = new ArrayList<String>(); - private final Map<String, Class<?>> propertyTypes = new HashMap<String, Class<?>>(); - private final Map<String, Boolean> propertyReadOnly = new HashMap<String, Boolean>(); - private final Map<String, Boolean> propertyPersistable = new HashMap<String, Boolean>(); - private final Map<String, Boolean> propertyNullable = new HashMap<String, Boolean>(); - private final Map<String, Boolean> propertyPrimaryKey = new HashMap<String, Boolean>(); - - /** Filters (WHERE) and sorters (ORDER BY) */ - private final List<Filter> filters = new ArrayList<Filter>(); - private final List<OrderBy> sorters = new ArrayList<OrderBy>(); - - /** - * Total number of items available in the data source using the current - * query, filters and sorters. - */ - private int size; - - /** - * Size updating logic. Do not update size from data source if it has been - * updated in the last sizeValidMilliSeconds milliseconds. - */ - private final int sizeValidMilliSeconds = 10000; - private boolean sizeDirty = true; - private Date sizeUpdated = new Date(); - - /** Starting row number of the currently fetched page */ - private int currentOffset; - - /** ItemSetChangeListeners */ - private LinkedList<Container.ItemSetChangeListener> itemSetChangeListeners; - - /** - * Temporary storage for modified items and items to be removed and added - */ - private final Map<RowId, RowItem> removedItems = new HashMap<RowId, RowItem>(); - private final List<RowItem> addedItems = new ArrayList<RowItem>(); - private final List<RowItem> modifiedItems = new ArrayList<RowItem>(); - - /** List of references to other SQLContainers */ - private final Map<SQLContainer, Reference> references = new HashMap<SQLContainer, Reference>(); - - /** Cache flush notification system enabled. Disabled by default. */ - private boolean notificationsEnabled; - - /** - * Prevent instantiation without a QueryDelegate. - */ - @SuppressWarnings("unused") - private SQLContainer() { - } - - /** - * Creates and initializes SQLContainer using the given QueryDelegate - * - * @param delegate - * QueryDelegate implementation - * @throws SQLException - */ - public SQLContainer(QueryDelegate delegate) throws SQLException { - if (delegate == null) { - throw new IllegalArgumentException( - "QueryDelegate must not be null."); - } - queryDelegate = delegate; - getPropertyIds(); - cachedItems.setCacheLimit(CACHE_RATIO * getPageLength() + cacheOverlap); - } - - /**************************************/ - /** Methods from interface Container **/ - /**************************************/ - - /** - * Note! If auto commit mode is enabled, this method will still return the - * temporary row ID assigned for the item. Implement - * QueryDelegate.RowIdChangeListener to receive the actual Row ID value - * after the addition has been committed. - * - * {@inheritDoc} - */ - - @Override - public Object addItem() throws UnsupportedOperationException { - Object emptyKey[] = new Object[queryDelegate.getPrimaryKeyColumns() - .size()]; - RowId itemId = new TemporaryRowId(emptyKey); - // Create new empty column properties for the row item. - List<ColumnProperty> itemProperties = new ArrayList<ColumnProperty>(); - for (String propertyId : propertyIds) { - /* Default settings for new item properties. */ - ColumnProperty cp = new ColumnProperty(propertyId, - propertyReadOnly.get(propertyId), - propertyPersistable.get(propertyId), - propertyNullable.get(propertyId), - propertyPrimaryKey.get(propertyId), null, - getType(propertyId)); - - itemProperties.add(cp); - } - RowItem newRowItem = new RowItem(this, itemId, itemProperties); - - if (autoCommit) { - /* Add and commit instantly */ - try { - if (queryDelegate instanceof TableQuery) { - itemId = ((TableQuery) queryDelegate) - .storeRowImmediately(newRowItem); - } else { - queryDelegate.beginTransaction(); - queryDelegate.storeRow(newRowItem); - queryDelegate.commit(); - } - refresh(); - if (notificationsEnabled) { - CacheFlushNotifier.notifyOfCacheFlush(this); - } - getLogger().log(Level.FINER, "Row added to DB..."); - return itemId; - } catch (SQLException e) { - getLogger().log(Level.WARNING, - "Failed to add row to DB. Rolling back.", e); - try { - queryDelegate.rollback(); - } catch (SQLException ee) { - getLogger().log(Level.SEVERE, - "Failed to roll back row addition", e); - } - return null; - } - } else { - addedItems.add(newRowItem); - fireContentsChange(); - return itemId; - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#containsId(java.lang.Object) - */ - - @Override - public boolean containsId(Object itemId) { - if (itemId == null) { - return false; - } - - if (cachedItems.containsKey(itemId)) { - return true; - } else { - for (RowItem item : addedItems) { - if (item.getId().equals(itemId)) { - return itemPassesFilters(item); - } - } - } - if (removedItems.containsKey(itemId)) { - return false; - } - - if (itemId instanceof ReadOnlyRowId) { - int rowNum = ((ReadOnlyRowId) itemId).getRowNum(); - return rowNum >= 0 && rowNum < size; - } - - if (itemId instanceof RowId && !(itemId instanceof TemporaryRowId)) { - try { - return queryDelegate - .containsRowWithKey(((RowId) itemId).getId()); - } catch (Exception e) { - /* Query failed, just return false. */ - getLogger().log(Level.WARNING, "containsId query failed", e); - } - } - return false; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#getContainerProperty(java.lang.Object, - * java.lang.Object) - */ - - @Override - public Property getContainerProperty(Object itemId, Object propertyId) { - Item item = getItem(itemId); - if (item == null) { - return null; - } - return item.getItemProperty(propertyId); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#getContainerPropertyIds() - */ - - @Override - public Collection<?> getContainerPropertyIds() { - return Collections.unmodifiableCollection(propertyIds); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#getItem(java.lang.Object) - */ - - @Override - public Item getItem(Object itemId) { - if (!cachedItems.containsKey(itemId)) { - int index = indexOfId(itemId); - if (index >= size) { - // The index is in the added items - int offset = index - size; - RowItem item = addedItems.get(offset); - if (itemPassesFilters(item)) { - return item; - } else { - return null; - } - } else { - // load the item into cache - updateOffsetAndCache(index); - } - } - return cachedItems.get(itemId); - } - - /** - * Bypasses in-memory filtering to return items that are cached in memory. - * <em>NOTE</em>: This does not bypass database-level filtering. - * - * @param itemId - * the id of the item to retrieve. - * @return the item represented by itemId. - */ - public Item getItemUnfiltered(Object itemId) { - if (!cachedItems.containsKey(itemId)) { - for (RowItem item : addedItems) { - if (item.getId().equals(itemId)) { - return item; - } - } - } - return cachedItems.get(itemId); - } - - /** - * NOTE! Do not use this method if in any way avoidable. This method doesn't - * (and cannot) use lazy loading, which means that all rows in the database - * will be loaded into memory. - * - * {@inheritDoc} - */ - - @Override - public Collection<?> getItemIds() { - updateCount(); - ArrayList<RowId> ids = new ArrayList<RowId>(); - ResultSet rs = null; - try { - // Load ALL rows :( - queryDelegate.beginTransaction(); - rs = queryDelegate.getResults(0, 0); - List<String> pKeys = queryDelegate.getPrimaryKeyColumns(); - while (rs.next()) { - RowId id = null; - if (pKeys.isEmpty()) { - /* Create a read only itemId */ - id = new ReadOnlyRowId(rs.getRow()); - } else { - /* Generate itemId for the row based on primary key(s) */ - Object[] itemId = new Object[pKeys.size()]; - for (int i = 0; i < pKeys.size(); i++) { - itemId[i] = rs.getObject(pKeys.get(i)); - } - id = new RowId(itemId); - } - if (id != null && !removedItems.containsKey(id)) { - ids.add(id); - } - } - rs.getStatement().close(); - rs.close(); - queryDelegate.commit(); - } catch (SQLException e) { - getLogger().log(Level.WARNING, "getItemIds() failed, rolling back.", - e); - try { - queryDelegate.rollback(); - } catch (SQLException e1) { - getLogger().log(Level.SEVERE, "Failed to roll back state", e1); - } - try { - rs.getStatement().close(); - rs.close(); - } catch (SQLException e1) { - getLogger().log(Level.WARNING, "Closing session failed", e1); - } - throw new RuntimeException("Failed to fetch item indexes.", e); - } - for (RowItem item : getFilteredAddedItems()) { - ids.add(item.getId()); - } - return Collections.unmodifiableCollection(ids); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#getType(java.lang.Object) - */ - - @Override - public Class<?> getType(Object propertyId) { - if (!propertyIds.contains(propertyId)) { - return null; - } - return propertyTypes.get(propertyId); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#size() - */ - - @Override - public int size() { - updateCount(); - return size + sizeOfAddedItems() - removedItems.size(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#removeItem(java.lang.Object) - */ - - @Override - public boolean removeItem(Object itemId) - throws UnsupportedOperationException { - if (!containsId(itemId)) { - return false; - } - for (RowItem item : addedItems) { - if (item.getId().equals(itemId)) { - addedItems.remove(item); - fireContentsChange(); - return true; - } - } - - if (autoCommit) { - /* Remove and commit instantly. */ - Item i = getItem(itemId); - if (i == null) { - return false; - } - try { - queryDelegate.beginTransaction(); - boolean success = queryDelegate.removeRow((RowItem) i); - queryDelegate.commit(); - refresh(); - if (notificationsEnabled) { - CacheFlushNotifier.notifyOfCacheFlush(this); - } - if (success) { - getLogger().log(Level.FINER, "Row removed from DB..."); - } - return success; - } catch (SQLException e) { - getLogger().log(Level.WARNING, - "Failed to remove row, rolling back", e); - try { - queryDelegate.rollback(); - } catch (SQLException ee) { - /* Nothing can be done here */ - getLogger().log(Level.SEVERE, - "Failed to rollback row removal", ee); - } - return false; - } catch (OptimisticLockException e) { - getLogger().log(Level.WARNING, - "Failed to remove row, rolling back", e); - try { - queryDelegate.rollback(); - } catch (SQLException ee) { - /* Nothing can be done here */ - getLogger().log(Level.SEVERE, - "Failed to rollback row removal", ee); - } - throw e; - } - } else { - removedItems.put((RowId) itemId, (RowItem) getItem(itemId)); - cachedItems.remove(itemId); - refresh(); - return true; - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#removeAllItems() - */ - - @Override - public boolean removeAllItems() throws UnsupportedOperationException { - if (autoCommit) { - /* Remove and commit instantly. */ - try { - queryDelegate.beginTransaction(); - boolean success = true; - for (Object id : getItemIds()) { - if (!queryDelegate.removeRow((RowItem) getItem(id))) { - success = false; - } - } - if (success) { - queryDelegate.commit(); - getLogger().log(Level.FINER, "All rows removed from DB..."); - refresh(); - if (notificationsEnabled) { - CacheFlushNotifier.notifyOfCacheFlush(this); - } - } else { - queryDelegate.rollback(); - } - return success; - } catch (SQLException e) { - getLogger().log(Level.WARNING, - "removeAllItems() failed, rolling back", e); - try { - queryDelegate.rollback(); - } catch (SQLException ee) { - /* Nothing can be done here */ - getLogger().log(Level.SEVERE, "Failed to roll back", ee); - } - return false; - } catch (OptimisticLockException e) { - getLogger().log(Level.WARNING, - "removeAllItems() failed, rolling back", e); - try { - queryDelegate.rollback(); - } catch (SQLException ee) { - /* Nothing can be done here */ - getLogger().log(Level.SEVERE, "Failed to roll back", ee); - } - throw e; - } - } else { - for (Object id : getItemIds()) { - removedItems.put((RowId) id, (RowItem) getItem(id)); - cachedItems.remove(id); - } - refresh(); - return true; - } - } - - /*************************************************/ - /** Methods from interface Container.Filterable **/ - /*************************************************/ - - /** - * {@inheritDoc} - */ - - @Override - public void addContainerFilter(Filter filter) - throws UnsupportedFilterException { - // filter.setCaseSensitive(!ignoreCase); - - filters.add(filter); - refresh(); - } - - /** - * {@inheritDoc} - */ - - @Override - public void removeContainerFilter(Filter filter) { - filters.remove(filter); - refresh(); - } - - /** - * {@inheritDoc} - */ - public void addContainerFilter(Object propertyId, String filterString, - boolean ignoreCase, boolean onlyMatchPrefix) { - if (propertyId == null || !propertyIds.contains(propertyId)) { - return; - } - - /* Generate Filter -object */ - String likeStr = onlyMatchPrefix ? filterString + "%" - : "%" + filterString + "%"; - Like like = new Like(propertyId.toString(), likeStr); - like.setCaseSensitive(!ignoreCase); - filters.add(like); - refresh(); - } - - /** - * {@inheritDoc} - */ - public void removeContainerFilters(Object propertyId) { - ArrayList<Filter> toRemove = new ArrayList<Filter>(); - for (Filter f : filters) { - if (f.appliesToProperty(propertyId)) { - toRemove.add(f); - } - } - filters.removeAll(toRemove); - refresh(); - } - - /** - * {@inheritDoc} - */ - @Override - public void removeAllContainerFilters() { - filters.clear(); - refresh(); - } - - /** - * Returns true if any filters have been applied to the container. - * - * @return true if the container has filters applied, false otherwise - * @since 7.1 - */ - public boolean hasContainerFilters() { - return !getContainerFilters().isEmpty(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Filterable#getContainerFilters() - */ - @Override - public Collection<Filter> getContainerFilters() { - return Collections.unmodifiableCollection(filters); - } - - /**********************************************/ - /** Methods from interface Container.Indexed **/ - /**********************************************/ - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Indexed#indexOfId(java.lang.Object) - */ - - @Override - public int indexOfId(Object itemId) { - // First check if the id is in the added items - for (int ix = 0; ix < addedItems.size(); ix++) { - RowItem item = addedItems.get(ix); - if (item.getId().equals(itemId)) { - if (itemPassesFilters(item)) { - updateCount(); - return size + ix; - } else { - return -1; - } - } - } - - if (!containsId(itemId)) { - return -1; - } - if (cachedItems.isEmpty()) { - getPage(); - } - // this protects against infinite looping - int counter = 0; - int oldIndex; - while (counter < size) { - if (itemIndexes.containsValue(itemId)) { - for (Integer idx : itemIndexes.keySet()) { - if (itemIndexes.get(idx).equals(itemId)) { - return idx; - } - } - } - oldIndex = currentOffset; - // load in the next page. - int nextIndex = currentOffset + pageLength * CACHE_RATIO - + cacheOverlap; - if (nextIndex >= size) { - // Container wrapped around, start from index 0. - nextIndex = 0; - } - updateOffsetAndCache(nextIndex); - - // Update counter - if (currentOffset > oldIndex) { - counter += currentOffset - oldIndex; - } else { - counter += size - oldIndex; - } - } - // safeguard in case item not found - return -1; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Indexed#getIdByIndex(int) - */ - - @Override - public Object getIdByIndex(int index) { - if (index < 0) { - throw new IndexOutOfBoundsException( - "Index is negative! index=" + index); - } - // make sure the size field is valid - updateCount(); - if (index < size) { - if (itemIndexes.keySet().contains(index)) { - return itemIndexes.get(index); - } - updateOffsetAndCache(index); - return itemIndexes.get(index); - } else { - // The index is in the added items - int offset = index - size; - // TODO this is very inefficient if looping - should improve - // getItemIds(int, int) - return getFilteredAddedItems().get(offset).getId(); - } - } - - @Override - public List<Object> getItemIds(int startIndex, int numberOfIds) { - // TODO create a better implementation - return (List<Object>) ContainerHelpers - .getItemIdsUsingGetIdByIndex(startIndex, numberOfIds, this); - } - - /**********************************************/ - /** Methods from interface Container.Ordered **/ - /**********************************************/ - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Ordered#nextItemId(java.lang.Object) - */ - - @Override - public Object nextItemId(Object itemId) { - int index = indexOfId(itemId) + 1; - try { - return getIdByIndex(index); - } catch (IndexOutOfBoundsException e) { - return null; - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Ordered#prevItemId(java.lang.Object) - */ - - @Override - public Object prevItemId(Object itemId) { - int prevIndex = indexOfId(itemId) - 1; - try { - return getIdByIndex(prevIndex); - } catch (IndexOutOfBoundsException e) { - return null; - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Ordered#firstItemId() - */ - - @Override - public Object firstItemId() { - updateCount(); - if (size == 0) { - if (addedItems.isEmpty()) { - return null; - } else { - int ix = -1; - do { - ix++; - } while (!itemPassesFilters(addedItems.get(ix)) - && ix < addedItems.size()); - if (ix < addedItems.size()) { - return addedItems.get(ix).getId(); - } - } - } - if (!itemIndexes.containsKey(0)) { - updateOffsetAndCache(0); - } - return itemIndexes.get(0); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Ordered#lastItemId() - */ - - @Override - public Object lastItemId() { - if (addedItems.isEmpty()) { - int lastIx = size() - 1; - if (!itemIndexes.containsKey(lastIx)) { - updateOffsetAndCache(size - 1); - } - return itemIndexes.get(lastIx); - } else { - int ix = addedItems.size(); - do { - ix--; - } while (!itemPassesFilters(addedItems.get(ix)) && ix >= 0); - if (ix >= 0) { - return addedItems.get(ix).getId(); - } else { - return null; - } - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Ordered#isFirstId(java.lang.Object) - */ - - @Override - public boolean isFirstId(Object itemId) { - return firstItemId().equals(itemId); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Ordered#isLastId(java.lang.Object) - */ - - @Override - public boolean isLastId(Object itemId) { - return lastItemId().equals(itemId); - } - - /***********************************************/ - /** Methods from interface Container.Sortable **/ - /***********************************************/ - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Sortable#sort(java.lang.Object[], - * boolean[]) - */ - - @Override - public void sort(Object[] propertyId, boolean[] ascending) { - sorters.clear(); - if (propertyId == null || propertyId.length == 0) { - refresh(); - return; - } - /* Generate OrderBy -objects */ - boolean asc = true; - for (int i = 0; i < propertyId.length; i++) { - /* Check that the property id is valid */ - if (propertyId[i] instanceof String - && propertyIds.contains(propertyId[i])) { - try { - asc = ascending[i]; - } catch (Exception e) { - getLogger().log(Level.WARNING, "", e); - } - sorters.add(new OrderBy((String) propertyId[i], asc)); - } - } - refresh(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Sortable#getSortableContainerPropertyIds() - */ - - @Override - public Collection<?> getSortableContainerPropertyIds() { - return getContainerPropertyIds(); - } - - /**************************************/ - /** Methods specific to SQLContainer **/ - /**************************************/ - - /** - * Refreshes the container - clears all caches and resets size and offset. - * Does NOT remove sorting or filtering rules! - */ - public void refresh() { - refresh(true); - } - - /** - * Refreshes the container. If <code>setSizeDirty</code> is - * <code>false</code>, assumes that the current size is up to date. This is - * used in {@link #updateCount()} to refresh the contents when we know the - * size was just updated. - * - * @param setSizeDirty - */ - private void refresh(boolean setSizeDirty) { - if (setSizeDirty) { - sizeDirty = true; - } - currentOffset = 0; - cachedItems.clear(); - itemIndexes.clear(); - fireContentsChange(); - } - - /** - * Returns modify state of the container. - * - * @return true if contents of this container have been modified - */ - public boolean isModified() { - return !removedItems.isEmpty() || !addedItems.isEmpty() - || !modifiedItems.isEmpty(); - } - - /** - * Set auto commit mode enabled or disabled. Auto commit mode means that all - * changes made to items of this container will be immediately written to - * the underlying data source. - * - * @param autoCommitEnabled - * true to enable auto commit mode - */ - public void setAutoCommit(boolean autoCommitEnabled) { - autoCommit = autoCommitEnabled; - } - - /** - * Returns status of the auto commit mode. - * - * @return true if auto commit mode is enabled - */ - public boolean isAutoCommit() { - return autoCommit; - } - - /** - * Returns the currently set page length. - * - * @return current page length - */ - public int getPageLength() { - return pageLength; - } - - /** - * Sets the page length used in lazy fetching of items from the data source. - * Also resets the cache size to match the new page length. - * - * As a side effect the container will be refreshed. - * - * @param pageLength - * new page length - */ - public void setPageLength(int pageLength) { - setPageLengthInternal(pageLength); - refresh(); - } - - /** - * Sets the page length internally, without refreshing the container. - * - * @param pageLength - * the new page length - */ - private void setPageLengthInternal(int pageLength) { - this.pageLength = pageLength > 0 ? pageLength : DEFAULT_PAGE_LENGTH; - cacheOverlap = getPageLength(); - cachedItems.setCacheLimit(CACHE_RATIO * getPageLength() + cacheOverlap); - } - - /** - * Adds the given OrderBy to this container and refreshes the container - * contents with the new sorting rules. - * - * Note that orderBy.getColumn() must return a column name that exists in - * this container. - * - * @param orderBy - * OrderBy to be added to the container sorting rules - */ - public void addOrderBy(OrderBy orderBy) { - if (orderBy == null) { - return; - } - if (!propertyIds.contains(orderBy.getColumn())) { - throw new IllegalArgumentException( - "The column given for sorting does not exist in this container."); - } - sorters.add(orderBy); - refresh(); - } - - /** - * Commits all the changes, additions and removals made to the items of this - * container. - * - * @throws UnsupportedOperationException - * @throws SQLException - */ - public void commit() throws UnsupportedOperationException, SQLException { - try { - getLogger().log(Level.FINER, - "Commiting changes through delegate..."); - queryDelegate.beginTransaction(); - /* Perform buffered deletions */ - for (RowItem item : removedItems.values()) { - try { - if (!queryDelegate.removeRow(item)) { - throw new SQLException( - "Removal failed for row with ID: " - + item.getId()); - } - } catch (IllegalArgumentException e) { - throw new SQLException( - "Removal failed for row with ID: " + item.getId(), - e); - } - } - /* Perform buffered modifications */ - for (RowItem item : modifiedItems) { - if (!removedItems.containsKey(item.getId())) { - if (queryDelegate.storeRow(item) > 0) { - /* - * Also reset the modified state in the item in case it - * is reused e.g. in a form. - */ - item.commit(); - } else { - queryDelegate.rollback(); - refresh(); - throw new ConcurrentModificationException( - "Item with the ID '" + item.getId() - + "' has been externally modified."); - } - } - } - /* Perform buffered additions */ - for (RowItem item : addedItems) { - queryDelegate.storeRow(item); - } - queryDelegate.commit(); - removedItems.clear(); - addedItems.clear(); - modifiedItems.clear(); - refresh(); - if (notificationsEnabled) { - CacheFlushNotifier.notifyOfCacheFlush(this); - } - } catch (SQLException e) { - queryDelegate.rollback(); - throw e; - } catch (OptimisticLockException e) { - queryDelegate.rollback(); - throw e; - } - } - - /** - * Rolls back all the changes, additions and removals made to the items of - * this container. - * - * @throws UnsupportedOperationException - * @throws SQLException - */ - public void rollback() throws UnsupportedOperationException, SQLException { - getLogger().log(Level.FINE, "Rolling back changes..."); - removedItems.clear(); - addedItems.clear(); - modifiedItems.clear(); - refresh(); - } - - /** - * Notifies this container that a property in the given item has been - * modified. The change will be buffered or made instantaneously depending - * on auto commit mode. - * - * @param changedItem - * item that has a modified property - */ - void itemChangeNotification(RowItem changedItem) { - if (autoCommit) { - try { - queryDelegate.beginTransaction(); - if (queryDelegate.storeRow(changedItem) == 0) { - queryDelegate.rollback(); - refresh(); - throw new ConcurrentModificationException( - "Item with the ID '" + changedItem.getId() - + "' has been externally modified."); - } - queryDelegate.commit(); - if (notificationsEnabled) { - CacheFlushNotifier.notifyOfCacheFlush(this); - } - getLogger().log(Level.FINER, "Row updated to DB..."); - } catch (SQLException e) { - getLogger().log(Level.WARNING, - "itemChangeNotification failed, rolling back...", e); - try { - queryDelegate.rollback(); - } catch (SQLException ee) { - /* Nothing can be done here */ - getLogger().log(Level.SEVERE, "Rollback failed", e); - } - throw new RuntimeException(e); - } - } else { - if (!(changedItem.getId() instanceof TemporaryRowId) - && !modifiedItems.contains(changedItem)) { - modifiedItems.add(changedItem); - } - } - } - - /** - * Determines a new offset for updating the row cache. The offset is - * calculated from the given index, and will be fixed to match the start of - * a page, based on the value of pageLength. - * - * @param index - * Index of the item that was requested, but not found in cache - */ - private void updateOffsetAndCache(int index) { - - int oldOffset = currentOffset; - - currentOffset = (index / pageLength) * pageLength - cacheOverlap; - - if (currentOffset < 0) { - currentOffset = 0; - } - - if (oldOffset == currentOffset && !cachedItems.isEmpty()) { - return; - } - - getPage(); - } - - /** - * Fetches new count of rows from the data source, if needed. - */ - private void updateCount() { - if (!sizeDirty && new Date().getTime() < sizeUpdated.getTime() - + sizeValidMilliSeconds) { - return; - } - try { - try { - queryDelegate.setFilters(filters); - } catch (UnsupportedOperationException e) { - getLogger().log(Level.FINE, - "The query delegate doesn't support filtering", e); - } - try { - queryDelegate.setOrderBy(sorters); - } catch (UnsupportedOperationException e) { - getLogger().log(Level.FINE, - "The query delegate doesn't support sorting", e); - } - int newSize = queryDelegate.getCount(); - sizeUpdated = new Date(); - sizeDirty = false; - if (newSize != size) { - size = newSize; - // Size is up to date so don't set it back to dirty in refresh() - refresh(false); - } - getLogger().log(Level.FINER, "Updated row count. New count is: {0}", - size); - } catch (SQLException e) { - throw new RuntimeException("Failed to update item set size.", e); - } - } - - /** - * Fetches property id's (column names and their types) from the data - * source. - * - * @throws SQLException - */ - private void getPropertyIds() throws SQLException { - propertyIds.clear(); - propertyTypes.clear(); - queryDelegate.setFilters(null); - queryDelegate.setOrderBy(null); - ResultSet rs = null; - ResultSetMetaData rsmd = null; - try { - queryDelegate.beginTransaction(); - rs = queryDelegate.getResults(0, 1); - rsmd = rs.getMetaData(); - boolean resultExists = rs.next(); - Class<?> type = null; - for (int i = 1; i <= rsmd.getColumnCount(); i++) { - if (!isColumnIdentifierValid(rsmd.getColumnLabel(i))) { - continue; - } - String colName = rsmd.getColumnLabel(i); - /* - * Make sure not to add the same colName twice. This can easily - * happen if the SQL query joins many tables with an ID column. - */ - if (!propertyIds.contains(colName)) { - propertyIds.add(colName); - } - /* Try to determine the column's JDBC class by all means. */ - if (resultExists && rs.getObject(i) != null) { - type = rs.getObject(i).getClass(); - } else { - try { - type = Class.forName(rsmd.getColumnClassName(i)); - } catch (Exception e) { - getLogger().log(Level.WARNING, "Class not found", e); - /* On failure revert to Object and hope for the best. */ - type = Object.class; - } - } - /* - * Determine read only and nullability status of the column. A - * column is read only if it is reported as either read only or - * auto increment by the database, and also it is set as the - * version column in a TableQuery delegate. - */ - boolean readOnly = rsmd.isAutoIncrement(i) - || rsmd.isReadOnly(i); - - boolean persistable = !rsmd.isReadOnly(i); - - if (queryDelegate instanceof TableQuery) { - if (rsmd.getColumnLabel(i).equals( - ((TableQuery) queryDelegate).getVersionColumn())) { - readOnly = true; - } - } - - propertyReadOnly.put(colName, readOnly); - propertyPersistable.put(colName, persistable); - propertyNullable.put(colName, - rsmd.isNullable(i) == ResultSetMetaData.columnNullable); - propertyPrimaryKey.put(colName, - queryDelegate.getPrimaryKeyColumns() - .contains(rsmd.getColumnLabel(i))); - propertyTypes.put(colName, type); - } - rs.getStatement().close(); - rs.close(); - queryDelegate.commit(); - getLogger().log(Level.FINER, "Property IDs fetched."); - } catch (SQLException e) { - getLogger().log(Level.WARNING, - "Failed to fetch property ids, rolling back", e); - try { - queryDelegate.rollback(); - } catch (SQLException e1) { - getLogger().log(Level.SEVERE, "Failed to roll back", e1); - } - try { - if (rs != null) { - if (rs.getStatement() != null) { - rs.getStatement().close(); - } - rs.close(); - } - } catch (SQLException e1) { - getLogger().log(Level.WARNING, "Failed to close session", e1); - } - throw e; - } - } - - /** - * Fetches a page from the data source based on the values of pageLength and - * currentOffset. Also updates the set of primary keys, used in - * identification of RowItems. - */ - private void getPage() { - updateCount(); - ResultSet rs = null; - ResultSetMetaData rsmd = null; - cachedItems.clear(); - itemIndexes.clear(); - try { - try { - queryDelegate.setOrderBy(sorters); - } catch (UnsupportedOperationException e) { - /* The query delegate doesn't support sorting. */ - /* No need to do anything. */ - getLogger().log(Level.FINE, - "The query delegate doesn't support sorting", e); - } - queryDelegate.beginTransaction(); - int fetchedRows = pageLength * CACHE_RATIO + cacheOverlap; - rs = queryDelegate.getResults(currentOffset, fetchedRows); - rsmd = rs.getMetaData(); - List<String> pKeys = queryDelegate.getPrimaryKeyColumns(); - // } - /* Create new items and column properties */ - ColumnProperty cp = null; - int rowCount = currentOffset; - if (!queryDelegate.implementationRespectsPagingLimits()) { - rowCount = currentOffset = 0; - setPageLengthInternal(size); - } - while (rs.next()) { - List<ColumnProperty> itemProperties = new ArrayList<ColumnProperty>(); - /* Generate row itemId based on primary key(s) */ - Object[] itemId = new Object[pKeys.size()]; - for (int i = 0; i < pKeys.size(); i++) { - itemId[i] = rs.getObject(pKeys.get(i)); - } - RowId id = null; - if (pKeys.isEmpty()) { - id = new ReadOnlyRowId(rs.getRow()); - } else { - id = new RowId(itemId); - } - List<String> propertiesToAdd = new ArrayList<String>( - propertyIds); - if (!removedItems.containsKey(id)) { - for (int i = 1; i <= rsmd.getColumnCount(); i++) { - if (!isColumnIdentifierValid(rsmd.getColumnLabel(i))) { - continue; - } - String colName = rsmd.getColumnLabel(i); - Object value = rs.getObject(i); - Class<?> type = value != null ? value.getClass() - : Object.class; - if (value == null) { - for (String propName : propertyTypes.keySet()) { - if (propName.equals(rsmd.getColumnLabel(i))) { - type = propertyTypes.get(propName); - break; - } - } - } - /* - * In case there are more than one column with the same - * name, add only the first one. This can easily happen - * if you join many tables where each table has an ID - * column. - */ - if (propertiesToAdd.contains(colName)) { - - cp = new ColumnProperty(colName, - propertyReadOnly.get(colName), - propertyPersistable.get(colName), - propertyNullable.get(colName), - propertyPrimaryKey.get(colName), value, - type); - itemProperties.add(cp); - propertiesToAdd.remove(colName); - } - } - /* Cache item */ - itemIndexes.put(rowCount, id); - - // if an item with the id is contained in the modified - // cache, then use this record and add it to the cached - // items. Otherwise create a new item - int modifiedIndex = indexInModifiedCache(id); - if (modifiedIndex != -1) { - cachedItems.put(id, modifiedItems.get(modifiedIndex)); - } else { - cachedItems.put(id, - new RowItem(this, id, itemProperties)); - } - - rowCount++; - } - } - rs.getStatement().close(); - rs.close(); - queryDelegate.commit(); - getLogger().log(Level.FINER, "Fetched {0} rows starting from {1}", - new Object[] { fetchedRows, currentOffset }); - } catch (SQLException e) { - getLogger().log(Level.WARNING, "Failed to fetch rows, rolling back", - e); - try { - queryDelegate.rollback(); - } catch (SQLException e1) { - getLogger().log(Level.SEVERE, "Failed to roll back", e1); - } - try { - if (rs != null) { - if (rs.getStatement() != null) { - rs.getStatement().close(); - rs.close(); - } - } - } catch (SQLException e1) { - getLogger().log(Level.WARNING, "Failed to close session", e1); - } - throw new RuntimeException("Failed to fetch page.", e); - } - } - - /** - * Returns the index of the item with the given itemId for the modified - * cache. - * - * @param itemId - * @return the index of the item with the itemId in the modified cache. Or - * -1 if not found. - */ - private int indexInModifiedCache(Object itemId) { - for (int ix = 0; ix < modifiedItems.size(); ix++) { - RowItem item = modifiedItems.get(ix); - if (item.getId().equals(itemId)) { - return ix; - } - } - return -1; - } - - private int sizeOfAddedItems() { - return getFilteredAddedItems().size(); - } - - private List<RowItem> getFilteredAddedItems() { - ArrayList<RowItem> filtered = new ArrayList<RowItem>(addedItems); - if (filters != null && !filters.isEmpty()) { - for (RowItem item : addedItems) { - if (!itemPassesFilters(item)) { - filtered.remove(item); - } - } - } - return filtered; - } - - private boolean itemPassesFilters(RowItem item) { - for (Filter filter : filters) { - if (!filter.passesFilter(item.getId(), item)) { - return false; - } - } - return true; - } - - /** - * Checks is the given column identifier valid to be used with SQLContainer. - * Currently the only non-valid identifier is "rownum" when MSSQL or Oracle - * is used. This is due to the way the SELECT queries are constructed in - * order to implement paging in these databases. - * - * @param identifier - * Column identifier - * @return true if the identifier is valid - */ - private boolean isColumnIdentifierValid(String identifier) { - if (identifier.equalsIgnoreCase("rownum") - && queryDelegate instanceof TableQuery) { - TableQuery tq = (TableQuery) queryDelegate; - if (tq.getSqlGenerator() instanceof MSSQLGenerator - || tq.getSqlGenerator() instanceof OracleGenerator) { - return false; - } - } - return true; - } - - /** - * Returns the QueryDelegate set for this SQLContainer. - * - * @return current querydelegate - */ - protected QueryDelegate getQueryDelegate() { - return queryDelegate; - } - - /************************************/ - /** UNSUPPORTED CONTAINER FEATURES **/ - /************************************/ - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#addContainerProperty(java.lang.Object, - * java.lang.Class, java.lang.Object) - */ - - @Override - public boolean addContainerProperty(Object propertyId, Class<?> type, - Object defaultValue) throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#removeContainerProperty(java.lang.Object) - */ - - @Override - public boolean removeContainerProperty(Object propertyId) - throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#addItem(java.lang.Object) - */ - - @Override - public Item addItem(Object itemId) throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object, - * java.lang.Object) - */ - - @Override - public Item addItemAfter(Object previousItemId, Object newItemId) - throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Indexed#addItemAt(int, java.lang.Object) - */ - - @Override - public Item addItemAt(int index, Object newItemId) - throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Indexed#addItemAt(int) - */ - - @Override - public Object addItemAt(int index) throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object) - */ - - @Override - public Object addItemAfter(Object previousItemId) - throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - /******************************************/ - /** ITEMSETCHANGENOTIFIER IMPLEMENTATION **/ - /******************************************/ - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.Container.ItemSetChangeNotifier#addListener(com.vaadin - * .data.Container.ItemSetChangeListener) - */ - - @Override - public void addItemSetChangeListener( - Container.ItemSetChangeListener listener) { - if (itemSetChangeListeners == null) { - itemSetChangeListeners = new LinkedList<Container.ItemSetChangeListener>(); - } - itemSetChangeListeners.add(listener); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #addItemSetChangeListener(com.vaadin.data.Container.ItemSetChangeListener)} - **/ - @Override - @Deprecated - public void addListener(Container.ItemSetChangeListener listener) { - addItemSetChangeListener(listener); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.Container.ItemSetChangeNotifier#removeListener(com.vaadin - * .data.Container.ItemSetChangeListener) - */ - - @Override - public void removeItemSetChangeListener( - Container.ItemSetChangeListener listener) { - if (itemSetChangeListeners != null) { - itemSetChangeListeners.remove(listener); - } - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #removeItemSetChangeListener(com.vaadin.data.Container.ItemSetChangeListener)} - **/ - @Override - @Deprecated - public void removeListener(Container.ItemSetChangeListener listener) { - removeItemSetChangeListener(listener); - } - - protected void fireContentsChange() { - if (itemSetChangeListeners != null) { - final Object[] l = itemSetChangeListeners.toArray(); - final Container.ItemSetChangeEvent event = new SQLContainer.ItemSetChangeEvent( - this); - for (int i = 0; i < l.length; i++) { - ((Container.ItemSetChangeListener) l[i]) - .containerItemSetChange(event); - } - } - } - - /** - * Simple ItemSetChangeEvent implementation. - */ - @SuppressWarnings("serial") - public static class ItemSetChangeEvent extends EventObject - implements Container.ItemSetChangeEvent { - - private ItemSetChangeEvent(SQLContainer source) { - super(source); - } - - @Override - public Container getContainer() { - return (Container) getSource(); - } - } - - /**************************************************/ - /** ROWIDCHANGELISTENER PASSING TO QUERYDELEGATE **/ - /**************************************************/ - - /** - * Adds a RowIdChangeListener to the QueryDelegate - * - * @param listener - */ - public void addRowIdChangeListener(RowIdChangeListener listener) { - if (queryDelegate instanceof QueryDelegate.RowIdChangeNotifier) { - ((QueryDelegate.RowIdChangeNotifier) queryDelegate) - .addListener(listener); - } - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #addRowIdChangeListener(RowIdChangeListener)} - **/ - @Deprecated - public void addListener(RowIdChangeListener listener) { - addRowIdChangeListener(listener); - } - - /** - * Removes a RowIdChangeListener from the QueryDelegate - * - * @param listener - */ - public void removeRowIdChangeListener(RowIdChangeListener listener) { - if (queryDelegate instanceof QueryDelegate.RowIdChangeNotifier) { - ((QueryDelegate.RowIdChangeNotifier) queryDelegate) - .removeListener(listener); - } - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #removeRowIdChangeListener(RowIdChangeListener)} - **/ - @Deprecated - public void removeListener(RowIdChangeListener listener) { - removeRowIdChangeListener(listener); - } - - /** - * Calling this will enable this SQLContainer to send and receive cache - * flush notifications for its lifetime. - */ - public void enableCacheFlushNotifications() { - if (!notificationsEnabled) { - notificationsEnabled = true; - CacheFlushNotifier.addInstance(this); - } - } - - /******************************************/ - /** Referencing mechanism implementation **/ - /******************************************/ - - /** - * Adds a new reference to the given SQLContainer. In addition to the - * container you must provide the column (property) names used for the - * reference in both this and the referenced SQLContainer. - * - * Note that multiple references pointing to the same SQLContainer are not - * supported. - * - * @param refdCont - * Target SQLContainer of the new reference - * @param refingCol - * Column (property) name in this container storing the (foreign - * key) reference - * @param refdCol - * Column (property) name in the referenced container storing the - * referenced key - */ - public void addReference(SQLContainer refdCont, String refingCol, - String refdCol) { - if (refdCont == null) { - throw new IllegalArgumentException( - "Referenced SQLContainer can not be null."); - } - if (!getContainerPropertyIds().contains(refingCol)) { - throw new IllegalArgumentException( - "Given referencing column name is invalid." - + " Please ensure that this container" - + " contains a property ID named: " + refingCol); - } - if (!refdCont.getContainerPropertyIds().contains(refdCol)) { - throw new IllegalArgumentException( - "Given referenced column name is invalid." - + " Please ensure that the referenced container" - + " contains a property ID named: " + refdCol); - } - if (references.keySet().contains(refdCont)) { - throw new IllegalArgumentException( - "An SQLContainer instance can only be referenced once."); - } - references.put(refdCont, new Reference(refdCont, refingCol, refdCol)); - } - - /** - * Removes the reference pointing to the given SQLContainer. - * - * @param refdCont - * Target SQLContainer of the reference - * @return true if successful, false if the reference did not exist - */ - public boolean removeReference(SQLContainer refdCont) { - if (refdCont == null) { - throw new IllegalArgumentException( - "Referenced SQLContainer can not be null."); - } - return references.remove(refdCont) == null ? false : true; - } - - /** - * Sets the referenced item. The referencing column of the item in this - * container is updated accordingly. - * - * @param itemId - * Item Id of the reference source (from this container) - * @param refdItemId - * Item Id of the reference target (from referenced container) - * @param refdCont - * Target SQLContainer of the reference - * @return true if the referenced item was successfully set, false on - * failure - */ - public boolean setReferencedItem(Object itemId, Object refdItemId, - SQLContainer refdCont) { - if (refdCont == null) { - throw new IllegalArgumentException( - "Referenced SQLContainer can not be null."); - } - Reference r = references.get(refdCont); - if (r == null) { - throw new IllegalArgumentException( - "Reference to the given SQLContainer not defined."); - } - try { - getContainerProperty(itemId, r.getReferencingColumn()) - .setValue(refdCont.getContainerProperty(refdItemId, - r.getReferencedColumn())); - return true; - } catch (Exception e) { - getLogger().log(Level.WARNING, "Setting referenced item failed.", - e); - return false; - } - } - - /** - * Fetches the Item Id of the referenced item from the target SQLContainer. - * - * @param itemId - * Item Id of the reference source (from this container) - * @param refdCont - * Target SQLContainer of the reference - * @return Item Id of the referenced item, or null if not found - */ - public Object getReferencedItemId(Object itemId, SQLContainer refdCont) { - if (refdCont == null) { - throw new IllegalArgumentException( - "Referenced SQLContainer can not be null."); - } - Reference r = references.get(refdCont); - if (r == null) { - throw new IllegalArgumentException( - "Reference to the given SQLContainer not defined."); - } - Object refKey = getContainerProperty(itemId, r.getReferencingColumn()) - .getValue(); - - refdCont.removeAllContainerFilters(); - refdCont.addContainerFilter(new Equal(r.getReferencedColumn(), refKey)); - Object toReturn = refdCont.firstItemId(); - refdCont.removeAllContainerFilters(); - return toReturn; - } - - /** - * Fetches the referenced item from the target SQLContainer. - * - * @param itemId - * Item Id of the reference source (from this container) - * @param refdCont - * Target SQLContainer of the reference - * @return The referenced item, or null if not found - */ - public Item getReferencedItem(Object itemId, SQLContainer refdCont) { - return refdCont.getItem(getReferencedItemId(itemId, refdCont)); - } - - private void writeObject(java.io.ObjectOutputStream out) - throws IOException { - out.defaultWriteObject(); - } - - private void readObject(java.io.ObjectInputStream in) - throws IOException, ClassNotFoundException { - in.defaultReadObject(); - if (notificationsEnabled) { - /* - * Register instance with CacheFlushNotifier after de-serialization - * if notifications are enabled - */ - CacheFlushNotifier.addInstance(this); - } - } - - private static final Logger getLogger() { - return Logger.getLogger(SQLContainer.class.getName()); - } - -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/SQLUtil.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/SQLUtil.java deleted file mode 100644 index 2abe45d5fc..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/SQLUtil.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer; - -import java.io.Serializable; - -public class SQLUtil implements Serializable { - /** - * Escapes different special characters in strings that are passed to SQL. - * Replaces the following: - * - * <list> - * <li>' is replaced with ''</li> - * <li>\x00 is removed</li> - * <li>\ is replaced with \\</li> - * <li>" is replaced with \"</li> - * <li>\x1a is removed</li> </list> - * - * Also note! The escaping done here may or may not be enough to prevent any - * and all SQL injections so it is recommended to check user input before - * giving it to the SQLContainer/TableQuery. - * - * @param constant - * @return \\\'\' - */ - public static String escapeSQL(String constant) { - if (constant == null) { - return null; - } - String fixedConstant = constant; - fixedConstant = fixedConstant.replaceAll("\\\\x00", ""); - fixedConstant = fixedConstant.replaceAll("\\\\x1a", ""); - fixedConstant = fixedConstant.replaceAll("'", "''"); - fixedConstant = fixedConstant.replaceAll("\\\\", "\\\\\\\\"); - fixedConstant = fixedConstant.replaceAll("\\\"", "\\\\\""); - return fixedConstant; - } -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/TemporaryRowId.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/TemporaryRowId.java deleted file mode 100644 index 5cd3e6fac8..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/TemporaryRowId.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer; - -public class TemporaryRowId extends RowId { - private static final long serialVersionUID = -641983830469018329L; - - public TemporaryRowId(Object... id) { - super(id); - } - - @Override - public int hashCode() { - return id.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj == null || !(TemporaryRowId.class.equals(obj.getClass()))) { - return false; - } - Object[] compId = ((TemporaryRowId) obj).getId(); - return id.equals(compId); - } - - @Override - public String toString() { - return "Temporary row id"; - } - -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPool.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPool.java deleted file mode 100644 index cf50a641de..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPool.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer.connection; - -import java.sql.Connection; -import java.sql.SQLException; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javax.naming.InitialContext; -import javax.naming.NamingException; -import javax.sql.DataSource; - -public class J2EEConnectionPool implements JDBCConnectionPool { - - private String dataSourceJndiName; - - private DataSource dataSource = null; - - public J2EEConnectionPool(DataSource dataSource) { - this.dataSource = dataSource; - } - - public J2EEConnectionPool(String dataSourceJndiName) { - this.dataSourceJndiName = dataSourceJndiName; - } - - @Override - public Connection reserveConnection() throws SQLException { - Connection conn = getDataSource().getConnection(); - conn.setAutoCommit(false); - - return conn; - } - - private DataSource getDataSource() throws SQLException { - if (dataSource == null) { - dataSource = lookupDataSource(); - } - return dataSource; - } - - private DataSource lookupDataSource() throws SQLException { - try { - InitialContext ic = new InitialContext(); - return (DataSource) ic.lookup(dataSourceJndiName); - } catch (NamingException e) { - throw new SQLException( - "NamingException - Cannot connect to the database. Cause: " - + e.getMessage()); - } - } - - @Override - public void releaseConnection(Connection conn) { - if (conn != null) { - try { - conn.close(); - } catch (SQLException e) { - Logger.getLogger(J2EEConnectionPool.class.getName()) - .log(Level.FINE, "Could not release SQL connection", e); - } - } - } - - @Override - public void destroy() { - dataSource = null; - } - -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/connection/JDBCConnectionPool.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/connection/JDBCConnectionPool.java deleted file mode 100644 index 842a264caa..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/connection/JDBCConnectionPool.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer.connection; - -import java.io.Serializable; -import java.sql.Connection; -import java.sql.SQLException; - -/** - * Interface for implementing connection pools to be used with SQLContainer. - */ -public interface JDBCConnectionPool extends Serializable { - /** - * Retrieves a connection. - * - * @return a usable connection to the database - * @throws SQLException - */ - public Connection reserveConnection() throws SQLException; - - /** - * Releases a connection that was retrieved earlier. - * - * Note that depending on implementation, the transaction possibly open in - * the connection may or may not be rolled back. - * - * @param conn - * Connection to be released - */ - public void releaseConnection(Connection conn); - - /** - * Destroys the connection pool: close() is called an all the connections in - * the pool, whether available or reserved. - * - * This method was added to fix PostgreSQL -related issues with connections - * that were left hanging 'idle'. - */ - public void destroy(); -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java deleted file mode 100644 index 9cf02a9e68..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer.connection; - -import java.io.IOException; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.HashSet; -import java.util.Set; - -/** - * Simple implementation of the JDBCConnectionPool interface. Handles loading - * the JDBC driver, setting up the connections and ensuring they are still - * usable upon release. - */ -@SuppressWarnings("serial") -public class SimpleJDBCConnectionPool implements JDBCConnectionPool { - - private int initialConnections = 5; - private int maxConnections = 20; - - private String driverName; - private String connectionUri; - private String userName; - private String password; - - private transient Set<Connection> availableConnections; - private transient Set<Connection> reservedConnections; - - private boolean initialized; - - public SimpleJDBCConnectionPool(String driverName, String connectionUri, - String userName, String password) throws SQLException { - if (driverName == null) { - throw new IllegalArgumentException( - "JDBC driver class name must be given."); - } - if (connectionUri == null) { - throw new IllegalArgumentException( - "Database connection URI must be given."); - } - if (userName == null) { - throw new IllegalArgumentException( - "Database username must be given."); - } - if (password == null) { - throw new IllegalArgumentException( - "Database password must be given."); - } - this.driverName = driverName; - this.connectionUri = connectionUri; - this.userName = userName; - this.password = password; - - /* Initialize JDBC driver */ - try { - Class.forName(driverName).newInstance(); - } catch (Exception ex) { - throw new RuntimeException("Specified JDBC Driver: " + driverName - + " - initialization failed.", ex); - } - } - - public SimpleJDBCConnectionPool(String driverName, String connectionUri, - String userName, String password, int initialConnections, - int maxConnections) throws SQLException { - this(driverName, connectionUri, userName, password); - this.initialConnections = initialConnections; - this.maxConnections = maxConnections; - } - - private void initializeConnections() throws SQLException { - availableConnections = new HashSet<Connection>(initialConnections); - reservedConnections = new HashSet<Connection>(initialConnections); - for (int i = 0; i < initialConnections; i++) { - availableConnections.add(createConnection()); - } - initialized = true; - } - - @Override - public synchronized Connection reserveConnection() throws SQLException { - if (!initialized) { - initializeConnections(); - } - if (availableConnections.isEmpty()) { - if (reservedConnections.size() < maxConnections) { - availableConnections.add(createConnection()); - } else { - throw new SQLException("Connection limit has been reached."); - } - } - - Connection c = availableConnections.iterator().next(); - availableConnections.remove(c); - reservedConnections.add(c); - - return c; - } - - @Override - public synchronized void releaseConnection(Connection conn) { - if (conn == null || !initialized) { - return; - } - /* Try to roll back if necessary */ - try { - if (!conn.getAutoCommit()) { - conn.rollback(); - } - } catch (SQLException e) { - /* Roll back failed, close and discard connection */ - try { - conn.close(); - } catch (SQLException e1) { - /* Nothing needs to be done */ - } - reservedConnections.remove(conn); - return; - } - reservedConnections.remove(conn); - availableConnections.add(conn); - } - - private Connection createConnection() throws SQLException { - Connection c = DriverManager.getConnection(connectionUri, userName, - password); - c.setAutoCommit(false); - if (driverName.toLowerCase().contains("mysql")) { - try { - Statement s = c.createStatement(); - s.execute("SET SESSION sql_mode = 'ANSI'"); - s.close(); - } catch (Exception e) { - // Failed to set ansi mode; continue - } - } - return c; - } - - @Override - public void destroy() { - for (Connection c : availableConnections) { - try { - c.close(); - } catch (SQLException e) { - // No need to do anything - } - } - for (Connection c : reservedConnections) { - try { - c.close(); - } catch (SQLException e) { - // No need to do anything - } - } - - } - - private void writeObject(java.io.ObjectOutputStream out) - throws IOException { - initialized = false; - out.defaultWriteObject(); - } - -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/AbstractTransactionalQuery.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/AbstractTransactionalQuery.java deleted file mode 100644 index 586fe28171..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/AbstractTransactionalQuery.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer.query; - -import java.io.Serializable; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool; - -/** - * Common base class for database query classes that handle connections and - * transactions. - * - * @author Vaadin Ltd - * @since 6.8.9 - */ -public abstract class AbstractTransactionalQuery implements Serializable { - - private JDBCConnectionPool connectionPool; - private transient Connection activeConnection; - - AbstractTransactionalQuery() { - } - - AbstractTransactionalQuery(JDBCConnectionPool connectionPool) { - this.connectionPool = connectionPool; - } - - /** - * Reserves a connection with auto-commit off if no transaction is in - * progress. - * - * @throws IllegalStateException - * if a transaction is already open - * @throws SQLException - * if a connection could not be obtained or configured - */ - public void beginTransaction() - throws UnsupportedOperationException, SQLException { - if (isInTransaction()) { - throw new IllegalStateException("A transaction is already active!"); - } - activeConnection = connectionPool.reserveConnection(); - activeConnection.setAutoCommit(false); - } - - /** - * Commits (if not in auto-commit mode) and releases the active connection. - * - * @throws SQLException - * if not in a transaction managed by this query - */ - public void commit() throws UnsupportedOperationException, SQLException { - if (!isInTransaction()) { - throw new SQLException("No active transaction"); - } - if (!activeConnection.getAutoCommit()) { - activeConnection.commit(); - } - connectionPool.releaseConnection(activeConnection); - activeConnection = null; - } - - /** - * Rolls back and releases the active connection. - * - * @throws SQLException - * if not in a transaction managed by this query - */ - public void rollback() throws UnsupportedOperationException, SQLException { - if (!isInTransaction()) { - throw new SQLException("No active transaction"); - } - activeConnection.rollback(); - connectionPool.releaseConnection(activeConnection); - activeConnection = null; - } - - /** - * Check that a transaction is active. - * - * @throws SQLException - * if no active transaction - */ - protected void ensureTransaction() throws SQLException { - if (!isInTransaction()) { - throw new SQLException("No active transaction!"); - } - } - - /** - * Closes a statement and a resultset, then releases the connection if it is - * not part of an active transaction. A failure in closing one of the - * parameters does not prevent closing the rest. - * - * If the statement is a {@link PreparedStatement}, its parameters are - * cleared prior to closing the statement. - * - * Although JDBC specification does state that closing a statement closes - * its result set and closing a connection closes statements and result - * sets, this method does try to close the result set and statement - * explicitly whenever not null. This can guard against bugs in certain JDBC - * drivers and reduce leaks in case e.g. closing the result set succeeds but - * closing the statement or connection fails. - * - * @param conn - * the connection to release - * @param statement - * the statement to close, may be null to skip closing - * @param rs - * the result set to close, may be null to skip closing - * @throws SQLException - * if closing the result set or the statement fails - */ - protected void releaseConnection(Connection conn, Statement statement, - ResultSet rs) throws SQLException { - try { - try { - if (null != rs) { - rs.close(); - } - } finally { - if (null != statement) { - if (statement instanceof PreparedStatement) { - try { - ((PreparedStatement) statement).clearParameters(); - } catch (Exception e) { - // will be closed below anyway - } - } - statement.close(); - } - } - } finally { - releaseConnection(conn); - } - } - - /** - * Returns the currently active connection, reserves and returns a new - * connection if no active connection. - * - * @return previously active or newly reserved connection - * @throws SQLException - */ - protected Connection getConnection() throws SQLException { - if (activeConnection != null) { - return activeConnection; - } - return connectionPool.reserveConnection(); - } - - protected boolean isInTransaction() { - return activeConnection != null; - } - - /** - * Releases the connection if it is not part of an active transaction. - * - * @param conn - * the connection to release - */ - private void releaseConnection(Connection conn) { - if (conn != activeConnection && conn != null) { - connectionPool.releaseConnection(conn); - } - } -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java deleted file mode 100644 index 8066d563a4..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java +++ /dev/null @@ -1,495 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer.query; - -import java.io.IOException; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.sqlcontainer.RowItem; -import com.vaadin.data.util.sqlcontainer.SQLContainer; -import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; -import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder; - -@SuppressWarnings("serial") -public class FreeformQuery extends AbstractTransactionalQuery - implements QueryDelegate { - - FreeformQueryDelegate delegate = null; - private String queryString; - private List<String> primaryKeyColumns; - - /** - * Prevent no-parameters instantiation of FreeformQuery - */ - @SuppressWarnings("unused") - private FreeformQuery() { - } - - /** - * Creates a new freeform query delegate to be used with the - * {@link SQLContainer}. - * - * @param queryString - * The actual query to perform. - * @param primaryKeyColumns - * The primary key columns. Read-only mode is forced if this - * parameter is null or empty. - * @param connectionPool - * the JDBCConnectionPool to use to open connections to the SQL - * database. - * @deprecated As of 6.7, @see - * {@link FreeformQuery#FreeformQuery(String, JDBCConnectionPool, String...)} - */ - @Deprecated - public FreeformQuery(String queryString, List<String> primaryKeyColumns, - JDBCConnectionPool connectionPool) { - super(connectionPool); - if (primaryKeyColumns == null) { - primaryKeyColumns = new ArrayList<String>(); - } - if (primaryKeyColumns.contains("")) { - throw new IllegalArgumentException( - "The primary key columns contain an empty string!"); - } else if (queryString == null || "".equals(queryString)) { - throw new IllegalArgumentException( - "The query string may not be empty or null!"); - } else if (connectionPool == null) { - throw new IllegalArgumentException( - "The connectionPool may not be null!"); - } - this.queryString = queryString; - this.primaryKeyColumns = Collections - .unmodifiableList(primaryKeyColumns); - } - - /** - * Creates a new freeform query delegate to be used with the - * {@link SQLContainer}. - * - * @param queryString - * The actual query to perform. - * @param connectionPool - * the JDBCConnectionPool to use to open connections to the SQL - * database. - * @param primaryKeyColumns - * The primary key columns. Read-only mode is forced if none are - * provided. (optional) - */ - public FreeformQuery(String queryString, JDBCConnectionPool connectionPool, - String... primaryKeyColumns) { - this(queryString, Arrays.asList(primaryKeyColumns), connectionPool); - } - - /** - * This implementation of getCount() actually fetches all records from the - * database, which might be a performance issue. Override this method with a - * SELECT COUNT(*) ... query if this is too slow for your needs. - * - * {@inheritDoc} - */ - @Override - public int getCount() throws SQLException { - // First try the delegate - int count = countByDelegate(); - if (count < 0) { - // Couldn't use the delegate, use the bad way. - Statement statement = null; - ResultSet rs = null; - Connection conn = getConnection(); - try { - statement = conn.createStatement( - ResultSet.TYPE_SCROLL_INSENSITIVE, - ResultSet.CONCUR_READ_ONLY); - - rs = statement.executeQuery(queryString); - if (rs.last()) { - count = rs.getRow(); - } else { - count = 0; - } - } finally { - releaseConnection(conn, statement, rs); - } - } - return count; - } - - @SuppressWarnings("deprecation") - private int countByDelegate() throws SQLException { - int count = -1; - if (delegate == null) { - return count; - } - /* First try using prepared statement */ - if (delegate instanceof FreeformStatementDelegate) { - try { - StatementHelper sh = ((FreeformStatementDelegate) delegate) - .getCountStatement(); - PreparedStatement pstmt = null; - ResultSet rs = null; - Connection c = getConnection(); - try { - pstmt = c.prepareStatement(sh.getQueryString()); - sh.setParameterValuesToStatement(pstmt); - rs = pstmt.executeQuery(); - if (rs.next()) { - count = rs.getInt(1); - } else { - // The result can be empty when using group by and there - // are no matches (#18043) - count = 0; - } - } finally { - releaseConnection(c, pstmt, rs); - } - return count; - } catch (UnsupportedOperationException e) { - // Count statement generation not supported - } - } - /* Try using regular statement */ - try { - String countQuery = delegate.getCountQuery(); - if (countQuery != null) { - Statement statement = null; - ResultSet rs = null; - Connection conn = getConnection(); - try { - statement = conn.createStatement(); - rs = statement.executeQuery(countQuery); - if (rs.next()) { - count = rs.getInt(1); - } else { - // The result can be empty when using group by and there - // are no matches (#18043) - count = 0; - } - return count; - } finally { - releaseConnection(conn, statement, rs); - } - } - } catch (UnsupportedOperationException e) { - // Count query generation not supported - } - return count; - } - - /** - * Fetches the results for the query. This implementation always fetches the - * entire record set, ignoring the offset and page length parameters. In - * order to support lazy loading of records, you must supply a - * FreeformQueryDelegate that implements the - * FreeformQueryDelegate.getQueryString(int,int) method. - * - * @throws SQLException - * - * @see FreeformQueryDelegate#getQueryString(int, int) - */ - @Override - @SuppressWarnings({ "deprecation", "finally" }) - public ResultSet getResults(int offset, int pagelength) - throws SQLException { - ensureTransaction(); - String query = queryString; - if (delegate != null) { - /* First try using prepared statement */ - if (delegate instanceof FreeformStatementDelegate) { - try { - StatementHelper sh = ((FreeformStatementDelegate) delegate) - .getQueryStatement(offset, pagelength); - PreparedStatement pstmt = getConnection() - .prepareStatement(sh.getQueryString()); - sh.setParameterValuesToStatement(pstmt); - return pstmt.executeQuery(); - } catch (UnsupportedOperationException e) { - // Statement generation not supported, continue... - } - } - try { - query = delegate.getQueryString(offset, pagelength); - } catch (UnsupportedOperationException e) { - // This is fine, we'll just use the default queryString. - } - } - Statement statement = getConnection().createStatement(); - ResultSet rs; - try { - rs = statement.executeQuery(query); - } catch (SQLException e) { - try { - statement.close(); - } finally { - // throw the original exception even if closing the statement - // fails - throw e; - } - } - return rs; - } - - @Override - @SuppressWarnings("deprecation") - public boolean implementationRespectsPagingLimits() { - if (delegate == null) { - return false; - } - /* First try using prepared statement */ - if (delegate instanceof FreeformStatementDelegate) { - try { - StatementHelper sh = ((FreeformStatementDelegate) delegate) - .getCountStatement(); - if (sh != null && sh.getQueryString() != null - && sh.getQueryString().length() > 0) { - return true; - } - } catch (UnsupportedOperationException e) { - // Statement generation not supported, continue... - } - } - try { - String queryString = delegate.getQueryString(0, 50); - return queryString != null && queryString.length() > 0; - } catch (UnsupportedOperationException e) { - return false; - } - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.util.sqlcontainer.query.QueryDelegate#setFilters(java - * .util.List) - */ - @Override - public void setFilters(List<Filter> filters) - throws UnsupportedOperationException { - if (delegate != null) { - delegate.setFilters(filters); - } else if (filters != null) { - throw new UnsupportedOperationException( - "FreeFormQueryDelegate not set!"); - } - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.util.sqlcontainer.query.QueryDelegate#setOrderBy(java - * .util.List) - */ - @Override - public void setOrderBy(List<OrderBy> orderBys) - throws UnsupportedOperationException { - if (delegate != null) { - delegate.setOrderBy(orderBys); - } else if (orderBys != null) { - throw new UnsupportedOperationException( - "FreeFormQueryDelegate not set!"); - } - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.util.sqlcontainer.query.QueryDelegate#storeRow(com.vaadin - * .data.util.sqlcontainer.RowItem) - */ - @Override - public int storeRow(RowItem row) throws SQLException { - if (!isInTransaction()) { - throw new IllegalStateException("No transaction is active!"); - } else if (primaryKeyColumns.isEmpty()) { - throw new UnsupportedOperationException( - "Cannot store items fetched with a read-only freeform query!"); - } - if (delegate != null) { - return delegate.storeRow(getConnection(), row); - } else { - throw new UnsupportedOperationException( - "FreeFormQueryDelegate not set!"); - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.sqlcontainer.query.QueryDelegate#removeRow(com. - * vaadin .data.util.sqlcontainer.RowItem) - */ - @Override - public boolean removeRow(RowItem row) throws SQLException { - if (!isInTransaction()) { - throw new IllegalStateException("No transaction is active!"); - } else if (primaryKeyColumns.isEmpty()) { - throw new UnsupportedOperationException( - "Cannot remove items fetched with a read-only freeform query!"); - } - if (delegate != null) { - return delegate.removeRow(getConnection(), row); - } else { - throw new UnsupportedOperationException( - "FreeFormQueryDelegate not set!"); - } - } - - @Override - public synchronized void beginTransaction() - throws UnsupportedOperationException, SQLException { - super.beginTransaction(); - } - - @Override - public synchronized void commit() - throws UnsupportedOperationException, SQLException { - super.commit(); - } - - @Override - public synchronized void rollback() - throws UnsupportedOperationException, SQLException { - super.rollback(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.sqlcontainer.query.QueryDelegate# - * getPrimaryKeyColumns () - */ - @Override - public List<String> getPrimaryKeyColumns() { - return primaryKeyColumns; - } - - public String getQueryString() { - return queryString; - } - - public FreeformQueryDelegate getDelegate() { - return delegate; - } - - public void setDelegate(FreeformQueryDelegate delegate) { - this.delegate = delegate; - } - - /** - * This implementation of the containsRowWithKey method rewrites existing - * WHERE clauses in the query string. The logic is, however, not very - * complex and some times can do the Wrong Thing<sup>TM</sup>. For the - * situations where this logic is not enough, you can implement the - * getContainsRowQueryString method in FreeformQueryDelegate and this will - * be used instead of the logic. - * - * @see FreeformQueryDelegate#getContainsRowQueryString(Object...) - * - */ - @Override - @SuppressWarnings("deprecation") - public boolean containsRowWithKey(Object... keys) throws SQLException { - String query = null; - boolean contains = false; - if (delegate != null) { - if (delegate instanceof FreeformStatementDelegate) { - try { - StatementHelper sh = ((FreeformStatementDelegate) delegate) - .getContainsRowQueryStatement(keys); - - PreparedStatement pstmt = null; - ResultSet rs = null; - Connection c = getConnection(); - try { - pstmt = c.prepareStatement(sh.getQueryString()); - sh.setParameterValuesToStatement(pstmt); - rs = pstmt.executeQuery(); - contains = rs.next(); - return contains; - } finally { - releaseConnection(c, pstmt, rs); - } - } catch (UnsupportedOperationException e) { - // Statement generation not supported, continue... - } - } - try { - query = delegate.getContainsRowQueryString(keys); - } catch (UnsupportedOperationException e) { - query = modifyWhereClause(keys); - } - } else { - query = modifyWhereClause(keys); - } - Statement statement = null; - ResultSet rs = null; - Connection conn = getConnection(); - try { - statement = conn.createStatement(); - rs = statement.executeQuery(query); - contains = rs.next(); - } finally { - releaseConnection(conn, statement, rs); - } - return contains; - } - - private String modifyWhereClause(Object... keys) { - // Build the where rules for the provided keys - StringBuffer where = new StringBuffer(); - for (int ix = 0; ix < primaryKeyColumns.size(); ix++) { - where.append(QueryBuilder.quote(primaryKeyColumns.get(ix))); - if (keys[ix] == null) { - where.append(" IS NULL"); - } else { - where.append(" = '").append(keys[ix]).append("'"); - } - if (ix < primaryKeyColumns.size() - 1) { - where.append(" AND "); - } - } - // Is there already a WHERE clause in the query string? - int index = queryString.toLowerCase().indexOf("where "); - if (index > -1) { - // Rewrite the where clause - return queryString.substring(0, index) + "WHERE " + where + " AND " - + queryString.substring(index + 6); - } - // Append a where clause - return queryString + " WHERE " + where; - } - - private void writeObject(java.io.ObjectOutputStream out) - throws IOException { - try { - rollback(); - } catch (SQLException ignored) { - } - out.defaultWriteObject(); - } -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/FreeformQueryDelegate.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/FreeformQueryDelegate.java deleted file mode 100644 index fac0b1ab45..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/FreeformQueryDelegate.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer.query; - -import java.io.Serializable; -import java.sql.Connection; -import java.sql.SQLException; -import java.util.List; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.sqlcontainer.RowItem; - -public interface FreeformQueryDelegate extends Serializable { - /** - * Should return the SQL query string to be performed. This method is - * responsible for gluing together the select query from the filters and the - * order by conditions if these are supported. - * - * @param offset - * the first record (row) to fetch. - * @param pagelength - * the number of records (rows) to fetch. 0 means all records - * starting from offset. - * @deprecated As of 6.7. Implement {@link FreeformStatementDelegate} - * instead of {@link FreeformQueryDelegate} - */ - @Deprecated - public String getQueryString(int offset, int limit) - throws UnsupportedOperationException; - - /** - * Generates and executes a query to determine the current row count from - * the DB. Row count will be fetched using filters that are currently set to - * the QueryDelegate. - * - * @return row count - * @throws SQLException - * @deprecated As of 6.7. Implement {@link FreeformStatementDelegate} - * instead of {@link FreeformQueryDelegate} - */ - @Deprecated - public String getCountQuery() throws UnsupportedOperationException; - - /** - * Sets the filters to apply when performing the SQL query. These are - * translated into a WHERE clause. Default filtering mode will be used. - * - * @param filters - * The filters to apply. - * @throws UnsupportedOperationException - * if the implementation doesn't support filtering. - */ - public void setFilters(List<Filter> filters) - throws UnsupportedOperationException; - - /** - * Sets the order in which to retrieve rows from the database. The result - * can be ordered by zero or more columns and each column can be in - * ascending or descending order. These are translated into an ORDER BY - * clause in the SQL query. - * - * @param orderBys - * A list of the OrderBy conditions. - * @throws UnsupportedOperationException - * if the implementation doesn't support ordering. - */ - public void setOrderBy(List<OrderBy> orderBys) - throws UnsupportedOperationException; - - /** - * Stores a row in the database. The implementation of this interface - * decides how to identify whether to store a new row or update an existing - * one. - * - * @param conn - * the JDBC connection to use - * @param row - * RowItem to be stored or updated. - * @throws UnsupportedOperationException - * if the implementation is read only. - * @throws SQLException - */ - public int storeRow(Connection conn, RowItem row) - throws UnsupportedOperationException, SQLException; - - /** - * Removes the given RowItem from the database. - * - * @param conn - * the JDBC connection to use - * @param row - * RowItem to be removed - * @return true on success - * @throws UnsupportedOperationException - * @throws SQLException - */ - public boolean removeRow(Connection conn, RowItem row) - throws UnsupportedOperationException, SQLException; - - /** - * Generates an SQL Query string that allows the user of the FreeformQuery - * class to customize the query string used by the - * FreeformQuery.containsRowWithKeys() method. This is useful for cases when - * the logic in the containsRowWithKeys method is not enough to support more - * complex free form queries. - * - * @param keys - * the values of the primary keys - * @throws UnsupportedOperationException - * to use the default logic in FreeformQuery - * @deprecated As of 6.7. Implement {@link FreeformStatementDelegate} - * instead of {@link FreeformQueryDelegate} - */ - @Deprecated - public String getContainsRowQueryString(Object... keys) - throws UnsupportedOperationException; -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java deleted file mode 100644 index 884a303684..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer.query; - -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; - -/** - * FreeformStatementDelegate is an extension to FreeformQueryDelegate that - * provides definitions for methods that produce StatementHelper objects instead - * of basic query strings. This allows the FreeformQuery query delegate to use - * PreparedStatements instead of regular Statement when accessing the database. - * - * Due to the injection protection and other benefits of prepared statements, it - * is advisable to implement this interface instead of the FreeformQueryDelegate - * whenever possible. - */ -public interface FreeformStatementDelegate extends FreeformQueryDelegate { - /** - * Should return a new instance of StatementHelper that contains the query - * string and parameter values required to create a PreparedStatement. This - * method is responsible for gluing together the select query from the - * filters and the order by conditions if these are supported. - * - * @param offset - * the first record (row) to fetch. - * @param pagelength - * the number of records (rows) to fetch. 0 means all records - * starting from offset. - */ - public StatementHelper getQueryStatement(int offset, int limit) - throws UnsupportedOperationException; - - /** - * Should return a new instance of StatementHelper that contains the query - * string and parameter values required to create a PreparedStatement that - * will fetch the row count from the DB. Row count should be fetched using - * filters that are currently set to the QueryDelegate. - */ - public StatementHelper getCountStatement() - throws UnsupportedOperationException; - - /** - * Should return a new instance of StatementHelper that contains the query - * string and parameter values required to create a PreparedStatement used - * by the FreeformQuery.containsRowWithKeys() method. This is useful for - * cases when the default logic in said method is not enough to support more - * complex free form queries. - * - * @param keys - * the values of the primary keys - * @throws UnsupportedOperationException - * to use the default logic in FreeformQuery - */ - public StatementHelper getContainsRowQueryStatement(Object... keys) - throws UnsupportedOperationException; -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/OrderBy.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/OrderBy.java deleted file mode 100644 index ed57967772..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/OrderBy.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer.query; - -import java.io.Serializable; - -/** - * OrderBy represents a sorting rule to be applied to a query made by the - * SQLContainer's QueryDelegate. - * - * The sorting rule is simple and contains only the affected column's name and - * the direction of the sort. - */ -public class OrderBy implements Serializable { - private String column; - private boolean isAscending; - - /** - * Prevent instantiation without required parameters. - */ - @SuppressWarnings("unused") - private OrderBy() { - } - - public OrderBy(String column, boolean isAscending) { - setColumn(column); - setAscending(isAscending); - } - - public void setColumn(String column) { - this.column = column; - } - - public String getColumn() { - return column; - } - - public void setAscending(boolean isAscending) { - this.isAscending = isAscending; - } - - public boolean isAscending() { - return isAscending; - } -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/QueryDelegate.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/QueryDelegate.java deleted file mode 100644 index 16e04a7da0..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/QueryDelegate.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer.query; - -import java.io.Serializable; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.List; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.sqlcontainer.RowId; -import com.vaadin.data.util.sqlcontainer.RowItem; - -public interface QueryDelegate extends Serializable { - /** - * Generates and executes a query to determine the current row count from - * the DB. Row count will be fetched using filters that are currently set to - * the QueryDelegate. - * - * @return row count - * @throws SQLException - */ - public int getCount() throws SQLException; - - /** - * Executes a paged SQL query and returns the ResultSet. The query is - * defined through implementations of this QueryDelegate interface. - * - * @param offset - * the first item of the page to load - * @param pagelength - * the length of the page to load - * @return a ResultSet containing the rows of the page - * @throws SQLException - * if the database access fails. - */ - public ResultSet getResults(int offset, int pagelength) throws SQLException; - - /** - * Allows the SQLContainer implementation to check whether the QueryDelegate - * implementation implements paging in the getResults method. - * - * @see QueryDelegate#getResults(int, int) - * - * @return true if the delegate implements paging - */ - public boolean implementationRespectsPagingLimits(); - - /** - * Sets the filters to apply when performing the SQL query. These are - * translated into a WHERE clause. Default filtering mode will be used. - * - * @param filters - * The filters to apply. - * @throws UnsupportedOperationException - * if the implementation doesn't support filtering. - */ - public void setFilters(List<Filter> filters) - throws UnsupportedOperationException; - - /** - * Sets the order in which to retrieve rows from the database. The result - * can be ordered by zero or more columns and each column can be in - * ascending or descending order. These are translated into an ORDER BY - * clause in the SQL query. - * - * @param orderBys - * A list of the OrderBy conditions. - * @throws UnsupportedOperationException - * if the implementation doesn't support ordering. - */ - public void setOrderBy(List<OrderBy> orderBys) - throws UnsupportedOperationException; - - /** - * Stores a row in the database. The implementation of this interface - * decides how to identify whether to store a new row or update an existing - * one. - * - * @param columnToValueMap - * A map containing the values for all columns to be stored or - * updated. - * @return the number of affected rows in the database table - * @throws UnsupportedOperationException - * if the implementation is read only. - */ - public int storeRow(RowItem row) - throws UnsupportedOperationException, SQLException; - - /** - * Removes the given RowItem from the database. - * - * @param row - * RowItem to be removed - * @return true on success - * @throws UnsupportedOperationException - * @throws SQLException - */ - public boolean removeRow(RowItem row) - throws UnsupportedOperationException, SQLException; - - /** - * Starts a new database transaction. Used when storing multiple changes. - * - * Note that if a transaction is already open, it will be rolled back when a - * new transaction is started. - * - * @throws SQLException - * if the database access fails. - */ - public void beginTransaction() throws SQLException; - - /** - * Commits a transaction. If a transaction is not open nothing should - * happen. - * - * @throws SQLException - * if the database access fails. - */ - public void commit() throws SQLException; - - /** - * Rolls a transaction back. If a transaction is not open nothing should - * happen. - * - * @throws SQLException - * if the database access fails. - */ - public void rollback() throws SQLException; - - /** - * Returns a list of primary key column names. The list is either fetched - * from the database (TableQuery) or given as an argument depending on - * implementation. - * - * @return - */ - public List<String> getPrimaryKeyColumns(); - - /** - * Performs a query to find out whether the SQL table contains a row with - * the given set of primary keys. - * - * @param keys - * the primary keys - * @return true if the SQL table contains a row with the provided keys - * @throws SQLException - */ - public boolean containsRowWithKey(Object... keys) throws SQLException; - - /************************/ - /** ROWID CHANGE EVENT **/ - /************************/ - - /** - * An <code>Event</code> object specifying the old and new RowId of an added - * item after the addition has been successfully committed. - */ - public interface RowIdChangeEvent extends Serializable { - /** - * Gets the old (temporary) RowId of the added row that raised this - * event. - * - * @return old RowId - */ - public RowId getOldRowId(); - - /** - * Gets the new, possibly database assigned RowId of the added row that - * raised this event. - * - * @return new RowId - */ - public RowId getNewRowId(); - } - - /** RowId change listener interface. */ - public interface RowIdChangeListener extends Serializable { - /** - * Lets the listener know that a RowId has been changed. - * - * @param event - */ - public void rowIdChange(QueryDelegate.RowIdChangeEvent event); - } - - /** - * The interface for adding and removing <code>RowIdChangeEvent</code> - * listeners. By implementing this interface a class explicitly announces - * that it will generate a <code>RowIdChangeEvent</code> when it performs a - * database commit that may change the RowId. - */ - public interface RowIdChangeNotifier extends Serializable { - /** - * Adds a RowIdChangeListener for the object. - * - * @param listener - * listener to be added - */ - public void addRowIdChangeListener( - QueryDelegate.RowIdChangeListener listener); - - /** - * @deprecated As of 7.0, replaced by - * {@link #addRowIdChangeListener(RowIdChangeListener)} - **/ - @Deprecated - public void addListener(QueryDelegate.RowIdChangeListener listener); - - /** - * Removes the specified RowIdChangeListener from the object. - * - * @param listener - * listener to be removed - */ - public void removeRowIdChangeListener( - QueryDelegate.RowIdChangeListener listener); - - /** - * @deprecated As of 7.0, replaced by - * {@link #removeRowIdChangeListener(RowIdChangeListener)} - **/ - @Deprecated - public void removeListener(QueryDelegate.RowIdChangeListener listener); - } -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/TableQuery.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/TableQuery.java deleted file mode 100644 index 959c494634..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/TableQuery.java +++ /dev/null @@ -1,869 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer.query; - -import java.io.IOException; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.EventObject; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.filter.Compare.Equal; -import com.vaadin.data.util.sqlcontainer.ColumnProperty; -import com.vaadin.data.util.sqlcontainer.OptimisticLockException; -import com.vaadin.data.util.sqlcontainer.RowId; -import com.vaadin.data.util.sqlcontainer.RowItem; -import com.vaadin.data.util.sqlcontainer.SQLUtil; -import com.vaadin.data.util.sqlcontainer.TemporaryRowId; -import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool; -import com.vaadin.data.util.sqlcontainer.query.generator.DefaultSQLGenerator; -import com.vaadin.data.util.sqlcontainer.query.generator.MSSQLGenerator; -import com.vaadin.data.util.sqlcontainer.query.generator.SQLGenerator; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; - -@SuppressWarnings("serial") -public class TableQuery extends AbstractTransactionalQuery - implements QueryDelegate, QueryDelegate.RowIdChangeNotifier { - - /** - * Table name (without catalog or schema information). - */ - private String tableName; - private String catalogName; - private String schemaName; - /** - * Cached concatenated version of the table name. - */ - private String fullTableName; - /** - * Primary key column name(s) in the table. - */ - private List<String> primaryKeyColumns; - /** - * Version column name in the table. - */ - private String versionColumn; - - /** Currently set Filters and OrderBys */ - private List<Filter> filters; - private List<OrderBy> orderBys; - - /** SQLGenerator instance to use for generating queries */ - private SQLGenerator sqlGenerator; - - /** Row ID change listeners */ - private LinkedList<RowIdChangeListener> rowIdChangeListeners; - /** Row ID change events, stored until commit() is called */ - private final List<RowIdChangeEvent> bufferedEvents = new ArrayList<RowIdChangeEvent>(); - - /** Set to true to output generated SQL Queries to System.out */ - private final boolean debug = false; - - /** - * Creates a new TableQuery using the given connection pool, SQL generator - * and table name to fetch the data from. All parameters must be non-null. - * - * The table name must be a simple name with no catalog or schema - * information. If those are needed, use - * {@link #TableQuery(String, String, String, JDBCConnectionPool, SQLGenerator)} - * . - * - * @param tableName - * Name of the database table to connect to - * @param connectionPool - * Connection pool for accessing the database - * @param sqlGenerator - * SQL query generator implementation - */ - public TableQuery(String tableName, JDBCConnectionPool connectionPool, - SQLGenerator sqlGenerator) { - this(null, null, tableName, connectionPool, sqlGenerator); - } - - /** - * Creates a new TableQuery using the given connection pool, SQL generator - * and table name to fetch the data from. Catalog and schema names can be - * null, all other parameters must be non-null. - * - * @param catalogName - * Name of the database catalog (can be null) - * @param schemaName - * Name of the database schema (can be null) - * @param tableName - * Name of the database table to connect to - * @param connectionPool - * Connection pool for accessing the database - * @param sqlGenerator - * SQL query generator implementation - * @since 7.1 - */ - public TableQuery(String catalogName, String schemaName, String tableName, - JDBCConnectionPool connectionPool, SQLGenerator sqlGenerator) { - this(catalogName, schemaName, tableName, connectionPool, sqlGenerator, - true); - } - - /** - * Creates a new TableQuery using the given connection pool and table name - * to fetch the data from. All parameters must be non-null. The default SQL - * generator will be used for queries. - * - * The table name must be a simple name with no catalog or schema - * information. If those are needed, use - * {@link #TableQuery(String, String, String, JDBCConnectionPool, SQLGenerator)} - * . - * - * @param tableName - * Name of the database table to connect to - * @param connectionPool - * Connection pool for accessing the database - */ - public TableQuery(String tableName, JDBCConnectionPool connectionPool) { - this(tableName, connectionPool, new DefaultSQLGenerator()); - } - - /** - * Creates a new TableQuery using the given connection pool, SQL generator - * and table name to fetch the data from. Catalog and schema names can be - * null, all other parameters must be non-null. - * - * @param catalogName - * Name of the database catalog (can be null) - * @param schemaName - * Name of the database schema (can be null) - * @param tableName - * Name of the database table to connect to - * @param connectionPool - * Connection pool for accessing the database - * @param sqlGenerator - * SQL query generator implementation - * @param escapeNames - * true to escape special characters in catalog, schema and table - * names, false to use the names as-is - * @since 7.1 - */ - protected TableQuery(String catalogName, String schemaName, - String tableName, JDBCConnectionPool connectionPool, - SQLGenerator sqlGenerator, boolean escapeNames) { - super(connectionPool); - if (tableName == null || tableName.trim().length() < 1 - || connectionPool == null || sqlGenerator == null) { - throw new IllegalArgumentException( - "Table name, connection pool and SQL generator parameters must be non-null and non-empty."); - } - if (escapeNames) { - this.catalogName = SQLUtil.escapeSQL(catalogName); - this.schemaName = SQLUtil.escapeSQL(schemaName); - this.tableName = SQLUtil.escapeSQL(tableName); - } else { - this.catalogName = catalogName; - this.schemaName = schemaName; - this.tableName = tableName; - } - this.sqlGenerator = sqlGenerator; - fetchMetaData(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.sqlcontainer.query.QueryDelegate#getCount() - */ - @Override - public int getCount() throws SQLException { - getLogger().log(Level.FINE, "Fetching count..."); - StatementHelper sh = sqlGenerator.generateSelectQuery( - getFullTableName(), filters, null, 0, 0, "COUNT(*)"); - boolean shouldCloseTransaction = false; - if (!isInTransaction()) { - shouldCloseTransaction = true; - beginTransaction(); - } - ResultSet r = null; - int count = -1; - try { - r = executeQuery(sh); - r.next(); - count = r.getInt(1); - } finally { - try { - if (r != null) { - // Do not release connection, it is done in commit() - releaseConnection(null, r.getStatement(), r); - } - } finally { - if (shouldCloseTransaction) { - commit(); - } - } - } - return count; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.sqlcontainer.query.QueryDelegate#getResults(int, - * int) - */ - @Override - public ResultSet getResults(int offset, int pagelength) - throws SQLException { - StatementHelper sh; - /* - * If no ordering is explicitly set, results will be ordered by the - * first primary key column. - */ - if (orderBys == null || orderBys.isEmpty()) { - List<OrderBy> ob = new ArrayList<OrderBy>(); - for (int i = 0; i < primaryKeyColumns.size(); i++) { - ob.add(new OrderBy(primaryKeyColumns.get(i), true)); - } - sh = sqlGenerator.generateSelectQuery(getFullTableName(), filters, - ob, offset, pagelength, null); - } else { - sh = sqlGenerator.generateSelectQuery(getFullTableName(), filters, - orderBys, offset, pagelength, null); - } - return executeQuery(sh); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.sqlcontainer.query.QueryDelegate# - * implementationRespectsPagingLimits() - */ - @Override - public boolean implementationRespectsPagingLimits() { - return true; - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.sqlcontainer.query.QueryDelegate#storeRow(com.vaadin - * .addon.sqlcontainer.RowItem) - */ - @Override - public int storeRow(RowItem row) - throws UnsupportedOperationException, SQLException { - if (row == null) { - throw new IllegalArgumentException( - "Row argument must be non-null."); - } - StatementHelper sh; - int result = 0; - if (row.getId() instanceof TemporaryRowId) { - setVersionColumnFlagInProperty(row); - sh = sqlGenerator.generateInsertQuery(getFullTableName(), row); - result = executeUpdateReturnKeys(sh, row); - } else { - setVersionColumnFlagInProperty(row); - sh = sqlGenerator.generateUpdateQuery(getFullTableName(), row); - result = executeUpdate(sh); - } - if (versionColumn != null && result == 0) { - throw new OptimisticLockException( - "Someone else changed the row that was being updated.", - row.getId()); - } - return result; - } - - private void setVersionColumnFlagInProperty(RowItem row) { - ColumnProperty versionProperty = (ColumnProperty) row - .getItemProperty(versionColumn); - if (versionProperty != null) { - versionProperty.setVersionColumn(true); - } - } - - /** - * Inserts the given row in the database table immediately. Begins and - * commits the transaction needed. This method was added specifically to - * solve the problem of returning the final RowId immediately on the - * SQLContainer.addItem() call when auto commit mode is enabled in the - * SQLContainer. - * - * @param row - * RowItem to add to the database - * @return Final RowId of the added row - * @throws SQLException - */ - public RowId storeRowImmediately(RowItem row) throws SQLException { - beginTransaction(); - /* Set version column, if one is provided */ - setVersionColumnFlagInProperty(row); - /* Generate query */ - StatementHelper sh = sqlGenerator - .generateInsertQuery(getFullTableName(), row); - Connection connection = null; - PreparedStatement pstmt = null; - ResultSet generatedKeys = null; - connection = getConnection(); - try { - pstmt = connection.prepareStatement(sh.getQueryString(), - primaryKeyColumns.toArray(new String[0])); - sh.setParameterValuesToStatement(pstmt); - getLogger().log(Level.FINE, "DB -> {0}", sh.getQueryString()); - int result = pstmt.executeUpdate(); - RowId newId = null; - if (result > 0) { - /* - * If affected rows exist, we'll get the new RowId, commit the - * transaction and return the new RowId. - */ - generatedKeys = pstmt.getGeneratedKeys(); - newId = getNewRowId(row, generatedKeys); - } - // transaction has to be closed in any case - commit(); - return newId; - } finally { - releaseConnection(connection, pstmt, generatedKeys); - } - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.sqlcontainer.query.QueryDelegate#setFilters(java.util - * .List) - */ - @Override - public void setFilters(List<Filter> filters) - throws UnsupportedOperationException { - if (filters == null) { - this.filters = null; - return; - } - this.filters = Collections.unmodifiableList(filters); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.sqlcontainer.query.QueryDelegate#setOrderBy(java.util - * .List) - */ - @Override - public void setOrderBy(List<OrderBy> orderBys) - throws UnsupportedOperationException { - if (orderBys == null) { - this.orderBys = null; - return; - } - this.orderBys = Collections.unmodifiableList(orderBys); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.sqlcontainer.query.QueryDelegate#beginTransaction() - */ - @Override - public void beginTransaction() - throws UnsupportedOperationException, SQLException { - getLogger().log(Level.FINE, "DB -> begin transaction"); - super.beginTransaction(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.sqlcontainer.query.QueryDelegate#commit() - */ - @Override - public void commit() throws UnsupportedOperationException, SQLException { - getLogger().log(Level.FINE, "DB -> commit"); - super.commit(); - - /* Handle firing row ID change events */ - RowIdChangeEvent[] unFiredEvents = bufferedEvents - .toArray(new RowIdChangeEvent[] {}); - bufferedEvents.clear(); - if (rowIdChangeListeners != null && !rowIdChangeListeners.isEmpty()) { - for (RowIdChangeListener r : rowIdChangeListeners) { - for (RowIdChangeEvent e : unFiredEvents) { - r.rowIdChange(e); - } - } - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.sqlcontainer.query.QueryDelegate#rollback() - */ - @Override - public void rollback() throws UnsupportedOperationException, SQLException { - getLogger().log(Level.FINE, "DB -> rollback"); - super.rollback(); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.sqlcontainer.query.QueryDelegate#getPrimaryKeyColumns() - */ - @Override - public List<String> getPrimaryKeyColumns() { - return Collections.unmodifiableList(primaryKeyColumns); - } - - public String getVersionColumn() { - return versionColumn; - } - - public void setVersionColumn(String column) { - versionColumn = column; - } - - /** - * Returns the table name for the query without catalog and schema - * information. - * - * @return table name, not null - */ - public String getTableName() { - return tableName; - } - - /** - * Returns the catalog name for the query. - * - * @return catalog name, can be null - * @since 7.1 - */ - public String getCatalogName() { - return catalogName; - } - - /** - * Returns the catalog name for the query. - * - * @return catalog name, can be null - * @since 7.1 - */ - public String getSchemaName() { - return schemaName; - } - - /** - * Returns the complete table name obtained by concatenation of the catalog - * and schema names (if any) and the table name. - * - * This method can be overridden if customization is needed. - * - * @return table name in the form it should be used in query and update - * statements - * @since 7.1 - */ - protected String getFullTableName() { - if (fullTableName == null) { - StringBuilder sb = new StringBuilder(); - if (catalogName != null) { - sb.append(catalogName).append("."); - } - if (schemaName != null) { - sb.append(schemaName).append("."); - } - sb.append(tableName); - fullTableName = sb.toString(); - } - return fullTableName; - } - - public SQLGenerator getSqlGenerator() { - return sqlGenerator; - } - - /** - * Executes the given query string using either the active connection if a - * transaction is already open, or a new connection from this query's - * connection pool. - * - * @param sh - * an instance of StatementHelper, containing the query string - * and parameter values. - * @return ResultSet of the query - * @throws SQLException - */ - private ResultSet executeQuery(StatementHelper sh) throws SQLException { - ensureTransaction(); - Connection connection = getConnection(); - PreparedStatement pstmt = null; - try { - pstmt = connection.prepareStatement(sh.getQueryString()); - sh.setParameterValuesToStatement(pstmt); - getLogger().log(Level.FINE, "DB -> {0}", sh.getQueryString()); - return pstmt.executeQuery(); - } catch (SQLException e) { - releaseConnection(null, pstmt, null); - throw e; - } - } - - /** - * Executes the given update query string using either the active connection - * if a transaction is already open, or a new connection from this query's - * connection pool. - * - * @param sh - * an instance of StatementHelper, containing the query string - * and parameter values. - * @return Number of affected rows - * @throws SQLException - */ - private int executeUpdate(StatementHelper sh) throws SQLException { - PreparedStatement pstmt = null; - Connection connection = null; - try { - connection = getConnection(); - pstmt = connection.prepareStatement(sh.getQueryString()); - sh.setParameterValuesToStatement(pstmt); - getLogger().log(Level.FINE, "DB -> {0}", sh.getQueryString()); - int retval = pstmt.executeUpdate(); - return retval; - } finally { - releaseConnection(connection, pstmt, null); - } - } - - /** - * Executes the given update query string using either the active connection - * if a transaction is already open, or a new connection from this query's - * connection pool. - * - * Additionally adds a new RowIdChangeEvent to the event buffer. - * - * @param sh - * an instance of StatementHelper, containing the query string - * and parameter values. - * @param row - * the row item to update - * @return Number of affected rows - * @throws SQLException - */ - private int executeUpdateReturnKeys(StatementHelper sh, RowItem row) - throws SQLException { - PreparedStatement pstmt = null; - ResultSet genKeys = null; - Connection connection = null; - try { - connection = getConnection(); - pstmt = connection.prepareStatement(sh.getQueryString(), - primaryKeyColumns.toArray(new String[0])); - sh.setParameterValuesToStatement(pstmt); - getLogger().log(Level.FINE, "DB -> {0}", sh.getQueryString()); - int result = pstmt.executeUpdate(); - genKeys = pstmt.getGeneratedKeys(); - RowId newId = getNewRowId(row, genKeys); - bufferedEvents.add(new RowIdChangeEvent(row.getId(), newId)); - return result; - } finally { - releaseConnection(connection, pstmt, genKeys); - } - } - - /** - * Fetches name(s) of primary key column(s) from DB metadata. - * - * Also tries to get the escape string to be used in search strings. - */ - private void fetchMetaData() { - Connection connection = null; - ResultSet rs = null; - ResultSet tables = null; - try { - connection = getConnection(); - DatabaseMetaData dbmd = connection.getMetaData(); - if (dbmd != null) { - tables = dbmd.getTables(catalogName, schemaName, tableName, - null); - if (!tables.next()) { - String catalog = (catalogName != null) - ? catalogName.toUpperCase() : null; - String schema = (schemaName != null) - ? schemaName.toUpperCase() : null; - tables = dbmd.getTables(catalog, schema, - tableName.toUpperCase(), null); - if (!tables.next()) { - throw new IllegalArgumentException( - "Table with the name \"" + getFullTableName() - + "\" was not found. Check your database contents."); - } else { - catalogName = catalog; - schemaName = schema; - tableName = tableName.toUpperCase(); - } - } - tables.close(); - rs = dbmd.getPrimaryKeys(catalogName, schemaName, tableName); - List<String> names = new ArrayList<String>(); - while (rs.next()) { - names.add(rs.getString("COLUMN_NAME")); - } - rs.close(); - if (!names.isEmpty()) { - primaryKeyColumns = names; - } - if (primaryKeyColumns == null || primaryKeyColumns.isEmpty()) { - throw new IllegalArgumentException( - "Primary key constraints have not been defined for the table \"" - + getFullTableName() - + "\". Use FreeFormQuery to access this table."); - } - for (String colName : primaryKeyColumns) { - if (colName.equalsIgnoreCase("rownum")) { - if (getSqlGenerator() instanceof MSSQLGenerator - || getSqlGenerator() instanceof MSSQLGenerator) { - throw new IllegalArgumentException( - "When using Oracle or MSSQL, a primary key column" - + " named \'rownum\' is not allowed!"); - } - } - } - } - } catch (SQLException e) { - throw new RuntimeException(e); - } finally { - try { - releaseConnection(connection, null, rs); - } catch (SQLException ignore) { - } finally { - try { - if (tables != null) { - tables.close(); - } - } catch (SQLException ignore) { - } - } - } - } - - private RowId getNewRowId(RowItem row, ResultSet genKeys) { - try { - /* Fetch primary key values and generate a map out of them. */ - Map<String, Object> values = new HashMap<String, Object>(); - ResultSetMetaData rsmd = genKeys.getMetaData(); - int colCount = rsmd.getColumnCount(); - if (genKeys.next()) { - for (int i = 1; i <= colCount; i++) { - values.put(rsmd.getColumnName(i), genKeys.getObject(i)); - } - } - /* Generate new RowId */ - List<Object> newRowId = new ArrayList<Object>(); - if (values.size() == 1) { - if (primaryKeyColumns.size() == 1) { - newRowId.add(values.get(values.keySet().iterator().next())); - } else { - for (String s : primaryKeyColumns) { - if (!((ColumnProperty) row.getItemProperty(s)) - .isReadOnlyChangeAllowed()) { - newRowId.add(values - .get(values.keySet().iterator().next())); - } else { - newRowId.add(values.get(s)); - } - } - } - } else { - for (String s : primaryKeyColumns) { - newRowId.add(values.get(s)); - } - } - return new RowId(newRowId.toArray()); - } catch (Exception e) { - getLogger().log(Level.FINE, - "Failed to fetch key values on insert: {0}", - e.getMessage()); - return null; - } - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.sqlcontainer.query.QueryDelegate#removeRow(com.vaadin - * .addon.sqlcontainer.RowItem) - */ - @Override - public boolean removeRow(RowItem row) - throws UnsupportedOperationException, SQLException { - if (getLogger().isLoggable(Level.FINE)) { - getLogger().log(Level.FINE, "Removing row with id: {0}", - row.getId().getId()[0]); - } - if (executeUpdate(sqlGenerator.generateDeleteQuery(getFullTableName(), - primaryKeyColumns, versionColumn, row)) == 1) { - return true; - } - if (versionColumn != null) { - throw new OptimisticLockException( - "Someone else changed the row that was being deleted.", - row.getId()); - } - return false; - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.sqlcontainer.query.QueryDelegate#containsRowWithKey( - * java.lang.Object[]) - */ - @Override - public boolean containsRowWithKey(Object... keys) throws SQLException { - ArrayList<Filter> filtersAndKeys = new ArrayList<Filter>(); - if (filters != null) { - filtersAndKeys.addAll(filters); - } - int ix = 0; - for (String colName : primaryKeyColumns) { - filtersAndKeys.add(new Equal(colName, keys[ix])); - ix++; - } - StatementHelper sh = sqlGenerator.generateSelectQuery( - getFullTableName(), filtersAndKeys, orderBys, 0, 0, "*"); - - boolean shouldCloseTransaction = false; - if (!isInTransaction()) { - shouldCloseTransaction = true; - beginTransaction(); - } - ResultSet rs = null; - try { - rs = executeQuery(sh); - boolean contains = rs.next(); - return contains; - } finally { - try { - if (rs != null) { - // Do not release connection, it is done in commit() - releaseConnection(null, rs.getStatement(), rs); - } - } finally { - if (shouldCloseTransaction) { - commit(); - } - } - } - } - - /** - * Custom writeObject to call rollback() if object is serialized. - */ - private void writeObject(java.io.ObjectOutputStream out) - throws IOException { - try { - rollback(); - } catch (SQLException ignored) { - } - out.defaultWriteObject(); - } - - /** - * Simple RowIdChangeEvent implementation. - */ - public static class RowIdChangeEvent extends EventObject - implements QueryDelegate.RowIdChangeEvent { - private final RowId oldId; - private final RowId newId; - - private RowIdChangeEvent(RowId oldId, RowId newId) { - super(oldId); - this.oldId = oldId; - this.newId = newId; - } - - @Override - public RowId getNewRowId() { - return newId; - } - - @Override - public RowId getOldRowId() { - return oldId; - } - } - - /** - * Adds RowIdChangeListener to this query - */ - @Override - public void addRowIdChangeListener(RowIdChangeListener listener) { - if (rowIdChangeListeners == null) { - rowIdChangeListeners = new LinkedList<QueryDelegate.RowIdChangeListener>(); - } - rowIdChangeListeners.add(listener); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #addRowIdChangeListener(com.vaadin.data.util.sqlcontainer.query.QueryDelegate.RowIdChangeListener)} - **/ - @Override - @Deprecated - public void addListener(RowIdChangeListener listener) { - addRowIdChangeListener(listener); - } - - /** - * Removes the given RowIdChangeListener from this query - */ - @Override - public void removeRowIdChangeListener(RowIdChangeListener listener) { - if (rowIdChangeListeners != null) { - rowIdChangeListeners.remove(listener); - } - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #removeRowIdChangeListener(com.vaadin.data.util.sqlcontainer.query.QueryDelegate.RowIdChangeListener)} - **/ - @Override - @Deprecated - public void removeListener(RowIdChangeListener listener) { - removeRowIdChangeListener(listener); - } - - private static final Logger getLogger() { - return Logger.getLogger(TableQuery.class.getName()); - } -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java deleted file mode 100644 index 9c05545e41..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer.query.generator; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.sqlcontainer.ColumnProperty; -import com.vaadin.data.util.sqlcontainer.RowItem; -import com.vaadin.data.util.sqlcontainer.SQLUtil; -import com.vaadin.data.util.sqlcontainer.TemporaryRowId; -import com.vaadin.data.util.sqlcontainer.query.OrderBy; -import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder; -import com.vaadin.data.util.sqlcontainer.query.generator.filter.StringDecorator; - -/** - * Generates generic SQL that is supported by HSQLDB, MySQL and PostgreSQL. - * - * @author Jonatan Kronqvist / Vaadin Ltd - */ -@SuppressWarnings("serial") -public class DefaultSQLGenerator implements SQLGenerator { - - private Class<? extends StatementHelper> statementHelperClass = null; - - public DefaultSQLGenerator() { - - } - - /** - * Create a new DefaultSqlGenerator instance that uses the given - * implementation of {@link StatementHelper} - * - * @param statementHelper - */ - public DefaultSQLGenerator( - Class<? extends StatementHelper> statementHelperClazz) { - this(); - statementHelperClass = statementHelperClazz; - } - - /** - * Construct a DefaultSQLGenerator with the specified identifiers for start - * and end of quoted strings. The identifiers may be different depending on - * the database engine and it's settings. - * - * @param quoteStart - * the identifier (character) denoting the start of a quoted - * string - * @param quoteEnd - * the identifier (character) denoting the end of a quoted string - */ - public DefaultSQLGenerator(String quoteStart, String quoteEnd) { - QueryBuilder - .setStringDecorator(new StringDecorator(quoteStart, quoteEnd)); - } - - /** - * Same as {@link #DefaultSQLGenerator(String, String)} but with support for - * custom {@link StatementHelper} implementation. - * - * @param quoteStart - * @param quoteEnd - * @param statementHelperClazz - */ - public DefaultSQLGenerator(String quoteStart, String quoteEnd, - Class<? extends StatementHelper> statementHelperClazz) { - this(quoteStart, quoteEnd); - statementHelperClass = statementHelperClazz; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.sqlcontainer.query.generator.SQLGenerator# - * generateSelectQuery(java.lang.String, java.util.List, java.util.List, - * int, int, java.lang.String) - */ - @Override - public StatementHelper generateSelectQuery(String tableName, - List<Filter> filters, List<OrderBy> orderBys, int offset, - int pagelength, String toSelect) { - if (tableName == null || tableName.trim().equals("")) { - throw new IllegalArgumentException("Table name must be given."); - } - toSelect = toSelect == null ? "*" : toSelect; - StatementHelper sh = getStatementHelper(); - StringBuffer query = new StringBuffer(); - query.append("SELECT " + toSelect + " FROM ") - .append(SQLUtil.escapeSQL(tableName)); - if (filters != null) { - query.append(QueryBuilder.getWhereStringForFilters(filters, sh)); - } - if (orderBys != null) { - for (OrderBy o : orderBys) { - generateOrderBy(query, o, orderBys.indexOf(o) == 0); - } - } - if (pagelength != 0) { - generateLimits(query, offset, pagelength); - } - sh.setQueryString(query.toString()); - return sh; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.sqlcontainer.query.generator.SQLGenerator# - * generateUpdateQuery(java.lang.String, - * com.vaadin.addon.sqlcontainer.RowItem) - */ - @Override - public StatementHelper generateUpdateQuery(String tableName, RowItem item) { - if (tableName == null || tableName.trim().equals("")) { - throw new IllegalArgumentException("Table name must be given."); - } - if (item == null) { - throw new IllegalArgumentException("Updated item must be given."); - } - StatementHelper sh = getStatementHelper(); - StringBuffer query = new StringBuffer(); - query.append("UPDATE ").append(tableName).append(" SET"); - - /* Generate column<->value and rowidentifiers map */ - Map<String, Object> columnToValueMap = generateColumnToValueMap(item); - Map<String, Object> rowIdentifiers = generateRowIdentifiers(item); - /* Generate columns and values to update */ - boolean first = true; - for (String column : columnToValueMap.keySet()) { - if (first) { - query.append(" " + QueryBuilder.quote(column) + " = ?"); - } else { - query.append(", " + QueryBuilder.quote(column) + " = ?"); - } - sh.addParameterValue(columnToValueMap.get(column), - item.getItemProperty(column).getType()); - first = false; - } - /* Generate identifiers for the row to be updated */ - first = true; - for (String column : rowIdentifiers.keySet()) { - if (first) { - query.append(" WHERE " + QueryBuilder.quote(column) + " = ?"); - } else { - query.append(" AND " + QueryBuilder.quote(column) + " = ?"); - } - sh.addParameterValue(rowIdentifiers.get(column), - item.getItemProperty(column).getType()); - first = false; - } - sh.setQueryString(query.toString()); - return sh; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.sqlcontainer.query.generator.SQLGenerator# - * generateInsertQuery(java.lang.String, - * com.vaadin.addon.sqlcontainer.RowItem) - */ - @Override - public StatementHelper generateInsertQuery(String tableName, RowItem item) { - if (tableName == null || tableName.trim().equals("")) { - throw new IllegalArgumentException("Table name must be given."); - } - if (item == null) { - throw new IllegalArgumentException("New item must be given."); - } - if (!(item.getId() instanceof TemporaryRowId)) { - throw new IllegalArgumentException( - "Cannot generate an insert query for item already in database."); - } - StatementHelper sh = getStatementHelper(); - StringBuffer query = new StringBuffer(); - query.append("INSERT INTO ").append(tableName).append(" ("); - - /* Generate column<->value map */ - Map<String, Object> columnToValueMap = generateColumnToValueMap(item); - /* Generate column names for insert query */ - boolean first = true; - for (String column : columnToValueMap.keySet()) { - if (!first) { - query.append(", "); - } - query.append(QueryBuilder.quote(column)); - first = false; - } - - /* Generate values for insert query */ - query.append(") VALUES ("); - first = true; - for (String column : columnToValueMap.keySet()) { - if (!first) { - query.append(", "); - } - query.append("?"); - sh.addParameterValue(columnToValueMap.get(column), - item.getItemProperty(column).getType()); - first = false; - } - query.append(")"); - sh.setQueryString(query.toString()); - return sh; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.sqlcontainer.query.generator.SQLGenerator# - * generateDeleteQuery(java.lang.String, - * com.vaadin.addon.sqlcontainer.RowItem) - */ - @Override - public StatementHelper generateDeleteQuery(String tableName, - List<String> primaryKeyColumns, String versionColumn, - RowItem item) { - if (tableName == null || tableName.trim().equals("")) { - throw new IllegalArgumentException("Table name must be given."); - } - if (item == null) { - throw new IllegalArgumentException( - "Item to be deleted must be given."); - } - if (primaryKeyColumns == null || primaryKeyColumns.isEmpty()) { - throw new IllegalArgumentException( - "Valid keyColumnNames must be provided."); - } - StatementHelper sh = getStatementHelper(); - StringBuffer query = new StringBuffer(); - query.append("DELETE FROM ").append(tableName).append(" WHERE "); - int count = 1; - for (String keyColName : primaryKeyColumns) { - if ((this instanceof MSSQLGenerator - || this instanceof OracleGenerator) - && keyColName.equalsIgnoreCase("rownum")) { - count++; - continue; - } - if (count > 1) { - query.append(" AND "); - } - if (item.getItemProperty(keyColName).getValue() != null) { - query.append(QueryBuilder.quote(keyColName) + " = ?"); - sh.addParameterValue( - item.getItemProperty(keyColName).getValue(), - item.getItemProperty(keyColName).getType()); - } - count++; - } - if (versionColumn != null) { - if (!item.getItemPropertyIds().contains(versionColumn)) { - throw new IllegalArgumentException(String.format( - "Table '%s' does not contain version column '%s'.", - tableName, versionColumn)); - } - - query.append(String.format(" AND %s = ?", - QueryBuilder.quote(versionColumn))); - sh.addParameterValue(item.getItemProperty(versionColumn).getValue(), - item.getItemProperty(versionColumn).getType()); - } - - sh.setQueryString(query.toString()); - return sh; - } - - /** - * Generates sorting rules as an ORDER BY -clause - * - * @param sb - * StringBuffer to which the clause is appended. - * @param o - * OrderBy object to be added into the sb. - * @param firstOrderBy - * If true, this is the first OrderBy. - * @return - */ - protected StringBuffer generateOrderBy(StringBuffer sb, OrderBy o, - boolean firstOrderBy) { - if (firstOrderBy) { - sb.append(" ORDER BY "); - } else { - sb.append(", "); - } - sb.append(QueryBuilder.quote(o.getColumn())); - if (o.isAscending()) { - sb.append(" ASC"); - } else { - sb.append(" DESC"); - } - return sb; - } - - /** - * Generates the LIMIT and OFFSET clause. - * - * @param sb - * StringBuffer to which the clause is appended. - * @param offset - * Value for offset. - * @param pagelength - * Value for pagelength. - * @return StringBuffer with LIMIT and OFFSET clause added. - */ - protected StringBuffer generateLimits(StringBuffer sb, int offset, - int pagelength) { - sb.append(" LIMIT ").append(pagelength).append(" OFFSET ") - .append(offset); - return sb; - } - - protected Map<String, Object> generateColumnToValueMap(RowItem item) { - Map<String, Object> columnToValueMap = new HashMap<String, Object>(); - for (Object id : item.getItemPropertyIds()) { - ColumnProperty cp = (ColumnProperty) item.getItemProperty(id); - /* Prevent "rownum" usage as a column name if MSSQL or ORACLE */ - if ((this instanceof MSSQLGenerator - || this instanceof OracleGenerator) - && cp.getPropertyId().equalsIgnoreCase("rownum")) { - continue; - } - if (cp.isPersistent()) { - columnToValueMap.put(cp.getPropertyId(), cp.getValue()); - } - } - return columnToValueMap; - } - - protected Map<String, Object> generateRowIdentifiers(RowItem item) { - Map<String, Object> rowIdentifiers = new HashMap<String, Object>(); - for (Object id : item.getItemPropertyIds()) { - ColumnProperty cp = (ColumnProperty) item.getItemProperty(id); - /* Prevent "rownum" usage as a column name if MSSQL or ORACLE */ - if ((this instanceof MSSQLGenerator - || this instanceof OracleGenerator) - && cp.getPropertyId().equalsIgnoreCase("rownum")) { - continue; - } - - if (cp.isRowIdentifier()) { - Object value; - if (cp.isPrimaryKey()) { - // If the value of a primary key has changed, its old value - // should be used to identify the row (#9145) - value = cp.getOldValue(); - } else { - value = cp.getValue(); - } - rowIdentifiers.put(cp.getPropertyId(), value); - } - } - return rowIdentifiers; - } - - /** - * Returns the statement helper for the generator. Override this to handle - * platform specific data types. - * - * @see http://dev.vaadin.com/ticket/9148 - * @return a new instance of the statement helper - */ - protected StatementHelper getStatementHelper() { - if (statementHelperClass == null) { - return new StatementHelper(); - } - - try { - return statementHelperClass.newInstance(); - } catch (InstantiationException e) { - throw new RuntimeException( - "Unable to instantiate custom StatementHelper", e); - } catch (IllegalAccessException e) { - throw new RuntimeException( - "Unable to instantiate custom StatementHelper", e); - } - } - -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/MSSQLGenerator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/MSSQLGenerator.java deleted file mode 100644 index baddc60e3f..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/MSSQLGenerator.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer.query.generator; - -import java.util.List; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.sqlcontainer.query.OrderBy; -import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder; - -@SuppressWarnings("serial") -public class MSSQLGenerator extends DefaultSQLGenerator { - - public MSSQLGenerator() { - - } - - /** - * Construct a MSSQLGenerator with the specified identifiers for start and - * end of quoted strings. The identifiers may be different depending on the - * database engine and it's settings. - * - * @param quoteStart - * the identifier (character) denoting the start of a quoted - * string - * @param quoteEnd - * the identifier (character) denoting the end of a quoted string - */ - public MSSQLGenerator(String quoteStart, String quoteEnd) { - super(quoteStart, quoteEnd); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.sqlcontainer.query.generator.DefaultSQLGenerator# - * generateSelectQuery(java.lang.String, java.util.List, - * com.vaadin.addon.sqlcontainer.query.FilteringMode, java.util.List, int, - * int, java.lang.String) - */ - @Override - public StatementHelper generateSelectQuery(String tableName, - List<Filter> filters, List<OrderBy> orderBys, int offset, - int pagelength, String toSelect) { - if (tableName == null || tableName.trim().equals("")) { - throw new IllegalArgumentException("Table name must be given."); - } - /* Adjust offset and page length parameters to match "row numbers" */ - offset = pagelength > 1 ? ++offset : offset; - pagelength = pagelength > 1 ? --pagelength : pagelength; - toSelect = toSelect == null ? "*" : toSelect; - StatementHelper sh = getStatementHelper(); - StringBuffer query = new StringBuffer(); - - /* Row count request is handled here */ - if ("COUNT(*)".equalsIgnoreCase(toSelect)) { - query.append(String.format( - "SELECT COUNT(*) AS %s FROM (SELECT * FROM %s", - QueryBuilder.quote("rowcount"), tableName)); - if (filters != null && !filters.isEmpty()) { - query.append( - QueryBuilder.getWhereStringForFilters(filters, sh)); - } - query.append(") AS t"); - sh.setQueryString(query.toString()); - return sh; - } - - /* SELECT without row number constraints */ - if (offset == 0 && pagelength == 0) { - query.append("SELECT ").append(toSelect).append(" FROM ") - .append(tableName); - if (filters != null) { - query.append( - QueryBuilder.getWhereStringForFilters(filters, sh)); - } - if (orderBys != null) { - for (OrderBy o : orderBys) { - generateOrderBy(query, o, orderBys.indexOf(o) == 0); - } - } - sh.setQueryString(query.toString()); - return sh; - } - - /* Remaining SELECT cases are handled here */ - query.append("SELECT * FROM (SELECT row_number() OVER ("); - if (orderBys != null) { - for (OrderBy o : orderBys) { - generateOrderBy(query, o, orderBys.indexOf(o) == 0); - } - } - query.append(") AS rownum, " + toSelect + " FROM ").append(tableName); - if (filters != null) { - query.append(QueryBuilder.getWhereStringForFilters(filters, sh)); - } - query.append(") AS a WHERE a.rownum BETWEEN ").append(offset) - .append(" AND ").append(Integer.toString(offset + pagelength)); - sh.setQueryString(query.toString()); - return sh; - } -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/OracleGenerator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/OracleGenerator.java deleted file mode 100644 index 0097b5017c..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/OracleGenerator.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer.query.generator; - -import java.util.List; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.sqlcontainer.query.OrderBy; -import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder; - -@SuppressWarnings("serial") -public class OracleGenerator extends DefaultSQLGenerator { - - public OracleGenerator() { - - } - - public OracleGenerator( - Class<? extends StatementHelper> statementHelperClazz) { - super(statementHelperClazz); - } - - /** - * Construct an OracleSQLGenerator with the specified identifiers for start - * and end of quoted strings. The identifiers may be different depending on - * the database engine and it's settings. - * - * @param quoteStart - * the identifier (character) denoting the start of a quoted - * string - * @param quoteEnd - * the identifier (character) denoting the end of a quoted string - */ - public OracleGenerator(String quoteStart, String quoteEnd) { - super(quoteStart, quoteEnd); - } - - public OracleGenerator(String quoteStart, String quoteEnd, - Class<? extends StatementHelper> statementHelperClazz) { - super(quoteStart, quoteEnd, statementHelperClazz); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.sqlcontainer.query.generator.DefaultSQLGenerator# - * generateSelectQuery(java.lang.String, java.util.List, - * com.vaadin.addon.sqlcontainer.query.FilteringMode, java.util.List, int, - * int, java.lang.String) - */ - @Override - public StatementHelper generateSelectQuery(String tableName, - List<Filter> filters, List<OrderBy> orderBys, int offset, - int pagelength, String toSelect) { - if (tableName == null || tableName.trim().equals("")) { - throw new IllegalArgumentException("Table name must be given."); - } - /* Adjust offset and page length parameters to match "row numbers" */ - offset = pagelength > 1 ? ++offset : offset; - pagelength = pagelength > 1 ? --pagelength : pagelength; - toSelect = toSelect == null ? "*" : toSelect; - StatementHelper sh = getStatementHelper(); - StringBuffer query = new StringBuffer(); - - /* Row count request is handled here */ - if ("COUNT(*)".equalsIgnoreCase(toSelect)) { - query.append(String.format( - "SELECT COUNT(*) AS %s FROM (SELECT * FROM %s", - QueryBuilder.quote("rowcount"), tableName)); - if (filters != null && !filters.isEmpty()) { - query.append( - QueryBuilder.getWhereStringForFilters(filters, sh)); - } - query.append(")"); - sh.setQueryString(query.toString()); - return sh; - } - - /* SELECT without row number constraints */ - if (offset == 0 && pagelength == 0) { - query.append("SELECT ").append(toSelect).append(" FROM ") - .append(tableName); - if (filters != null) { - query.append( - QueryBuilder.getWhereStringForFilters(filters, sh)); - } - if (orderBys != null) { - for (OrderBy o : orderBys) { - generateOrderBy(query, o, orderBys.indexOf(o) == 0); - } - } - sh.setQueryString(query.toString()); - return sh; - } - - /* Remaining SELECT cases are handled here */ - query.append(String.format( - "SELECT * FROM (SELECT x.*, ROWNUM AS %s FROM (SELECT %s FROM %s", - QueryBuilder.quote("rownum"), toSelect, tableName)); - if (filters != null) { - query.append(QueryBuilder.getWhereStringForFilters(filters, sh)); - } - if (orderBys != null) { - for (OrderBy o : orderBys) { - generateOrderBy(query, o, orderBys.indexOf(o) == 0); - } - } - query.append(String.format(") x) WHERE %s BETWEEN %d AND %d", - QueryBuilder.quote("rownum"), offset, offset + pagelength)); - sh.setQueryString(query.toString()); - return sh; - } - -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/SQLGenerator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/SQLGenerator.java deleted file mode 100644 index 6011346b78..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/SQLGenerator.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer.query.generator; - -import java.io.Serializable; -import java.util.List; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.sqlcontainer.RowItem; -import com.vaadin.data.util.sqlcontainer.query.OrderBy; - -/** - * The SQLGenerator interface is meant to be implemented for each different SQL - * syntax that is to be supported. By default there are implementations for - * HSQLDB, MySQL, PostgreSQL, MSSQL and Oracle syntaxes. - * - * @author Jonatan Kronqvist / Vaadin Ltd - */ -public interface SQLGenerator extends Serializable { - /** - * Generates a SELECT query with the provided parameters. Uses default - * filtering mode (INCLUSIVE). - * - * @param tableName - * Name of the table queried - * @param filters - * The filters, converted into a WHERE clause - * @param orderBys - * The the ordering conditions, converted into an ORDER BY clause - * @param offset - * The offset of the first row to be included - * @param pagelength - * The number of rows to be returned when the query executes - * @param toSelect - * String containing what to select, e.g. "*", "COUNT(*)" - * @return StatementHelper instance containing the query string for a - * PreparedStatement and the values required for the parameters - */ - public StatementHelper generateSelectQuery(String tableName, - List<Filter> filters, List<OrderBy> orderBys, int offset, - int pagelength, String toSelect); - - /** - * Generates an UPDATE query with the provided parameters. - * - * @param tableName - * Name of the table queried - * @param item - * RowItem containing the updated values update. - * @return StatementHelper instance containing the query string for a - * PreparedStatement and the values required for the parameters - */ - public StatementHelper generateUpdateQuery(String tableName, RowItem item); - - /** - * Generates an INSERT query for inserting a new row with the provided - * values. - * - * @param tableName - * Name of the table queried - * @param item - * New RowItem to be inserted into the database. - * @return StatementHelper instance containing the query string for a - * PreparedStatement and the values required for the parameters - */ - public StatementHelper generateInsertQuery(String tableName, RowItem item); - - /** - * Generates a DELETE query for deleting data related to the given RowItem - * from the database. - * - * @param tableName - * Name of the table queried - * @param primaryKeyColumns - * the names of the columns holding the primary key. Usually just - * one column, but might be several. - * @param versionColumn - * the column containing the version number of the row, null if - * versioning (optimistic locking) not enabled. - * @param item - * Item to be deleted from the database - * @return StatementHelper instance containing the query string for a - * PreparedStatement and the values required for the parameters - */ - public StatementHelper generateDeleteQuery(String tableName, - List<String> primaryKeyColumns, String versionColumn, RowItem item); -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java deleted file mode 100644 index 43cfb597bb..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer.query.generator; - -import java.io.Serializable; -import java.math.BigDecimal; -import java.sql.Date; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Time; -import java.sql.Timestamp; -import java.sql.Types; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * StatementHelper is a simple helper class that assists TableQuery and the - * query generators in filling a PreparedStatement. The actual statement is - * generated by the query generator methods, but the resulting statement and all - * the parameter values are stored in an instance of StatementHelper. - * - * This class will also fill the values with correct setters into the - * PreparedStatement on request. - */ -public class StatementHelper implements Serializable { - - private String queryString; - - private List<Object> parameters = new ArrayList<Object>(); - private Map<Integer, Class<?>> dataTypes = new HashMap<Integer, Class<?>>(); - - public StatementHelper() { - } - - public void setQueryString(String queryString) { - this.queryString = queryString; - } - - public String getQueryString() { - return queryString; - } - - public void addParameterValue(Object parameter) { - if (parameter != null) { - parameters.add(parameter); - dataTypes.put(parameters.size() - 1, parameter.getClass()); - } else { - throw new IllegalArgumentException( - "You cannot add null parameters using addParamaters(Object). " - + "Use addParameters(Object,Class) instead"); - } - } - - public void addParameterValue(Object parameter, Class<?> type) { - parameters.add(parameter); - dataTypes.put(parameters.size() - 1, type); - } - - public void setParameterValuesToStatement(PreparedStatement pstmt) - throws SQLException { - for (int i = 0; i < parameters.size(); i++) { - if (parameters.get(i) == null) { - handleNullValue(i, pstmt); - } else { - pstmt.setObject(i + 1, parameters.get(i)); - } - } - - /* - * The following list contains the data types supported by - * PreparedStatement but not supported by SQLContainer: - * - * [The list is provided as PreparedStatement method signatures] - * - * setNCharacterStream(int parameterIndex, Reader value) - * - * setNClob(int parameterIndex, NClob value) - * - * setNString(int parameterIndex, String value) - * - * setRef(int parameterIndex, Ref x) - * - * setRowId(int parameterIndex, RowId x) - * - * setSQLXML(int parameterIndex, SQLXML xmlObject) - * - * setBytes(int parameterIndex, byte[] x) - * - * setCharacterStream(int parameterIndex, Reader reader) - * - * setClob(int parameterIndex, Clob x) - * - * setURL(int parameterIndex, URL x) - * - * setArray(int parameterIndex, Array x) - * - * setAsciiStream(int parameterIndex, InputStream x) - * - * setBinaryStream(int parameterIndex, InputStream x) - * - * setBlob(int parameterIndex, Blob x) - */ - } - - private void handleNullValue(int i, PreparedStatement pstmt) - throws SQLException { - Class<?> dataType = dataTypes.get(i); - int index = i + 1; - if (BigDecimal.class.equals(dataType)) { - pstmt.setBigDecimal(index, null); - } else if (Boolean.class.equals(dataType)) { - pstmt.setNull(index, Types.BOOLEAN); - } else if (Byte.class.equals(dataType)) { - pstmt.setNull(index, Types.SMALLINT); - } else if (Date.class.equals(dataType)) { - pstmt.setDate(index, null); - } else if (Double.class.equals(dataType)) { - pstmt.setNull(index, Types.DOUBLE); - } else if (Float.class.equals(dataType)) { - pstmt.setNull(index, Types.FLOAT); - } else if (Integer.class.equals(dataType)) { - pstmt.setNull(index, Types.INTEGER); - } else if (Long.class.equals(dataType)) { - pstmt.setNull(index, Types.BIGINT); - } else if (Short.class.equals(dataType)) { - pstmt.setNull(index, Types.SMALLINT); - } else if (String.class.equals(dataType)) { - pstmt.setString(index, null); - } else if (Time.class.equals(dataType)) { - pstmt.setTime(index, null); - } else if (Timestamp.class.equals(dataType)) { - pstmt.setTimestamp(index, null); - } else if (byte[].class.equals(dataType)) { - pstmt.setBytes(index, null); - } else { - - if (handleUnrecognizedTypeNullValue(i, pstmt, dataTypes)) { - return; - } - - throw new SQLException("Data type for parameter " + i - + " not supported by SQLContainer: " + dataType.getName()); - } - } - - /** - * Handle unrecognized null values. Override this to handle null values for - * platform specific data types that are not handled by the default - * implementation of the {@link StatementHelper}. - * - * @param i - * @param pstmt - * @param dataTypes2 - * - * @return true if handled, false otherwise - * - * @see {@link http://dev.vaadin.com/ticket/9148} - */ - protected boolean handleUnrecognizedTypeNullValue(int i, - PreparedStatement pstmt, Map<Integer, Class<?>> dataTypes) - throws SQLException { - return false; - } -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/AndTranslator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/AndTranslator.java deleted file mode 100644 index 6eab9f5596..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/AndTranslator.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer.query.generator.filter; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.filter.And; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; - -public class AndTranslator implements FilterTranslator { - - @Override - public boolean translatesFilter(Filter filter) { - return filter instanceof And; - } - - @Override - public String getWhereStringForFilter(Filter filter, StatementHelper sh) { - return QueryBuilder.group(QueryBuilder - .getJoinedFilterString(((And) filter).getFilters(), "AND", sh)); - } - -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/BetweenTranslator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/BetweenTranslator.java deleted file mode 100644 index 2cdecd1e6d..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/BetweenTranslator.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer.query.generator.filter; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.filter.Between; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; - -public class BetweenTranslator implements FilterTranslator { - - @Override - public boolean translatesFilter(Filter filter) { - return filter instanceof Between; - } - - @Override - public String getWhereStringForFilter(Filter filter, StatementHelper sh) { - Between between = (Between) filter; - sh.addParameterValue(between.getStartValue()); - sh.addParameterValue(between.getEndValue()); - return QueryBuilder.quote(between.getPropertyId()) + " BETWEEN ? AND ?"; - } - -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/CompareTranslator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/CompareTranslator.java deleted file mode 100644 index bcb348dc8a..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/CompareTranslator.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer.query.generator.filter; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.filter.Compare; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; - -public class CompareTranslator implements FilterTranslator { - - @Override - public boolean translatesFilter(Filter filter) { - return filter instanceof Compare; - } - - @Override - public String getWhereStringForFilter(Filter filter, StatementHelper sh) { - Compare compare = (Compare) filter; - sh.addParameterValue(compare.getValue()); - String prop = QueryBuilder.quote(compare.getPropertyId()); - switch (compare.getOperation()) { - case EQUAL: - return prop + " = ?"; - case GREATER: - return prop + " > ?"; - case GREATER_OR_EQUAL: - return prop + " >= ?"; - case LESS: - return prop + " < ?"; - case LESS_OR_EQUAL: - return prop + " <= ?"; - default: - return ""; - } - } - -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/FilterTranslator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/FilterTranslator.java deleted file mode 100644 index e593146550..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/FilterTranslator.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer.query.generator.filter; - -import java.io.Serializable; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; - -public interface FilterTranslator extends Serializable { - public boolean translatesFilter(Filter filter); - - public String getWhereStringForFilter(Filter filter, StatementHelper sh); - -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/IsNullTranslator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/IsNullTranslator.java deleted file mode 100644 index dd7a90828a..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/IsNullTranslator.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer.query.generator.filter; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.filter.IsNull; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; - -public class IsNullTranslator implements FilterTranslator { - - @Override - public boolean translatesFilter(Filter filter) { - return filter instanceof IsNull; - } - - @Override - public String getWhereStringForFilter(Filter filter, StatementHelper sh) { - IsNull in = (IsNull) filter; - return QueryBuilder.quote(in.getPropertyId()) + " IS NULL"; - } -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/LikeTranslator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/LikeTranslator.java deleted file mode 100644 index 3c27240e9e..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/LikeTranslator.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer.query.generator.filter; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.filter.Like; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; - -public class LikeTranslator implements FilterTranslator { - - @Override - public boolean translatesFilter(Filter filter) { - return filter instanceof Like; - } - - @Override - public String getWhereStringForFilter(Filter filter, StatementHelper sh) { - Like like = (Like) filter; - if (like.isCaseSensitive()) { - sh.addParameterValue(like.getValue()); - return QueryBuilder.quote(like.getPropertyId()) + " LIKE ?"; - } else { - sh.addParameterValue(like.getValue().toUpperCase()); - return "UPPER(" + QueryBuilder.quote(like.getPropertyId()) - + ") LIKE ?"; - } - } - -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/NotTranslator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/NotTranslator.java deleted file mode 100644 index fe98ca24b6..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/NotTranslator.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer.query.generator.filter; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.filter.IsNull; -import com.vaadin.data.util.filter.Not; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; - -public class NotTranslator implements FilterTranslator { - - @Override - public boolean translatesFilter(Filter filter) { - return filter instanceof Not; - } - - @Override - public String getWhereStringForFilter(Filter filter, StatementHelper sh) { - Not not = (Not) filter; - if (not.getFilter() instanceof IsNull) { - IsNull in = (IsNull) not.getFilter(); - return QueryBuilder.quote(in.getPropertyId()) + " IS NOT NULL"; - } - return "NOT " - + QueryBuilder.getWhereStringForFilter(not.getFilter(), sh); - } - -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/OrTranslator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/OrTranslator.java deleted file mode 100644 index 2f30acc89f..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/OrTranslator.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer.query.generator.filter; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.filter.Or; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; - -public class OrTranslator implements FilterTranslator { - - @Override - public boolean translatesFilter(Filter filter) { - return filter instanceof Or; - } - - @Override - public String getWhereStringForFilter(Filter filter, StatementHelper sh) { - return QueryBuilder.group(QueryBuilder - .getJoinedFilterString(((Or) filter).getFilters(), "OR", sh)); - } - -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/QueryBuilder.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/QueryBuilder.java deleted file mode 100644 index b8fb306076..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/QueryBuilder.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer.query.generator.filter; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; - -public class QueryBuilder implements Serializable { - - private static ArrayList<FilterTranslator> filterTranslators = new ArrayList<FilterTranslator>(); - private static StringDecorator stringDecorator = new StringDecorator("\"", - "\""); - - static { - /* Register all default filter translators */ - addFilterTranslator(new AndTranslator()); - addFilterTranslator(new OrTranslator()); - addFilterTranslator(new LikeTranslator()); - addFilterTranslator(new BetweenTranslator()); - addFilterTranslator(new CompareTranslator()); - addFilterTranslator(new NotTranslator()); - addFilterTranslator(new IsNullTranslator()); - addFilterTranslator(new SimpleStringTranslator()); - } - - public synchronized static void addFilterTranslator( - FilterTranslator translator) { - filterTranslators.add(translator); - } - - /** - * Allows specification of a custom ColumnQuoter instance that handles - * quoting of column names for the current DB dialect. - * - * @param decorator - * the ColumnQuoter instance to use. - */ - public static void setStringDecorator(StringDecorator decorator) { - stringDecorator = decorator; - } - - public static String quote(Object str) { - return stringDecorator.quote(str); - } - - public static String group(String str) { - return stringDecorator.group(str); - } - - /** - * Constructs and returns a string representing the filter that can be used - * in a WHERE clause. - * - * @param filter - * the filter to translate - * @param sh - * the statement helper to update with the value(s) of the filter - * @return a string representing the filter. - */ - public synchronized static String getWhereStringForFilter(Filter filter, - StatementHelper sh) { - for (FilterTranslator ft : filterTranslators) { - if (ft.translatesFilter(filter)) { - return ft.getWhereStringForFilter(filter, sh); - } - } - return ""; - } - - public static String getJoinedFilterString(Collection<Filter> filters, - String joinString, StatementHelper sh) { - StringBuilder result = new StringBuilder(); - for (Filter f : filters) { - result.append(getWhereStringForFilter(f, sh)); - result.append(" ").append(joinString).append(" "); - } - // Remove the last instance of joinString - result.delete(result.length() - joinString.length() - 2, - result.length()); - return result.toString(); - } - - public static String getWhereStringForFilters(List<Filter> filters, - StatementHelper sh) { - if (filters == null || filters.isEmpty()) { - return ""; - } - StringBuilder where = new StringBuilder(" WHERE "); - where.append(getJoinedFilterString(filters, "AND", sh)); - return where.toString(); - } -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/SimpleStringTranslator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/SimpleStringTranslator.java deleted file mode 100644 index 312adc5ed7..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/SimpleStringTranslator.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer.query.generator.filter; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.filter.Like; -import com.vaadin.data.util.filter.SimpleStringFilter; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; - -public class SimpleStringTranslator implements FilterTranslator { - - @Override - public boolean translatesFilter(Filter filter) { - return filter instanceof SimpleStringFilter; - } - - @Override - public String getWhereStringForFilter(Filter filter, StatementHelper sh) { - SimpleStringFilter ssf = (SimpleStringFilter) filter; - // Create a Like filter based on the SimpleStringFilter and execute the - // LikeTranslator - String likeStr = ssf.isOnlyMatchPrefix() ? ssf.getFilterString() + "%" - : "%" + ssf.getFilterString() + "%"; - Like like = new Like(ssf.getPropertyId().toString(), likeStr); - like.setCaseSensitive(!ssf.isIgnoreCase()); - return new LikeTranslator().getWhereStringForFilter(like, sh); - } - -} diff --git a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/StringDecorator.java b/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/StringDecorator.java deleted file mode 100644 index f8005f4290..0000000000 --- a/server/src/main/java/com/vaadin/data/util/sqlcontainer/query/generator/filter/StringDecorator.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.sqlcontainer.query.generator.filter; - -import java.io.Serializable; - -/** - * The StringDecorator knows how to produce a quoted string using the specified - * quote start and quote end characters. It also handles grouping of a string - * (surrounding it in parenthesis). - * - * Extend this class if you need to support special characters for grouping - * (parenthesis). - * - * @author Vaadin Ltd - */ -public class StringDecorator implements Serializable { - - private final String quoteStart; - private final String quoteEnd; - - /** - * Constructs a StringDecorator that uses the quoteStart and quoteEnd - * characters to create quoted strings. - * - * @param quoteStart - * the character denoting the start of a quote. - * @param quoteEnd - * the character denoting the end of a quote. - */ - public StringDecorator(String quoteStart, String quoteEnd) { - this.quoteStart = quoteStart; - this.quoteEnd = quoteEnd; - } - - /** - * Surround a string with quote characters. - * - * @param str - * the string to quote - * @return the quoted string - */ - public String quote(Object str) { - return quoteStart + str + quoteEnd; - } - - /** - * Groups a string by surrounding it in parenthesis - * - * @param str - * the string to group - * @return the grouped string - */ - public String group(String str) { - return "(" + str + ")"; - } -} diff --git a/server/src/main/java/com/vaadin/event/dd/DragSource.java b/server/src/main/java/com/vaadin/event/dd/DragSource.java index 07f8dd43aa..bf5983e502 100644 --- a/server/src/main/java/com/vaadin/event/dd/DragSource.java +++ b/server/src/main/java/com/vaadin/event/dd/DragSource.java @@ -20,7 +20,6 @@ import java.util.Map; import com.vaadin.event.Transferable; import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; import com.vaadin.ui.Component; -import com.vaadin.ui.Tree; /** * DragSource is a {@link Component} that builds a {@link Transferable} for a @@ -48,7 +47,7 @@ public interface DragSource extends Component { * the client side. Vaadin developer don't and can't know anything about * these generated keys, only about item identifiers. When tree node is * dragged client puts that key to {@link Transferable}s client side - * counterpart. In {@link Tree#getTransferable(Map)} the key is converted + * counterpart. In {@code Tree.getTransferable(Map)} the key is converted * back to item identifier that the server side developer can use. * <p> * diff --git a/server/src/main/java/com/vaadin/event/dd/TargetDetails.java b/server/src/main/java/com/vaadin/event/dd/TargetDetails.java index 7a51f8f3b7..b30d902dce 100644 --- a/server/src/main/java/com/vaadin/event/dd/TargetDetails.java +++ b/server/src/main/java/com/vaadin/event/dd/TargetDetails.java @@ -17,15 +17,13 @@ package com.vaadin.event.dd; import java.io.Serializable; -import com.vaadin.ui.Tree.TreeTargetDetails; - /** * TargetDetails wraps drop target related information about * {@link DragAndDropEvent}. * <p> * When a TargetDetails object is used in {@link DropHandler} it is often * preferable to cast the TargetDetails to an implementation provided by - * DropTarget like {@link TreeTargetDetails}. They often provide a better typed, + * DropTarget like {@code TreeTargetDetails}. They often provide a better typed, * drop target specific API. * * @since 6.3 diff --git a/server/src/main/java/com/vaadin/ui/AbstractColorPicker.java b/server/src/main/java/com/vaadin/ui/AbstractColorPicker.java deleted file mode 100644 index d7d12c6d03..0000000000 --- a/server/src/main/java/com/vaadin/ui/AbstractColorPicker.java +++ /dev/null @@ -1,588 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui; - -import java.io.Serializable; -import java.lang.reflect.Method; -import java.util.Collection; - -import org.jsoup.nodes.Attributes; -import org.jsoup.nodes.Element; - -import com.vaadin.shared.ui.colorpicker.Color; -import com.vaadin.shared.ui.colorpicker.ColorPickerServerRpc; -import com.vaadin.shared.ui.colorpicker.ColorPickerState; -import com.vaadin.ui.Window.CloseEvent; -import com.vaadin.ui.Window.CloseListener; -import com.vaadin.ui.components.colorpicker.ColorChangeEvent; -import com.vaadin.ui.components.colorpicker.ColorChangeListener; -import com.vaadin.ui.components.colorpicker.ColorPickerPopup; -import com.vaadin.ui.components.colorpicker.ColorSelector; -import com.vaadin.ui.declarative.DesignAttributeHandler; -import com.vaadin.ui.declarative.DesignContext; - -/** - * An abstract class that defines default implementation for a color picker - * component. - * - * @since 7.0.0 - */ -public abstract class AbstractColorPicker extends AbstractComponent - implements CloseListener, ColorSelector { - private static final Method COLOR_CHANGE_METHOD; - static { - try { - COLOR_CHANGE_METHOD = ColorChangeListener.class.getDeclaredMethod( - "colorChanged", new Class[] { ColorChangeEvent.class }); - } catch (final java.lang.NoSuchMethodException e) { - // This should never happen - throw new java.lang.RuntimeException( - "Internal error finding methods in ColorPicker"); - } - } - - /** - * Interface for converting 2d-coordinates to a Color - */ - public interface Coordinates2Color extends Serializable { - - /** - * Calculate color from coordinates - * - * @param x - * the x-coordinate - * @param y - * the y-coordinate - * - * @return the color - */ - public Color calculate(int x, int y); - - /** - * Calculate coordinates from color - * - * @param c - * the c - * - * @return the integer array with the coordinates - */ - public int[] calculate(Color c); - } - - public enum PopupStyle { - POPUP_NORMAL("normal"), POPUP_SIMPLE("simple"); - - private String style; - - PopupStyle(String styleName) { - style = styleName; - } - - @Override - public String toString() { - return style; - } - } - - private ColorPickerServerRpc rpc = new ColorPickerServerRpc() { - - @Override - public void openPopup(boolean open) { - showPopup(open); - } - }; - - protected static final String STYLENAME_DEFAULT = "v-colorpicker"; - protected static final String STYLENAME_BUTTON = "v-button"; - protected static final String STYLENAME_AREA = "v-colorpicker-area"; - - protected PopupStyle popupStyle = PopupStyle.POPUP_NORMAL; - - /** The popup window. */ - private ColorPickerPopup window; - - /** The color. */ - protected Color color; - - /** The UI. */ - private UI parent; - - protected String popupCaption = null; - private int positionX = 0; - private int positionY = 0; - - protected boolean rgbVisible = true; - protected boolean hsvVisible = true; - protected boolean swatchesVisible = true; - protected boolean historyVisible = true; - protected boolean textfieldVisible = true; - - /** - * Instantiates a new color picker. - */ - public AbstractColorPicker() { - this("Colors", Color.WHITE); - } - - /** - * Instantiates a new color picker. - * - * @param popupCaption - * the caption of the popup window - */ - public AbstractColorPicker(String popupCaption) { - this(popupCaption, Color.WHITE); - } - - /** - * Instantiates a new color picker. - * - * @param popupCaption - * the caption of the popup window - * @param initialColor - * the initial color - */ - public AbstractColorPicker(String popupCaption, Color initialColor) { - super(); - registerRpc(rpc); - setColor(initialColor); - this.popupCaption = popupCaption; - setDefaultStyles(); - setCaption(""); - } - - @Override - public void setColor(Color color) { - this.color = color; - - if (window != null) { - window.setColor(color); - } - getState().color = color.getCSS(); - } - - @Override - public Color getColor() { - return color; - } - - /** - * Set true if the component should show a default caption (css-code for the - * currently selected color, e.g. #ffffff) when no other caption is - * available. - * - * @param enabled - */ - public void setDefaultCaptionEnabled(boolean enabled) { - getState().showDefaultCaption = enabled; - } - - /** - * Returns true if the component shows the default caption (css-code for the - * currently selected color, e.g. #ffffff) if no other caption is available. - */ - public boolean isDefaultCaptionEnabled() { - return getState(false).showDefaultCaption; - } - - /** - * Sets the position of the popup window - * - * @param x - * the x-coordinate - * @param y - * the y-coordinate - */ - public void setPosition(int x, int y) { - positionX = x; - positionY = y; - - if (window != null) { - window.setPositionX(x); - window.setPositionY(y); - } - } - - @Override - public void addColorChangeListener(ColorChangeListener listener) { - addListener(ColorChangeEvent.class, listener, COLOR_CHANGE_METHOD); - } - - @Override - public void removeColorChangeListener(ColorChangeListener listener) { - removeListener(ColorChangeEvent.class, listener); - } - - @Override - public void windowClose(CloseEvent e) { - if (e.getWindow() == window) { - getState().popupVisible = false; - } - } - - /** - * Fired when a color change event occurs - * - * @param event - * The color change event - */ - protected void colorChanged(ColorChangeEvent event) { - setColor(event.getColor()); - fireColorChanged(); - } - - /** - * Notifies the listeners that the selected color has changed - */ - public void fireColorChanged() { - fireEvent(new ColorChangeEvent(this, color)); - } - - /** - * The style for the popup window - * - * @param style - * The style - */ - public void setPopupStyle(PopupStyle style) { - popupStyle = style; - - switch (style) { - case POPUP_NORMAL: { - setRGBVisibility(true); - setHSVVisibility(true); - setSwatchesVisibility(true); - setHistoryVisibility(true); - setTextfieldVisibility(true); - break; - } - - case POPUP_SIMPLE: { - setRGBVisibility(false); - setHSVVisibility(false); - setSwatchesVisibility(true); - setHistoryVisibility(false); - setTextfieldVisibility(false); - break; - } - } - } - - /** - * Gets the style for the popup window - * - * @since 7.5.0 - * @return popup window style - */ - public PopupStyle getPopupStyle() { - return popupStyle; - } - - /** - * Set the visibility of the RGB Tab - * - * @param visible - * The visibility - */ - public void setRGBVisibility(boolean visible) { - - if (!visible && !hsvVisible && !swatchesVisible) { - throw new IllegalArgumentException("Cannot hide all tabs."); - } - - rgbVisible = visible; - if (window != null) { - window.setRGBTabVisible(visible); - } - } - - /** - * Gets the visibility of the RGB Tab - * - * @since 7.5.0 - * @return visibility of the RGB tab - */ - public boolean getRGBVisibility() { - return rgbVisible; - } - - /** - * Set the visibility of the HSV Tab - * - * @param visible - * The visibility - */ - public void setHSVVisibility(boolean visible) { - if (!visible && !rgbVisible && !swatchesVisible) { - throw new IllegalArgumentException("Cannot hide all tabs."); - } - - hsvVisible = visible; - if (window != null) { - window.setHSVTabVisible(visible); - } - } - - /** - * Gets the visibility of the HSV Tab - * - * @since 7.5.0 - * @return visibility of the HSV tab - */ - public boolean getHSVVisibility() { - return hsvVisible; - } - - /** - * Set the visibility of the Swatches Tab - * - * @param visible - * The visibility - */ - public void setSwatchesVisibility(boolean visible) { - if (!visible && !hsvVisible && !rgbVisible) { - throw new IllegalArgumentException("Cannot hide all tabs."); - } - - swatchesVisible = visible; - if (window != null) { - window.setSwatchesTabVisible(visible); - } - } - - /** - * Gets the visibility of the Swatches Tab - * - * @since 7.5.0 - * @return visibility of the swatches tab - */ - public boolean getSwatchesVisibility() { - return swatchesVisible; - } - - /** - * Sets the visibility of the Color History - * - * @param visible - * The visibility - */ - public void setHistoryVisibility(boolean visible) { - historyVisible = visible; - if (window != null) { - window.setHistoryVisible(visible); - } - } - - /** - * Gets the visibility of the Color History - * - * @since 7.5.0 - * @return visibility of color history - */ - public boolean getHistoryVisibility() { - return historyVisible; - } - - /** - * Sets the visibility of the CSS color code text field - * - * @param visible - * The visibility - */ - public void setTextfieldVisibility(boolean visible) { - textfieldVisible = visible; - if (window != null) { - window.setPreviewVisible(visible); - } - } - - /** - * Gets the visibility of CSS color code text field - * - * @since 7.5.0 - * @return visibility of css color code text field - */ - public boolean getTextfieldVisibility() { - return textfieldVisible; - } - - @Override - protected ColorPickerState getState() { - return (ColorPickerState) super.getState(); - } - - @Override - protected ColorPickerState getState(boolean markAsDirty) { - return (ColorPickerState) super.getState(markAsDirty); - } - - /** - * Sets the default styles of the component - * - */ - abstract protected void setDefaultStyles(); - - /** - * Shows a popup-window for color selection. - */ - public void showPopup() { - showPopup(true); - } - - /** - * Hides a popup-window for color selection. - */ - public void hidePopup() { - showPopup(false); - } - - /** - * Shows or hides popup-window depending on the given parameter. If there is - * no such window yet, one is created. - * - * @param open - */ - protected void showPopup(boolean open) { - if (open && !isReadOnly()) { - if (parent == null) { - parent = getUI(); - } - - if (window == null) { - - // Create the popup - window = new ColorPickerPopup(color); - window.setCaption(popupCaption); - - window.setRGBTabVisible(rgbVisible); - window.setHSVTabVisible(hsvVisible); - window.setSwatchesTabVisible(swatchesVisible); - window.setHistoryVisible(historyVisible); - window.setPreviewVisible(textfieldVisible); - - window.setImmediate(true); - window.addCloseListener(this); - window.addColorChangeListener(new ColorChangeListener() { - @Override - public void colorChanged(ColorChangeEvent event) { - AbstractColorPicker.this.colorChanged(event); - } - }); - - window.getHistory().setColor(color); - parent.addWindow(window); - window.setVisible(true); - window.setPositionX(positionX); - window.setPositionY(positionY); - - } else if (!parent.equals(window.getParent())) { - - window.setRGBTabVisible(rgbVisible); - window.setHSVTabVisible(hsvVisible); - window.setSwatchesTabVisible(swatchesVisible); - window.setHistoryVisible(historyVisible); - window.setPreviewVisible(textfieldVisible); - - window.setColor(color); - window.getHistory().setColor(color); - window.setVisible(true); - parent.addWindow(window); - } - - } else if (window != null) { - window.setVisible(false); - parent.removeWindow(window); - } - getState().popupVisible = open; - } - - /** - * Set whether the caption text is rendered as HTML or not. You might need - * to re-theme component to allow higher content than the original text - * style. - * - * If set to true, the captions are passed to the browser as html and the - * developer is responsible for ensuring no harmful html is used. If set to - * false, the content is passed to the browser as plain text. - * - * @param htmlContentAllowed - * <code>true</code> if caption is rendered as HTML, - * <code>false</code> otherwise - * @deprecated as of , use {@link #setCaptionAsHtml(boolean)} instead - */ - @Deprecated - public void setHtmlContentAllowed(boolean htmlContentAllowed) { - setCaptionAsHtml(htmlContentAllowed); - } - - /** - * Return HTML rendering setting - * - * @return <code>true</code> if the caption text is to be rendered as HTML, - * <code>false</code> otherwise - * @deprecated as of , use {@link #isCaptionAsHtml()} instead - */ - @Deprecated - public boolean isHtmlContentAllowed() { - return isCaptionAsHtml(); - } - - @Override - public void readDesign(Element design, DesignContext designContext) { - super.readDesign(design, designContext); - - Attributes attributes = design.attributes(); - if (design.hasAttr("color")) { - // Ignore the # character - String hexColor = DesignAttributeHandler - .readAttribute("color", attributes, String.class) - .substring(1); - setColor(new Color(Integer.parseInt(hexColor, 16))); - } - if (design.hasAttr("popup-style")) { - setPopupStyle(PopupStyle.valueOf( - "POPUP_" + attributes.get("popup-style").toUpperCase())); - } - if (design.hasAttr("position")) { - String[] position = attributes.get("position").split(","); - setPosition(Integer.parseInt(position[0]), - Integer.parseInt(position[1])); - } - } - - @Override - public void writeDesign(Element design, DesignContext designContext) { - super.writeDesign(design, designContext); - - Attributes attribute = design.attributes(); - DesignAttributeHandler.writeAttribute("color", attribute, - color.getCSS(), Color.WHITE.getCSS(), String.class); - DesignAttributeHandler.writeAttribute("popup-style", attribute, - (popupStyle == PopupStyle.POPUP_NORMAL ? "normal" : "simple"), - "normal", String.class); - DesignAttributeHandler.writeAttribute("position", attribute, - positionX + "," + positionY, "0,0", String.class); - } - - @Override - protected Collection<String> getCustomAttributes() { - Collection<String> result = super.getCustomAttributes(); - result.add("color"); - result.add("position"); - result.add("popup-style"); - return result; - } -} diff --git a/server/src/main/java/com/vaadin/ui/AbstractSelect.java b/server/src/main/java/com/vaadin/ui/AbstractSelect.java deleted file mode 100644 index 57c2fc1046..0000000000 --- a/server/src/main/java/com/vaadin/ui/AbstractSelect.java +++ /dev/null @@ -1,2353 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.EventObject; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.jsoup.nodes.Element; - -import com.vaadin.data.Container; -import com.vaadin.data.Item; -import com.vaadin.data.Property; -import com.vaadin.data.util.IndexedContainer; -import com.vaadin.event.DataBoundTransferable; -import com.vaadin.event.Transferable; -import com.vaadin.event.dd.DragAndDropEvent; -import com.vaadin.event.dd.DropTarget; -import com.vaadin.event.dd.TargetDetailsImpl; -import com.vaadin.event.dd.acceptcriteria.ClientSideCriterion; -import com.vaadin.event.dd.acceptcriteria.ContainsDataFlavor; -import com.vaadin.event.dd.acceptcriteria.TargetDetailIs; -import com.vaadin.server.KeyMapper; -import com.vaadin.server.PaintException; -import com.vaadin.server.PaintTarget; -import com.vaadin.server.Resource; -import com.vaadin.server.VaadinSession; -import com.vaadin.shared.ui.combobox.FilteringMode; -import com.vaadin.shared.ui.dd.VerticalDropLocation; -import com.vaadin.shared.ui.select.AbstractSelectState; -import com.vaadin.ui.declarative.DesignAttributeHandler; -import com.vaadin.ui.declarative.DesignContext; -import com.vaadin.ui.declarative.DesignException; -import com.vaadin.ui.declarative.DesignFormatter; -import com.vaadin.v7.data.Validator.InvalidValueException; -import com.vaadin.v7.data.util.converter.LegacyConverter; -import com.vaadin.v7.data.util.converter.LegacyConverterUtil; -import com.vaadin.v7.data.util.converter.LegacyConverter.ConversionException; -import com.vaadin.v7.ui.LegacyAbstractField; - -/** - * <p> - * A class representing a selection of items the user has selected in a UI. The - * set of choices is presented as a set of {@link com.vaadin.data.Item}s in a - * {@link com.vaadin.data.Container}. - * </p> - * - * <p> - * A <code>Select</code> component may be in single- or multiselect mode. - * Multiselect mode means that more than one item can be selected - * simultaneously. - * </p> - * - * @author Vaadin Ltd. - * @since 5.0 - */ -@SuppressWarnings("serial") -// TODO currently cannot specify type more precisely in case of multi-select -public abstract class AbstractSelect extends LegacyAbstractField<Object> - implements Container, Container.Viewer, - Container.PropertySetChangeListener, - Container.PropertySetChangeNotifier, Container.ItemSetChangeNotifier, - Container.ItemSetChangeListener, LegacyComponent { - - public enum ItemCaptionMode { - /** - * Item caption mode: Item's ID converted to a String using - * {@link VaadinSession#getConverterFactory()} is used as caption. - */ - ID, - /** - * Item caption mode: Item's ID's <code>String</code> representation is - * used as caption. - * - * @since 7.5.6 - */ - ID_TOSTRING, - /** - * Item caption mode: Item's <code>String</code> representation is used - * as caption. - */ - ITEM, - /** - * Item caption mode: Index of the item is used as caption. The index - * mode can only be used with the containers implementing the - * {@link com.vaadin.data.Container.Indexed} interface. - */ - INDEX, - /** - * Item caption mode: If an Item has a caption it's used, if not, Item's - * ID converted to a String using - * {@link VaadinSession#getConverterFactory()} is used as caption. - * <b>This is the default</b>. - */ - EXPLICIT_DEFAULTS_ID, - /** - * Item caption mode: Captions must be explicitly specified. - */ - EXPLICIT, - /** - * Item caption mode: Only icons are shown, captions are hidden. - */ - ICON_ONLY, - /** - * Item caption mode: Item captions are read from property specified - * with <code>setItemCaptionPropertyId</code>. - */ - PROPERTY; - } - - /** - * @deprecated As of 7.0, use {@link ItemCaptionMode#ID} instead - */ - @Deprecated - public static final ItemCaptionMode ITEM_CAPTION_MODE_ID = ItemCaptionMode.ID; - - /** - * @deprecated As of 7.0, use {@link ItemCaptionMode#ITEM} instead - */ - @Deprecated - public static final ItemCaptionMode ITEM_CAPTION_MODE_ITEM = ItemCaptionMode.ITEM; - - /** - * @deprecated As of 7.0, use {@link ItemCaptionMode#INDEX} instead - */ - @Deprecated - public static final ItemCaptionMode ITEM_CAPTION_MODE_INDEX = ItemCaptionMode.INDEX; - - /** - * @deprecated As of 7.0, use {@link ItemCaptionMode#EXPLICIT_DEFAULTS_ID} - * instead - */ - @Deprecated - public static final ItemCaptionMode ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID = ItemCaptionMode.EXPLICIT_DEFAULTS_ID; - - /** - * @deprecated As of 7.0, use {@link ItemCaptionMode#EXPLICIT} instead - */ - @Deprecated - public static final ItemCaptionMode ITEM_CAPTION_MODE_EXPLICIT = ItemCaptionMode.EXPLICIT; - - /** - * @deprecated As of 7.0, use {@link ItemCaptionMode#ICON_ONLY} instead - */ - @Deprecated - public static final ItemCaptionMode ITEM_CAPTION_MODE_ICON_ONLY = ItemCaptionMode.ICON_ONLY; - - /** - * @deprecated As of 7.0, use {@link ItemCaptionMode#PROPERTY} instead - */ - @Deprecated - public static final ItemCaptionMode ITEM_CAPTION_MODE_PROPERTY = ItemCaptionMode.PROPERTY; - - /** - * Interface for option filtering, used to filter options based on user - * entered value. The value is matched to the item caption. - * <code>FilteringMode.OFF</code> (0) turns the filtering off. - * <code>FilteringMode.STARTSWITH</code> (1) matches from the start of the - * caption. <code>FilteringMode.CONTAINS</code> (1) matches anywhere in the - * caption. - */ - public interface Filtering extends Serializable { - - /** - * @deprecated As of 7.0, use {@link FilteringMode#OFF} instead - */ - @Deprecated - public static final FilteringMode FILTERINGMODE_OFF = FilteringMode.OFF; - /** - * @deprecated As of 7.0, use {@link FilteringMode#STARTSWITH} instead - */ - @Deprecated - public static final FilteringMode FILTERINGMODE_STARTSWITH = FilteringMode.STARTSWITH; - /** - * @deprecated As of 7.0, use {@link FilteringMode#CONTAINS} instead - */ - @Deprecated - public static final FilteringMode FILTERINGMODE_CONTAINS = FilteringMode.CONTAINS; - - /** - * Sets the option filtering mode. - * - * @param filteringMode - * the filtering mode to use - */ - public void setFilteringMode(FilteringMode filteringMode); - - /** - * Gets the current filtering mode. - * - * @return the filtering mode in use - */ - public FilteringMode getFilteringMode(); - - } - - /** - * Select options. - */ - protected Container items; - - /** - * Is the user allowed to add new options? - */ - private boolean allowNewOptions; - - /** - * Keymapper used to map key values. - */ - protected KeyMapper<Object> itemIdMapper = new KeyMapper<Object>(); - - /** - * Item icons. - */ - private final HashMap<Object, Resource> itemIcons = new HashMap<Object, Resource>(); - - /** - * Item captions. - */ - private final HashMap<Object, String> itemCaptions = new HashMap<Object, String>(); - - /** - * Item caption mode. - */ - private ItemCaptionMode itemCaptionMode = ItemCaptionMode.EXPLICIT_DEFAULTS_ID; - - /** - * Item caption source property id. - */ - private Object itemCaptionPropertyId = null; - - /** - * Item icon source property id. - */ - private Object itemIconPropertyId = null; - - /** - * List of property set change event listeners. - */ - private Set<Container.PropertySetChangeListener> propertySetEventListeners = null; - - /** - * List of item set change event listeners. - */ - private Set<Container.ItemSetChangeListener> itemSetEventListeners = null; - - /** - * Item id that represents null selection of this select. - * - * <p> - * Data interface does not support nulls as item ids. Selecting the item - * identified by this id is the same as selecting no items at all. This - * setting only affects the single select mode. - * </p> - */ - private Object nullSelectionItemId = null; - - // Null (empty) selection is enabled by default - private boolean nullSelectionAllowed = true; - private NewItemHandler newItemHandler; - - // Caption (Item / Property) change listeners - CaptionChangeListener captionChangeListener; - - /* Constructors */ - - /** - * Creates an empty Select. The caption is not used. - */ - public AbstractSelect() { - setContainerDataSource(new IndexedContainer()); - } - - /** - * Creates an empty Select with caption. - */ - public AbstractSelect(String caption) { - setContainerDataSource(new IndexedContainer()); - setCaption(caption); - } - - /** - * Creates a new select that is connected to a data-source. - * - * @param caption - * the Caption of the component. - * @param dataSource - * the Container datasource to be selected from by this select. - */ - public AbstractSelect(String caption, Container dataSource) { - setCaption(caption); - setContainerDataSource(dataSource); - } - - /** - * Creates a new select that is filled from a collection of option values. - * - * @param caption - * the Caption of this field. - * @param options - * the Collection containing the options. - */ - public AbstractSelect(String caption, Collection<?> options) { - - // Creates the options container and add given options to it - final Container c = new IndexedContainer(); - if (options != null) { - for (final Iterator<?> i = options.iterator(); i.hasNext();) { - c.addItem(i.next()); - } - } - - setCaption(caption); - setContainerDataSource(c); - } - - /* Component methods */ - - /** - * Paints the content of this component. - * - * @param target - * the Paint Event. - * @throws PaintException - * if the paint operation failed. - */ - @Override - public void paintContent(PaintTarget target) throws PaintException { - - // Paints select attributes - if (isNewItemsAllowed()) { - target.addAttribute("allownewitem", true); - } - if (isNullSelectionAllowed()) { - target.addAttribute("nullselect", true); - if (getNullSelectionItemId() != null) { - target.addAttribute("nullselectitem", true); - } - } - - // Constructs selected keys array - String[] selectedKeys; - if (isMultiSelect()) { - selectedKeys = new String[((Set<?>) getValue()).size()]; - } else { - selectedKeys = new String[(getValue() == null - && getNullSelectionItemId() == null ? 0 : 1)]; - } - - // == - // first remove all previous item/property listeners - getCaptionChangeListener().clear(); - // Paints the options and create array of selected id keys - - target.startTag("options"); - int keyIndex = 0; - // Support for external null selection item id - final Collection<?> ids = getItemIds(); - if (isNullSelectionAllowed() && getNullSelectionItemId() != null - && !ids.contains(getNullSelectionItemId())) { - final Object id = getNullSelectionItemId(); - // Paints option - target.startTag("so"); - paintItem(target, id); - if (isSelected(id)) { - selectedKeys[keyIndex++] = itemIdMapper.key(id); - } - target.endTag("so"); - } - - final Iterator<?> i = getItemIds().iterator(); - // Paints the available selection options from data source - while (i.hasNext()) { - // Gets the option attribute values - final Object id = i.next(); - if (!isNullSelectionAllowed() && id != null - && id.equals(getNullSelectionItemId())) { - // Remove item if it's the null selection item but null - // selection is not allowed - continue; - } - final String key = itemIdMapper.key(id); - // add listener for each item, to cause repaint if an item changes - getCaptionChangeListener().addNotifierForItem(id); - target.startTag("so"); - paintItem(target, id); - if (isSelected(id) && keyIndex < selectedKeys.length) { - selectedKeys[keyIndex++] = key; - } - target.endTag("so"); - } - target.endTag("options"); - // == - - // Paint variables - target.addVariable(this, "selected", selectedKeys); - if (isNewItemsAllowed()) { - target.addVariable(this, "newitem", ""); - } - - } - - protected void paintItem(PaintTarget target, Object itemId) - throws PaintException { - final String key = itemIdMapper.key(itemId); - final String caption = getItemCaption(itemId); - final Resource icon = getItemIcon(itemId); - if (icon != null) { - target.addAttribute("icon", icon); - } - target.addAttribute("caption", caption); - if (itemId != null && itemId.equals(getNullSelectionItemId())) { - target.addAttribute("nullselection", true); - } - target.addAttribute("key", key); - if (isSelected(itemId)) { - target.addAttribute("selected", true); - } - } - - /** - * Invoked when the value of a variable has changed. - * - * @see com.vaadin.ui.AbstractComponent#changeVariables(java.lang.Object, - * java.util.Map) - */ - @Override - public void changeVariables(Object source, Map<String, Object> variables) { - - // New option entered (and it is allowed) - if (isNewItemsAllowed()) { - final String newitem = (String) variables.get("newitem"); - if (newitem != null && newitem.length() > 0) { - getNewItemHandler().addNewItem(newitem); - } - } - - // Selection change - if (variables.containsKey("selected")) { - final String[] clientSideSelectedKeys = (String[]) variables - .get("selected"); - - // Multiselect mode - if (isMultiSelect()) { - - // TODO Optimize by adding repaintNotNeeded when applicable - - // Converts the key-array to id-set - final LinkedList<Object> acceptedSelections = new LinkedList<Object>(); - for (int i = 0; i < clientSideSelectedKeys.length; i++) { - final Object id = itemIdMapper - .get(clientSideSelectedKeys[i]); - if (!isNullSelectionAllowed() - && (id == null || id == getNullSelectionItemId())) { - // skip empty selection if nullselection is not allowed - markAsDirty(); - } else if (id != null && containsId(id)) { - acceptedSelections.add(id); - } - } - - if (!isNullSelectionAllowed() - && acceptedSelections.size() < 1) { - // empty selection not allowed, keep old value - markAsDirty(); - return; - } - - // Limits the deselection to the set of visible items - // (non-visible items can not be deselected) - Collection<?> visibleNotSelected = getVisibleItemIds(); - if (visibleNotSelected != null) { - visibleNotSelected = new HashSet<Object>( - visibleNotSelected); - // Don't remove those that will be added to preserve order - visibleNotSelected.removeAll(acceptedSelections); - - @SuppressWarnings("unchecked") - Set<Object> newsel = (Set<Object>) getValue(); - if (newsel == null) { - newsel = new LinkedHashSet<Object>(); - } else { - newsel = new LinkedHashSet<Object>(newsel); - } - newsel.removeAll(visibleNotSelected); - newsel.addAll(acceptedSelections); - setValue(newsel, true); - } - } else { - // Single select mode - if (!isNullSelectionAllowed() - && (clientSideSelectedKeys.length == 0 - || clientSideSelectedKeys[0] == null - || clientSideSelectedKeys[0] == getNullSelectionItemId())) { - markAsDirty(); - return; - } - if (clientSideSelectedKeys.length == 0) { - // Allows deselection only if the deselected item is - // visible - final Object current = getValue(); - final Collection<?> visible = getVisibleItemIds(); - if (visible != null && visible.contains(current)) { - setValue(null, true); - } - } else { - String clientSelectedKey = clientSideSelectedKeys[0]; - if ("null".equals(clientSelectedKey) - || itemIdMapper.containsKey(clientSelectedKey)) { - // Happens to work for nullselection - // (get ("null") -> null)) - final Object id = itemIdMapper.get(clientSelectedKey); - - if (!isNullSelectionAllowed() && id == null) { - markAsDirty(); - } else if (id != null - && id.equals(getNullSelectionItemId())) { - setValue(null, true); - } else { - setValue(id, true); - } - } - } - } - } - } - - /** - * TODO refine doc Setter for new item handler that is called when user adds - * new item in newItemAllowed mode. - * - * @param newItemHandler - */ - public void setNewItemHandler(NewItemHandler newItemHandler) { - this.newItemHandler = newItemHandler; - } - - /** - * TODO refine doc - * - * @return - */ - public NewItemHandler getNewItemHandler() { - if (newItemHandler == null) { - newItemHandler = new DefaultNewItemHandler(); - } - return newItemHandler; - } - - public interface NewItemHandler extends Serializable { - void addNewItem(String newItemCaption); - } - - /** - * TODO refine doc - * - * This is a default class that handles adding new items that are typed by - * user to selects container. - * - * By extending this class one may implement some logic on new item addition - * like database inserts. - * - */ - public class DefaultNewItemHandler implements NewItemHandler { - @Override - public void addNewItem(String newItemCaption) { - // Checks for readonly - if (isReadOnly()) { - throw new Property.ReadOnlyException(); - } - - // Adds new option - if (addItem(newItemCaption) != null) { - - // Sets the caption property, if used - if (getItemCaptionPropertyId() != null) { - getContainerProperty(newItemCaption, - getItemCaptionPropertyId()) - .setValue(newItemCaption); - } - if (isMultiSelect()) { - Set values = new HashSet((Collection) getValue()); - values.add(newItemCaption); - setValue(values); - } else { - setValue(newItemCaption); - } - } - } - } - - /** - * Gets the visible item ids. In Select, this returns list of all item ids, - * but can be overriden in subclasses if they paint only part of the items - * to the terminal or null if no items is visible. - */ - public Collection<?> getVisibleItemIds() { - return getItemIds(); - } - - /* Property methods */ - - /** - * Returns the type of the property. <code>getValue</code> and - * <code>setValue</code> methods must be compatible with this type: one can - * safely cast <code>getValue</code> to given type and pass any variable - * assignable to this type as a parameter to <code>setValue</code>. - * - * @return the Type of the property. - */ - @Override - public Class<?> getType() { - if (isMultiSelect()) { - return Set.class; - } else { - return Object.class; - } - } - - /** - * Gets the selected item id or in multiselect mode a set of selected ids. - * - * @see com.vaadin.v7.ui.LegacyAbstractField#getValue() - */ - @Override - public Object getValue() { - final Object retValue = super.getValue(); - - if (isMultiSelect()) { - - // If the return value is not a set - if (retValue == null) { - return new HashSet<Object>(); - } - if (retValue instanceof Set) { - return Collections.unmodifiableSet((Set<?>) retValue); - } else if (retValue instanceof Collection) { - return new HashSet<Object>((Collection<?>) retValue); - } else { - final Set<Object> s = new HashSet<Object>(); - if (items.containsId(retValue)) { - s.add(retValue); - } - return s; - } - - } else { - return retValue; - } - } - - /** - * Sets the visible value of the property. - * - * <p> - * The value of the select is the selected item id. If the select is in - * multiselect-mode, the value is a set of selected item keys. In - * multiselect mode all collections of id:s can be assigned. - * </p> - * - * @param newValue - * the New selected item or collection of selected items. - * @see com.vaadin.v7.ui.LegacyAbstractField#setValue(java.lang.Object) - */ - @Override - public void setValue(Object newValue) throws Property.ReadOnlyException { - if (newValue == getNullSelectionItemId()) { - newValue = null; - } - - setValue(newValue, false); - } - - /** - * Sets the visible value of the property. - * - * <p> - * The value of the select is the selected item id. If the select is in - * multiselect-mode, the value is a set of selected item keys. In - * multiselect mode all collections of id:s can be assigned. - * </p> - * - * @since 7.5.7 - * @param newValue - * the New selected item or collection of selected items. - * @param repaintIsNotNeeded - * True if caller is sure that repaint is not needed. - * @param ignoreReadOnly - * True if read-only check should be omitted. - * @see com.vaadin.v7.ui.LegacyAbstractField#setValue(java.lang.Object, - * java.lang.Boolean) - */ - @Override - protected void setValue(Object newFieldValue, boolean repaintIsNotNeeded, - boolean ignoreReadOnly) - throws com.vaadin.data.Property.ReadOnlyException, - ConversionException, InvalidValueException { - if (isMultiSelect()) { - if (newFieldValue == null) { - super.setValue(new LinkedHashSet<Object>(), repaintIsNotNeeded, - ignoreReadOnly); - } else if (Collection.class - .isAssignableFrom(newFieldValue.getClass())) { - super.setValue( - new LinkedHashSet<Object>( - (Collection<?>) newFieldValue), - repaintIsNotNeeded, ignoreReadOnly); - } - } else if (newFieldValue == null || items.containsId(newFieldValue)) { - super.setValue(newFieldValue, repaintIsNotNeeded, ignoreReadOnly); - } - } - - /* Container methods */ - - /** - * Gets the item from the container with given id. If the container does not - * contain the requested item, null is returned. - * - * @param itemId - * the item id. - * @return the item from the container. - */ - @Override - public Item getItem(Object itemId) { - return items.getItem(itemId); - } - - /** - * Gets the item Id collection from the container. - * - * @return the Collection of item ids. - */ - @Override - public Collection<?> getItemIds() { - return items.getItemIds(); - } - - /** - * Gets the property Id collection from the container. - * - * @return the Collection of property ids. - */ - @Override - public Collection<?> getContainerPropertyIds() { - return items.getContainerPropertyIds(); - } - - /** - * Gets the property type. - * - * @param propertyId - * the Id identifying the property. - * @see com.vaadin.data.Container#getType(java.lang.Object) - */ - @Override - public Class<?> getType(Object propertyId) { - return items.getType(propertyId); - } - - /* - * Gets the number of items in the container. - * - * @return the Number of items in the container. - * - * @see com.vaadin.data.Container#size() - */ - @Override - public int size() { - int size = items.size(); - assert size >= 0; - return size; - } - - /** - * Tests, if the collection contains an item with given id. - * - * @param itemId - * the Id the of item to be tested. - */ - @Override - public boolean containsId(Object itemId) { - if (itemId != null) { - return items.containsId(itemId); - } else { - return false; - } - } - - /** - * Gets the Property identified by the given itemId and propertyId from the - * Container - * - * @see com.vaadin.data.Container#getContainerProperty(Object, Object) - */ - @Override - public Property getContainerProperty(Object itemId, Object propertyId) { - return items.getContainerProperty(itemId, propertyId); - } - - /** - * Adds the new property to all items. Adds a property with given id, type - * and default value to all items in the container. - * - * This functionality is optional. If the function is unsupported, it always - * returns false. - * - * @return True if the operation succeeded. - * @see com.vaadin.data.Container#addContainerProperty(java.lang.Object, - * java.lang.Class, java.lang.Object) - */ - @Override - public boolean addContainerProperty(Object propertyId, Class<?> type, - Object defaultValue) throws UnsupportedOperationException { - - final boolean retval = items.addContainerProperty(propertyId, type, - defaultValue); - if (retval && !(items instanceof Container.PropertySetChangeNotifier)) { - firePropertySetChange(); - } - return retval; - } - - /** - * Removes all items from the container. - * - * This functionality is optional. If the function is unsupported, it always - * returns false. - * - * @return True if the operation succeeded. - * @see com.vaadin.data.Container#removeAllItems() - */ - @Override - public boolean removeAllItems() throws UnsupportedOperationException { - - final boolean retval = items.removeAllItems(); - itemIdMapper.removeAll(); - if (retval) { - setValue(null); - if (!(items instanceof Container.ItemSetChangeNotifier)) { - fireItemSetChange(); - } - } - return retval; - } - - /** - * Creates a new item into container with container managed id. The id of - * the created new item is returned. The item can be fetched with getItem() - * method. if the creation fails, null is returned. - * - * @return the Id of the created item or null in case of failure. - * @see com.vaadin.data.Container#addItem() - */ - @Override - public Object addItem() throws UnsupportedOperationException { - - final Object retval = items.addItem(); - if (retval != null - && !(items instanceof Container.ItemSetChangeNotifier)) { - fireItemSetChange(); - } - return retval; - } - - /** - * Create a new item into container. The created new item is returned and - * ready for setting property values. if the creation fails, null is - * returned. In case the container already contains the item, null is - * returned. - * - * This functionality is optional. If the function is unsupported, it always - * returns null. - * - * @param itemId - * the Identification of the item to be created. - * @return the Created item with the given id, or null in case of failure. - * @see com.vaadin.data.Container#addItem(java.lang.Object) - */ - @Override - public Item addItem(Object itemId) throws UnsupportedOperationException { - - final Item retval = items.addItem(itemId); - if (retval != null - && !(items instanceof Container.ItemSetChangeNotifier)) { - fireItemSetChange(); - } - return retval; - } - - /** - * Adds given items with given item ids to container. - * - * @since 7.2 - * @param itemId - * item identifiers to be added to underlying container - * @throws UnsupportedOperationException - * if the underlying container don't support adding items with - * identifiers - */ - public void addItems(Object... itemId) - throws UnsupportedOperationException { - for (Object id : itemId) { - addItem(id); - } - } - - /** - * Adds given items with given item ids to container. - * - * @since 7.2 - * @param itemIds - * item identifiers to be added to underlying container - * @throws UnsupportedOperationException - * if the underlying container don't support adding items with - * identifiers - */ - public void addItems(Collection<?> itemIds) - throws UnsupportedOperationException { - addItems(itemIds.toArray()); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#removeItem(java.lang.Object) - */ - @Override - public boolean removeItem(Object itemId) - throws UnsupportedOperationException { - - unselect(itemId); - final boolean retval = items.removeItem(itemId); - itemIdMapper.remove(itemId); - if (retval && !(items instanceof Container.ItemSetChangeNotifier)) { - fireItemSetChange(); - } - return retval; - } - - /** - * Checks that the current selection is valid, i.e. the selected item ids - * exist in the container. Updates the selection if one or several selected - * item ids are no longer available in the container. - */ - @SuppressWarnings("unchecked") - public void sanitizeSelection() { - Object value = getValue(); - if (value == null) { - return; - } - - boolean changed = false; - - if (isMultiSelect()) { - Collection<Object> valueAsCollection = (Collection<Object>) value; - List<Object> newSelection = new ArrayList<Object>( - valueAsCollection.size()); - for (Object subValue : valueAsCollection) { - if (containsId(subValue)) { - newSelection.add(subValue); - } else { - changed = true; - } - } - if (changed) { - setValue(newSelection); - } - } else { - if (!containsId(value)) { - setValue(null); - } - } - - } - - /** - * Removes the property from all items. Removes a property with given id - * from all the items in the container. - * - * This functionality is optional. If the function is unsupported, it always - * returns false. - * - * @return True if the operation succeeded. - * @see com.vaadin.data.Container#removeContainerProperty(java.lang.Object) - */ - @Override - public boolean removeContainerProperty(Object propertyId) - throws UnsupportedOperationException { - - final boolean retval = items.removeContainerProperty(propertyId); - if (retval && !(items instanceof Container.PropertySetChangeNotifier)) { - firePropertySetChange(); - } - return retval; - } - - /* Container.Viewer methods */ - - /** - * Sets the Container that serves as the data source of the viewer. - * - * As a side-effect the fields value (selection) is set to null due old - * selection not necessary exists in new Container. - * - * @see com.vaadin.data.Container.Viewer#setContainerDataSource(Container) - * - * @param newDataSource - * the new data source. - */ - @Override - public void setContainerDataSource(Container newDataSource) { - if (newDataSource == null) { - newDataSource = new IndexedContainer(); - } - - getCaptionChangeListener().clear(); - - if (items != newDataSource) { - - // Removes listeners from the old datasource - if (items != null) { - if (items instanceof Container.ItemSetChangeNotifier) { - ((Container.ItemSetChangeNotifier) items) - .removeItemSetChangeListener(this); - } - if (items instanceof Container.PropertySetChangeNotifier) { - ((Container.PropertySetChangeNotifier) items) - .removePropertySetChangeListener(this); - } - } - - // Assigns new data source - items = newDataSource; - - // Clears itemIdMapper also - itemIdMapper.removeAll(); - - // Adds listeners - if (items != null) { - if (items instanceof Container.ItemSetChangeNotifier) { - ((Container.ItemSetChangeNotifier) items) - .addItemSetChangeListener(this); - } - if (items instanceof Container.PropertySetChangeNotifier) { - ((Container.PropertySetChangeNotifier) items) - .addPropertySetChangeListener(this); - } - } - - /* - * We expect changing the data source should also clean value. See - * #810, #4607, #5281 - */ - setValue(null); - - markAsDirty(); - - } - } - - /** - * Gets the viewing data-source container. - * - * @see com.vaadin.data.Container.Viewer#getContainerDataSource() - */ - @Override - public Container getContainerDataSource() { - return items; - } - - /* Select attributes */ - - /** - * Is the select in multiselect mode? In multiselect mode - * - * @return the Value of property multiSelect. - */ - public boolean isMultiSelect() { - return getState(false).multiSelect; - } - - /** - * Sets the multiselect mode. Setting multiselect mode false may lose - * selection information: if selected items set contains one or more - * selected items, only one of the selected items is kept as selected. - * - * Subclasses of AbstractSelect can choose not to support changing the - * multiselect mode, and may throw {@link UnsupportedOperationException}. - * - * @param multiSelect - * the New value of property multiSelect. - */ - public void setMultiSelect(boolean multiSelect) { - if (multiSelect && getNullSelectionItemId() != null) { - throw new IllegalStateException( - "Multiselect and NullSelectionItemId can not be set at the same time."); - } - if (multiSelect != getState(false).multiSelect) { - - // Selection before mode change - final Object oldValue = getValue(); - - getState().multiSelect = multiSelect; - - // Convert the value type - if (multiSelect) { - final Set<Object> s = new HashSet<Object>(); - if (oldValue != null) { - s.add(oldValue); - } - setValue(s); - } else { - final Set<?> s = (Set<?>) oldValue; - if (s == null || s.isEmpty()) { - setValue(null); - } else { - // Set the single select to contain only the first - // selected value in the multiselect - setValue(s.iterator().next()); - } - } - - markAsDirty(); - } - } - - /** - * Does the select allow adding new options by the user. If true, the new - * options can be added to the Container. The text entered by the user is - * used as id. Note that data-source must allow adding new items. - * - * @return True if additions are allowed. - */ - public boolean isNewItemsAllowed() { - return allowNewOptions; - } - - /** - * Enables or disables possibility to add new options by the user. - * - * @param allowNewOptions - * the New value of property allowNewOptions. - */ - public void setNewItemsAllowed(boolean allowNewOptions) { - - // Only handle change requests - if (this.allowNewOptions != allowNewOptions) { - - this.allowNewOptions = allowNewOptions; - - markAsDirty(); - } - } - - /** - * Override the caption of an item. Setting caption explicitly overrides id, - * item and index captions. - * - * @param itemId - * the id of the item to be recaptioned. - * @param caption - * the New caption. - */ - public void setItemCaption(Object itemId, String caption) { - if (itemId != null) { - itemCaptions.put(itemId, caption); - markAsDirty(); - } - } - - /** - * Gets the caption of an item. The caption is generated as specified by the - * item caption mode. See <code>setItemCaptionMode()</code> for more - * details. - * - * @param itemId - * the id of the item to be queried. - * @return the caption for specified item. - */ - public String getItemCaption(Object itemId) { - - // Null items can not be found - if (itemId == null) { - return null; - } - - String caption = null; - - switch (getItemCaptionMode()) { - - case ID: - caption = idToCaption(itemId); - break; - case ID_TOSTRING: - caption = itemId.toString(); - break; - case INDEX: - if (items instanceof Container.Indexed) { - caption = String - .valueOf(((Container.Indexed) items).indexOfId(itemId)); - } else { - caption = "ERROR: Container is not indexed"; - } - break; - - case ITEM: - final Item i = getItem(itemId); - if (i != null) { - caption = i.toString(); - } - break; - - case EXPLICIT: - caption = itemCaptions.get(itemId); - break; - - case EXPLICIT_DEFAULTS_ID: - caption = itemCaptions.get(itemId); - if (caption == null) { - caption = idToCaption(itemId); - } - break; - - case PROPERTY: - final Property<?> p = getContainerProperty(itemId, - getItemCaptionPropertyId()); - if (p != null) { - Object value = p.getValue(); - if (value != null) { - caption = value.toString(); - } - } - break; - } - - // All items must have some captions - return caption != null ? caption : ""; - } - - private String idToCaption(Object itemId) { - try { - LegacyConverter<String, Object> c = (LegacyConverter<String, Object>) LegacyConverterUtil - .getConverter(String.class, itemId.getClass(), - getSession()); - return LegacyConverterUtil.convertFromModel(itemId, String.class, c, - getLocale()); - } catch (Exception e) { - return itemId.toString(); - } - } - - /** - * Sets the icon for an item. - * - * @param itemId - * the id of the item to be assigned an icon. - * @param icon - * the icon to use or null. - */ - public void setItemIcon(Object itemId, Resource icon) { - if (itemId != null) { - if (icon == null) { - itemIcons.remove(itemId); - } else { - itemIcons.put(itemId, icon); - } - markAsDirty(); - } - } - - /** - * Gets the item icon. - * - * @param itemId - * the id of the item to be assigned an icon. - * @return the icon for the item or null, if not specified. - */ - public Resource getItemIcon(Object itemId) { - final Resource explicit = itemIcons.get(itemId); - if (explicit != null) { - return explicit; - } - - if (getItemIconPropertyId() == null) { - return null; - } - - final Property<?> ip = getContainerProperty(itemId, - getItemIconPropertyId()); - if (ip == null) { - return null; - } - final Object icon = ip.getValue(); - if (icon instanceof Resource) { - return (Resource) icon; - } - - return null; - } - - /** - * Sets the item caption mode. - * - * See {@link ItemCaptionMode} for a description of the modes. - * <p> - * {@link ItemCaptionMode#EXPLICIT_DEFAULTS_ID} is the default mode. - * </p> - * - * @param mode - * the One of the modes listed above. - */ - public void setItemCaptionMode(ItemCaptionMode mode) { - if (mode != null) { - itemCaptionMode = mode; - markAsDirty(); - } - } - - /** - * Gets the item caption mode. - * - * <p> - * The mode can be one of the following ones: - * <ul> - * <li><code>ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID</code> : Items - * Id-objects <code>toString</code> is used as item caption. If caption is - * explicitly specified, it overrides the id-caption. - * <li><code>ITEM_CAPTION_MODE_ID</code> : Items Id-objects - * <code>toString</code> is used as item caption.</li> - * <li><code>ITEM_CAPTION_MODE_ITEM</code> : Item-objects - * <code>toString</code> is used as item caption.</li> - * <li><code>ITEM_CAPTION_MODE_INDEX</code> : The index of the item is used - * as item caption. The index mode can only be used with the containers - * implementing <code>Container.Indexed</code> interface.</li> - * <li><code>ITEM_CAPTION_MODE_EXPLICIT</code> : The item captions must be - * explicitly specified.</li> - * <li><code>ITEM_CAPTION_MODE_PROPERTY</code> : The item captions are read - * from property, that must be specified with - * <code>setItemCaptionPropertyId</code>.</li> - * </ul> - * The <code>ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID</code> is the default - * mode. - * </p> - * - * @return the One of the modes listed above. - */ - public ItemCaptionMode getItemCaptionMode() { - return itemCaptionMode; - } - - /** - * Sets the item caption property. - * - * <p> - * Setting the id to a existing property implicitly sets the item caption - * mode to <code>ITEM_CAPTION_MODE_PROPERTY</code>. If the object is in - * <code>ITEM_CAPTION_MODE_PROPERTY</code> mode, setting caption property id - * null resets the item caption mode to - * <code>ITEM_CAPTION_EXPLICIT_DEFAULTS_ID</code>. - * </p> - * <p> - * Note that the type of the property used for caption must be String - * </p> - * <p> - * Setting the property id to null disables this feature. The id is null by - * default - * </p> - * . - * - * @param propertyId - * the id of the property. - * - */ - public void setItemCaptionPropertyId(Object propertyId) { - if (propertyId != null) { - itemCaptionPropertyId = propertyId; - setItemCaptionMode(ITEM_CAPTION_MODE_PROPERTY); - markAsDirty(); - } else { - itemCaptionPropertyId = null; - if (getItemCaptionMode() == ITEM_CAPTION_MODE_PROPERTY) { - setItemCaptionMode(ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID); - } - markAsDirty(); - } - } - - /** - * Gets the item caption property. - * - * @return the Id of the property used as item caption source. - */ - public Object getItemCaptionPropertyId() { - return itemCaptionPropertyId; - } - - /** - * Sets the item icon property. - * - * <p> - * If the property id is set to a valid value, each item is given an icon - * got from the given property of the items. The type of the property must - * be assignable to Resource. - * </p> - * - * <p> - * Note : The icons set with <code>setItemIcon</code> function override the - * icons from the property. - * </p> - * - * <p> - * Setting the property id to null disables this feature. The id is null by - * default - * </p> - * . - * - * @param propertyId - * the id of the property that specifies icons for items or null - * @throws IllegalArgumentException - * If the propertyId is not in the container or is not of a - * valid type - */ - public void setItemIconPropertyId(Object propertyId) - throws IllegalArgumentException { - if (propertyId == null) { - itemIconPropertyId = null; - } else if (!getContainerPropertyIds().contains(propertyId)) { - throw new IllegalArgumentException( - "Property id not found in the container"); - } else if (Resource.class.isAssignableFrom(getType(propertyId))) { - itemIconPropertyId = propertyId; - } else { - throw new IllegalArgumentException( - "Property type must be assignable to Resource"); - } - markAsDirty(); - } - - /** - * Gets the item icon property. - * - * <p> - * If the property id is set to a valid value, each item is given an icon - * got from the given property of the items. The type of the property must - * be assignable to Icon. - * </p> - * - * <p> - * Note : The icons set with <code>setItemIcon</code> function override the - * icons from the property. - * </p> - * - * <p> - * Setting the property id to null disables this feature. The id is null by - * default - * </p> - * . - * - * @return the Id of the property containing the item icons. - */ - public Object getItemIconPropertyId() { - return itemIconPropertyId; - } - - /** - * Tests if an item is selected. - * - * <p> - * In single select mode testing selection status of the item identified by - * {@link #getNullSelectionItemId()} returns true if the value of the - * property is null. - * </p> - * - * @param itemId - * the Id the of the item to be tested. - * @see #getNullSelectionItemId() - * @see #setNullSelectionItemId(Object) - * - */ - public boolean isSelected(Object itemId) { - if (itemId == null) { - return false; - } - if (isMultiSelect()) { - return ((Set<?>) getValue()).contains(itemId); - } else { - final Object value = getValue(); - return itemId - .equals(value == null ? getNullSelectionItemId() : value); - } - } - - /** - * Selects an item. - * - * <p> - * In single select mode selecting item identified by - * {@link #getNullSelectionItemId()} sets the value of the property to null. - * </p> - * - * @param itemId - * the identifier of Item to be selected. - * @see #getNullSelectionItemId() - * @see #setNullSelectionItemId(Object) - * - */ - public void select(Object itemId) { - if (!isMultiSelect()) { - setValue(itemId); - } else if (!isSelected(itemId) && itemId != null - && items.containsId(itemId)) { - final Set<Object> s = new HashSet<Object>((Set<?>) getValue()); - s.add(itemId); - setValue(s); - } - } - - /** - * Unselects an item. - * - * @param itemId - * the identifier of the Item to be unselected. - * @see #getNullSelectionItemId() - * @see #setNullSelectionItemId(Object) - * - */ - public void unselect(Object itemId) { - if (isSelected(itemId)) { - if (isMultiSelect()) { - final Set<Object> s = new HashSet<Object>((Set<?>) getValue()); - s.remove(itemId); - setValue(s); - } else { - setValue(null); - } - } - } - - /** - * Notifies this listener that the Containers contents has changed. - * - * @see com.vaadin.data.Container.PropertySetChangeListener#containerPropertySetChange(com.vaadin.data.Container.PropertySetChangeEvent) - */ - @Override - public void containerPropertySetChange( - Container.PropertySetChangeEvent event) { - firePropertySetChange(); - } - - /** - * Adds a new Property set change listener for this Container. - * - * @see com.vaadin.data.Container.PropertySetChangeNotifier#addListener(com.vaadin.data.Container.PropertySetChangeListener) - */ - @Override - public void addPropertySetChangeListener( - Container.PropertySetChangeListener listener) { - if (propertySetEventListeners == null) { - propertySetEventListeners = new LinkedHashSet<Container.PropertySetChangeListener>(); - } - propertySetEventListeners.add(listener); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #addPropertySetChangeListener(com.vaadin.data.Container.PropertySetChangeListener)} - **/ - @Override - @Deprecated - public void addListener(Container.PropertySetChangeListener listener) { - addPropertySetChangeListener(listener); - } - - /** - * Removes a previously registered Property set change listener. - * - * @see com.vaadin.data.Container.PropertySetChangeNotifier#removeListener(com.vaadin.data.Container.PropertySetChangeListener) - */ - @Override - public void removePropertySetChangeListener( - Container.PropertySetChangeListener listener) { - if (propertySetEventListeners != null) { - propertySetEventListeners.remove(listener); - if (propertySetEventListeners.isEmpty()) { - propertySetEventListeners = null; - } - } - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #removePropertySetChangeListener(com.vaadin.data.Container.PropertySetChangeListener)} - **/ - @Override - @Deprecated - public void removeListener(Container.PropertySetChangeListener listener) { - removePropertySetChangeListener(listener); - } - - /** - * Adds an Item set change listener for the object. - * - * @see com.vaadin.data.Container.ItemSetChangeNotifier#addListener(com.vaadin.data.Container.ItemSetChangeListener) - */ - @Override - public void addItemSetChangeListener( - Container.ItemSetChangeListener listener) { - if (itemSetEventListeners == null) { - itemSetEventListeners = new LinkedHashSet<Container.ItemSetChangeListener>(); - } - itemSetEventListeners.add(listener); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #addItemSetChangeListener(com.vaadin.data.Container.ItemSetChangeListener)} - **/ - @Override - @Deprecated - public void addListener(Container.ItemSetChangeListener listener) { - addItemSetChangeListener(listener); - } - - /** - * Removes the Item set change listener from the object. - * - * @see com.vaadin.data.Container.ItemSetChangeNotifier#removeListener(com.vaadin.data.Container.ItemSetChangeListener) - */ - @Override - public void removeItemSetChangeListener( - Container.ItemSetChangeListener listener) { - if (itemSetEventListeners != null) { - itemSetEventListeners.remove(listener); - if (itemSetEventListeners.isEmpty()) { - itemSetEventListeners = null; - } - } - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #removeItemSetChangeListener(com.vaadin.data.Container.ItemSetChangeListener)} - **/ - @Override - @Deprecated - public void removeListener(Container.ItemSetChangeListener listener) { - removeItemSetChangeListener(listener); - } - - @Override - public Collection<?> getListeners(Class<?> eventType) { - if (Container.ItemSetChangeEvent.class.isAssignableFrom(eventType)) { - if (itemSetEventListeners == null) { - return Collections.EMPTY_LIST; - } else { - return Collections - .unmodifiableCollection(itemSetEventListeners); - } - } else if (Container.PropertySetChangeEvent.class - .isAssignableFrom(eventType)) { - if (propertySetEventListeners == null) { - return Collections.EMPTY_LIST; - } else { - return Collections - .unmodifiableCollection(propertySetEventListeners); - } - } - - return super.getListeners(eventType); - } - - /** - * Lets the listener know a Containers Item set has changed. - * - * @see com.vaadin.data.Container.ItemSetChangeListener#containerItemSetChange(com.vaadin.data.Container.ItemSetChangeEvent) - */ - @Override - public void containerItemSetChange(Container.ItemSetChangeEvent event) { - // Clears the item id mapping table - itemIdMapper.removeAll(); - - // Notify all listeners - fireItemSetChange(); - } - - /** - * Fires the property set change event. - */ - protected void firePropertySetChange() { - if (propertySetEventListeners != null - && !propertySetEventListeners.isEmpty()) { - final Container.PropertySetChangeEvent event = new PropertySetChangeEvent( - this); - final Object[] listeners = propertySetEventListeners.toArray(); - for (int i = 0; i < listeners.length; i++) { - ((Container.PropertySetChangeListener) listeners[i]) - .containerPropertySetChange(event); - } - } - markAsDirty(); - } - - /** - * Fires the item set change event. - */ - protected void fireItemSetChange() { - if (itemSetEventListeners != null && !itemSetEventListeners.isEmpty()) { - final Container.ItemSetChangeEvent event = new ItemSetChangeEvent( - this); - final Object[] listeners = itemSetEventListeners.toArray(); - for (int i = 0; i < listeners.length; i++) { - ((Container.ItemSetChangeListener) listeners[i]) - .containerItemSetChange(event); - } - } - markAsDirty(); - } - - /** - * Implementation of item set change event. - */ - private static class ItemSetChangeEvent extends EventObject - implements Serializable, Container.ItemSetChangeEvent { - - private ItemSetChangeEvent(Container source) { - super(source); - } - - /** - * Gets the Property where the event occurred. - * - * @see com.vaadin.data.Container.ItemSetChangeEvent#getContainer() - */ - @Override - public Container getContainer() { - return (Container) getSource(); - } - - } - - /** - * Implementation of property set change event. - */ - private static class PropertySetChangeEvent extends EventObject - implements Container.PropertySetChangeEvent, Serializable { - - private PropertySetChangeEvent(Container source) { - super(source); - } - - /** - * Retrieves the Container whose contents have been modified. - * - * @see com.vaadin.data.Container.PropertySetChangeEvent#getContainer() - */ - @Override - public Container getContainer() { - return (Container) getSource(); - } - - } - - /** - * For multi-selectable fields, also an empty collection of values is - * considered to be an empty field. - * - * @see LegacyAbstractField#isEmpty(). - */ - @Override - public boolean isEmpty() { - if (!isMultiSelect()) { - return super.isEmpty(); - } else { - Object value = getValue(); - return super.isEmpty() || (value instanceof Collection - && ((Collection<?>) value).isEmpty()); - } - } - - /** - * Allow or disallow empty selection by the user. If the select is in - * single-select mode, you can make an item represent the empty selection by - * calling <code>setNullSelectionItemId()</code>. This way you can for - * instance set an icon and caption for the null selection item. - * - * @param nullSelectionAllowed - * whether or not to allow empty selection - * @see #setNullSelectionItemId(Object) - * @see #isNullSelectionAllowed() - */ - public void setNullSelectionAllowed(boolean nullSelectionAllowed) { - if (nullSelectionAllowed != this.nullSelectionAllowed) { - this.nullSelectionAllowed = nullSelectionAllowed; - markAsDirty(); - } - } - - /** - * Checks if null empty selection is allowed by the user. - * - * @return whether or not empty selection is allowed - * @see #setNullSelectionAllowed(boolean) - */ - public boolean isNullSelectionAllowed() { - return nullSelectionAllowed; - } - - /** - * Returns the item id that represents null value of this select in single - * select mode. - * - * <p> - * Data interface does not support nulls as item ids. Selecting the item - * identified by this id is the same as selecting no items at all. This - * setting only affects the single select mode. - * </p> - * - * @return the Object Null value item id. - * @see #setNullSelectionItemId(Object) - * @see #isSelected(Object) - * @see #select(Object) - */ - public Object getNullSelectionItemId() { - return nullSelectionItemId; - } - - /** - * Sets the item id that represents null value of this select. - * - * <p> - * Data interface does not support nulls as item ids. Selecting the item - * identified by this id is the same as selecting no items at all. This - * setting only affects the single select mode. - * </p> - * - * @param nullSelectionItemId - * the nullSelectionItemId to set. - * @see #getNullSelectionItemId() - * @see #isSelected(Object) - * @see #select(Object) - */ - public void setNullSelectionItemId(Object nullSelectionItemId) { - if (nullSelectionItemId != null && isMultiSelect()) { - throw new IllegalStateException( - "Multiselect and NullSelectionItemId can not be set at the same time."); - } - this.nullSelectionItemId = nullSelectionItemId; - } - - /** - * Notifies the component that it is connected to an application. - * - * @see com.vaadin.v7.ui.LegacyAbstractField#attach() - */ - @Override - public void attach() { - super.attach(); - } - - /** - * Detaches the component from application. - * - * @see com.vaadin.ui.AbstractComponent#detach() - */ - @Override - public void detach() { - getCaptionChangeListener().clear(); - super.detach(); - } - - // Caption change listener - protected CaptionChangeListener getCaptionChangeListener() { - if (captionChangeListener == null) { - captionChangeListener = new CaptionChangeListener(); - } - return captionChangeListener; - } - - /** - * This is a listener helper for Item and Property changes that should cause - * a repaint. It should be attached to all items that are displayed, and the - * default implementation does this in paintContent(). Especially - * "lazyloading" components should take care to add and remove listeners as - * appropriate. Call addNotifierForItem() for each painted item (and - * remember to clear). - * - * NOTE: singleton, use getCaptionChangeListener(). - * - */ - protected class CaptionChangeListener implements - Item.PropertySetChangeListener, Property.ValueChangeListener { - - // TODO clean this up - type is either Item.PropertySetChangeNotifier or - // Property.ValueChangeNotifier - HashSet<Object> captionChangeNotifiers = new HashSet<Object>(); - - public void addNotifierForItem(Object itemId) { - switch (getItemCaptionMode()) { - case ITEM: - final Item i = getItem(itemId); - if (i == null) { - return; - } - if (i instanceof Item.PropertySetChangeNotifier) { - ((Item.PropertySetChangeNotifier) i) - .addPropertySetChangeListener( - getCaptionChangeListener()); - captionChangeNotifiers.add(i); - } - Collection<?> pids = i.getItemPropertyIds(); - if (pids != null) { - for (Iterator<?> it = pids.iterator(); it.hasNext();) { - Property<?> p = i.getItemProperty(it.next()); - if (p != null - && p instanceof Property.ValueChangeNotifier) { - ((Property.ValueChangeNotifier) p) - .addValueChangeListener( - getCaptionChangeListener()); - captionChangeNotifiers.add(p); - } - } - - } - break; - case PROPERTY: - final Property<?> p = getContainerProperty(itemId, - getItemCaptionPropertyId()); - if (p != null && p instanceof Property.ValueChangeNotifier) { - ((Property.ValueChangeNotifier) p) - .addValueChangeListener(getCaptionChangeListener()); - captionChangeNotifiers.add(p); - } - break; - - } - if (getItemIconPropertyId() != null) { - final Property p = getContainerProperty(itemId, - getItemIconPropertyId()); - if (p != null && p instanceof Property.ValueChangeNotifier) { - ((Property.ValueChangeNotifier) p) - .addValueChangeListener(getCaptionChangeListener()); - captionChangeNotifiers.add(p); - } - } - } - - public void clear() { - for (Iterator<Object> it = captionChangeNotifiers.iterator(); it - .hasNext();) { - Object notifier = it.next(); - if (notifier instanceof Item.PropertySetChangeNotifier) { - ((Item.PropertySetChangeNotifier) notifier) - .removePropertySetChangeListener( - getCaptionChangeListener()); - } else { - ((Property.ValueChangeNotifier) notifier) - .removeValueChangeListener( - getCaptionChangeListener()); - } - } - captionChangeNotifiers.clear(); - } - - @Override - public void valueChange( - com.vaadin.data.Property.ValueChangeEvent event) { - markAsDirty(); - } - - @Override - public void itemPropertySetChange( - com.vaadin.data.Item.PropertySetChangeEvent event) { - markAsDirty(); - } - - } - - /** - * Criterion which accepts a drop only if the drop target is (one of) the - * given Item identifier(s). Criterion can be used only on a drop targets - * that extends AbstractSelect like {@link Table} and {@link Tree}. The - * target and identifiers of valid Items are given in constructor. - * - * @since 6.3 - */ - public static class TargetItemIs extends AbstractItemSetCriterion { - - /** - * @param select - * the select implementation that is used as a drop target - * @param itemId - * the identifier(s) that are valid drop locations - */ - public TargetItemIs(AbstractSelect select, Object... itemId) { - super(select, itemId); - } - - @Override - public boolean accept(DragAndDropEvent dragEvent) { - AbstractSelectTargetDetails dropTargetData = (AbstractSelectTargetDetails) dragEvent - .getTargetDetails(); - if (dropTargetData.getTarget() != select) { - return false; - } - return itemIds.contains(dropTargetData.getItemIdOver()); - } - - } - - /** - * Abstract helper class to implement item id based criterion. - * - * Note, inner class used not to open itemIdMapper for public access. - * - * @since 6.3 - * - */ - private static abstract class AbstractItemSetCriterion - extends ClientSideCriterion { - protected final Collection<Object> itemIds = new HashSet<Object>(); - protected AbstractSelect select; - - public AbstractItemSetCriterion(AbstractSelect select, - Object... itemId) { - if (itemIds == null || select == null) { - throw new IllegalArgumentException( - "Accepted item identifiers must be accepted."); - } - Collections.addAll(itemIds, itemId); - this.select = select; - } - - @Override - public void paintContent(PaintTarget target) throws PaintException { - super.paintContent(target); - String[] keys = new String[itemIds.size()]; - int i = 0; - for (Object itemId : itemIds) { - String key = select.itemIdMapper.key(itemId); - keys[i++] = key; - } - target.addAttribute("keys", keys); - target.addAttribute("s", select); - } - - } - - /** - * This criterion accepts a only a {@link Transferable} that contains given - * Item (practically its identifier) from a specific AbstractSelect. - * - * @since 6.3 - */ - public static class AcceptItem extends AbstractItemSetCriterion { - - /** - * @param select - * the select from which the item id's are checked - * @param itemId - * the item identifier(s) of the select that are accepted - */ - public AcceptItem(AbstractSelect select, Object... itemId) { - super(select, itemId); - } - - @Override - public boolean accept(DragAndDropEvent dragEvent) { - DataBoundTransferable transferable = (DataBoundTransferable) dragEvent - .getTransferable(); - if (transferable.getSourceComponent() != select) { - return false; - } - return itemIds.contains(transferable.getItemId()); - } - - /** - * A simple accept criterion which ensures that {@link Transferable} - * contains an {@link Item} (or actually its identifier). In other words - * the criterion check that drag is coming from a {@link Container} like - * {@link Tree} or {@link Table}. - */ - public static final ClientSideCriterion ALL = new ContainsDataFlavor( - "itemId"); - - } - - /** - * TargetDetails implementation for subclasses of {@link AbstractSelect} - * that implement {@link DropTarget}. - * - * @since 6.3 - */ - public class AbstractSelectTargetDetails extends TargetDetailsImpl { - - /** - * The item id over which the drag event happened. - */ - protected Object idOver; - - /** - * Constructor that automatically converts itemIdOver key to - * corresponding item Id - * - */ - protected AbstractSelectTargetDetails( - Map<String, Object> rawVariables) { - super(rawVariables, (DropTarget) AbstractSelect.this); - // eagar fetch itemid, mapper may be emptied - String keyover = (String) getData("itemIdOver"); - if (keyover != null) { - idOver = itemIdMapper.get(keyover); - } - } - - /** - * If the drag operation is currently over an {@link Item}, this method - * returns the identifier of that {@link Item}. - * - */ - public Object getItemIdOver() { - return idOver; - } - - /** - * Returns a detailed vertical location where the drop happened on Item. - */ - public VerticalDropLocation getDropLocation() { - String detail = (String) getData("detail"); - if (detail == null) { - return null; - } - return VerticalDropLocation.valueOf(detail); - } - - } - - /** - * An accept criterion to accept drops only on a specific vertical location - * of an item. - * <p> - * This accept criterion is currently usable in Tree and Table - * implementations. - */ - public static class VerticalLocationIs extends TargetDetailIs { - public static VerticalLocationIs TOP = new VerticalLocationIs( - VerticalDropLocation.TOP); - public static VerticalLocationIs BOTTOM = new VerticalLocationIs( - VerticalDropLocation.BOTTOM); - public static VerticalLocationIs MIDDLE = new VerticalLocationIs( - VerticalDropLocation.MIDDLE); - - private VerticalLocationIs(VerticalDropLocation l) { - super("detail", l.name()); - } - } - - /** - * Implement this interface and pass it to Tree.setItemDescriptionGenerator - * or Table.setItemDescriptionGenerator to generate mouse over descriptions - * ("tooltips") for the rows and cells in Table or for the items in Tree. - */ - public interface ItemDescriptionGenerator extends Serializable { - - /** - * Called by Table when a cell (and row) is painted or a item is painted - * in Tree - * - * @param source - * The source of the generator, the Tree or Table the - * generator is attached to - * @param itemId - * The itemId of the painted cell - * @param propertyId - * The propertyId of the cell, null when getting row - * description - * @return The description or "tooltip" of the item. - */ - public String generateDescription(Component source, Object itemId, - Object propertyId); - } - - @Override - public void readDesign(Element design, DesignContext context) { - // handle default attributes - super.readDesign(design, context); - // handle children specifying selectable items (<option>) - readItems(design, context); - } - - protected void readItems(Element design, DesignContext context) { - Set<String> selected = new HashSet<String>(); - for (Element child : design.children()) { - readItem(child, selected, context); - } - if (!selected.isEmpty()) { - if (isMultiSelect()) { - setValue(selected, false, true); - } else if (selected.size() == 1) { - setValue(selected.iterator().next(), false, true); - } else { - throw new DesignException( - "Multiple values selected for a single select component"); - } - } - } - - /** - * Reads an Item from a design and inserts it into the data source. - * Hierarchical select components should override this method to recursively - * recursively read any child items as well. - * - * @since 7.5.0 - * @param child - * a child element representing the item - * @param selected - * A set accumulating selected items. If the item that is read is - * marked as selected, its item id should be added to this set. - * @param context - * the DesignContext instance used in parsing - * @return the item id of the new item - * - * @throws DesignException - * if the tag name of the {@code child} element is not - * {@code option}. - */ - protected Object readItem(Element child, Set<String> selected, - DesignContext context) { - if (!"option".equals(child.tagName())) { - throw new DesignException("Unrecognized child element in " - + getClass().getSimpleName() + ": " + child.tagName()); - } - - String itemId; - String caption = DesignFormatter.decodeFromTextNode(child.html()); - if (child.hasAttr("item-id")) { - itemId = child.attr("item-id"); - addItem(itemId); - setItemCaption(itemId, caption); - } else { - addItem(itemId = caption); - } - - if (child.hasAttr("icon")) { - setItemIcon(itemId, DesignAttributeHandler.readAttribute("icon", - child.attributes(), Resource.class)); - } - - if (child.hasAttr("selected")) { - selected.add(itemId); - } - - return itemId; - } - - @Override - public void writeDesign(Element design, DesignContext context) { - // Write default attributes - super.writeDesign(design, context); - - // Write options if warranted - if (context.shouldWriteData(this)) { - writeItems(design, context); - } - } - - /** - * Writes the data source items to a design. Hierarchical select components - * should override this method to only write the root items. - * - * @since 7.5.0 - * @param design - * the element into which to insert the items - * @param context - * the DesignContext instance used in writing - */ - protected void writeItems(Element design, DesignContext context) { - for (Object itemId : getItemIds()) { - writeItem(design, itemId, context); - } - } - - /** - * Writes a data source Item to a design. Hierarchical select components - * should override this method to recursively write any child items as well. - * - * @since 7.5.0 - * @param design - * the element into which to insert the item - * @param itemId - * the id of the item to write - * @param context - * the DesignContext instance used in writing - * @return - */ - protected Element writeItem(Element design, Object itemId, - DesignContext context) { - Element element = design.appendElement("option"); - - String caption = getItemCaption(itemId); - if (caption != null && !caption.equals(itemId.toString())) { - element.html(DesignFormatter.encodeForTextNode(caption)); - element.attr("item-id", itemId.toString()); - } else { - element.html(DesignFormatter.encodeForTextNode(itemId.toString())); - } - - Resource icon = getItemIcon(itemId); - if (icon != null) { - DesignAttributeHandler.writeAttribute("icon", element.attributes(), - icon, null, Resource.class); - } - - if (isSelected(itemId)) { - element.attr("selected", ""); - } - - return element; - } - - @Override - protected AbstractSelectState getState() { - return (AbstractSelectState) super.getState(); - } - - @Override - protected AbstractSelectState getState(boolean markAsDirty) { - return (AbstractSelectState) super.getState(markAsDirty); - } -} diff --git a/server/src/main/java/com/vaadin/ui/Calendar.java b/server/src/main/java/com/vaadin/ui/Calendar.java deleted file mode 100644 index 1a2c7ef716..0000000000 --- a/server/src/main/java/com/vaadin/ui/Calendar.java +++ /dev/null @@ -1,2029 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui; - -import java.lang.reflect.Method; -import java.text.DateFormat; -import java.text.DateFormatSymbols; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Date; -import java.util.EventListener; -import java.util.GregorianCalendar; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.TimeZone; -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.jsoup.nodes.Attributes; -import org.jsoup.nodes.Element; - -import com.vaadin.data.Container; -import com.vaadin.data.util.BeanItemContainer; -import com.vaadin.event.Action; -import com.vaadin.event.Action.Handler; -import com.vaadin.event.dd.DropHandler; -import com.vaadin.event.dd.DropTarget; -import com.vaadin.event.dd.TargetDetails; -import com.vaadin.server.KeyMapper; -import com.vaadin.server.PaintException; -import com.vaadin.server.PaintTarget; -import com.vaadin.shared.ui.calendar.CalendarEventId; -import com.vaadin.shared.ui.calendar.CalendarServerRpc; -import com.vaadin.shared.ui.calendar.CalendarState; -import com.vaadin.shared.ui.calendar.DateConstants; -import com.vaadin.ui.components.calendar.CalendarComponentEvent; -import com.vaadin.ui.components.calendar.CalendarComponentEvents; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.BackwardEvent; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.BackwardHandler; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.DateClickEvent; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.DateClickHandler; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventClick; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventClickHandler; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventMoveHandler; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventResize; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventResizeHandler; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.ForwardEvent; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.ForwardHandler; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.MoveEvent; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.RangeSelectEvent; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.RangeSelectHandler; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.WeekClick; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.WeekClickHandler; -import com.vaadin.ui.components.calendar.CalendarDateRange; -import com.vaadin.ui.components.calendar.CalendarTargetDetails; -import com.vaadin.ui.components.calendar.ContainerEventProvider; -import com.vaadin.ui.components.calendar.event.BasicEventProvider; -import com.vaadin.ui.components.calendar.event.CalendarEditableEventProvider; -import com.vaadin.ui.components.calendar.event.CalendarEvent; -import com.vaadin.ui.components.calendar.event.CalendarEvent.EventChangeEvent; -import com.vaadin.ui.components.calendar.event.CalendarEvent.EventChangeListener; -import com.vaadin.ui.components.calendar.event.CalendarEventProvider; -import com.vaadin.ui.components.calendar.handler.BasicBackwardHandler; -import com.vaadin.ui.components.calendar.handler.BasicDateClickHandler; -import com.vaadin.ui.components.calendar.handler.BasicEventMoveHandler; -import com.vaadin.ui.components.calendar.handler.BasicEventResizeHandler; -import com.vaadin.ui.components.calendar.handler.BasicForwardHandler; -import com.vaadin.ui.components.calendar.handler.BasicWeekClickHandler; -import com.vaadin.ui.declarative.DesignAttributeHandler; -import com.vaadin.ui.declarative.DesignContext; - -/** - * <p> - * Vaadin Calendar is for visualizing events in a calendar. Calendar events can - * be visualized in the variable length view depending on the start and end - * dates. - * </p> - * - * <li>You can set the viewable date range with the {@link #setStartDate(Date)} - * and {@link #setEndDate(Date)} methods. Calendar has a default date range of - * one week</li> - * - * <li>Calendar has two kind of views: monthly and weekly view</li> - * - * <li>If date range is seven days or shorter, the weekly view is used.</li> - * - * <li>Calendar queries its events by using a - * {@link com.vaadin.addon.calendar.event.CalendarEventProvider - * CalendarEventProvider}. By default, a - * {@link com.vaadin.addon.calendar.event.BasicEventProvider BasicEventProvider} - * is used.</li> - * - * @since 7.1 - * @author Vaadin Ltd. - */ -@SuppressWarnings("serial") -public class Calendar extends AbstractComponent - implements CalendarComponentEvents.NavigationNotifier, - CalendarComponentEvents.EventMoveNotifier, - CalendarComponentEvents.RangeSelectNotifier, - CalendarComponentEvents.EventResizeNotifier, - CalendarEventProvider.EventSetChangeListener, DropTarget, - CalendarEditableEventProvider, Action.Container, LegacyComponent { - - /** - * Calendar can use either 12 hours clock or 24 hours clock. - */ - public enum TimeFormat { - - Format12H(), Format24H(); - } - - /** Defines currently active format for time. 12H/24H. */ - protected TimeFormat currentTimeFormat; - - /** Internal calendar data source. */ - protected java.util.Calendar currentCalendar = java.util.Calendar - .getInstance(); - - /** Defines the component's active time zone. */ - protected TimeZone timezone; - - /** Defines the calendar's date range starting point. */ - protected Date startDate = null; - - /** Defines the calendar's date range ending point. */ - protected Date endDate = null; - - /** Event provider. */ - private CalendarEventProvider calendarEventProvider; - - /** - * Internal buffer for the events that are retrieved from the event - * provider. - */ - protected List<CalendarEvent> events; - - /** Date format that will be used in the UIDL for dates. */ - protected DateFormat df_date = new SimpleDateFormat("yyyy-MM-dd"); - - /** Time format that will be used in the UIDL for time. */ - protected DateFormat df_time = new SimpleDateFormat("HH:mm:ss"); - - /** Date format that will be used in the UIDL for both date and time. */ - protected DateFormat df_date_time = new SimpleDateFormat( - DateConstants.CLIENT_DATE_FORMAT + "-" - + DateConstants.CLIENT_TIME_FORMAT); - - /** - * Week view's scroll position. Client sends updates to this value so that - * scroll position wont reset all the time. - */ - private int scrollTop = 0; - - /** Caption format for the weekly view */ - private String weeklyCaptionFormat = null; - - /** Map from event ids to event handlers */ - private final Map<String, EventListener> handlers; - - /** - * Drop Handler for Vaadin DD. By default null. - */ - private DropHandler dropHandler; - - /** - * First day to show for a week - */ - private int firstDay = 1; - - /** - * Last day to show for a week - */ - private int lastDay = 7; - - /** - * First hour to show for a day - */ - private int firstHour = 0; - - /** - * Last hour to show for a day - */ - private int lastHour = 23; - - /** - * List of action handlers. - */ - private LinkedList<Action.Handler> actionHandlers = null; - - /** - * Action mapper. - */ - private KeyMapper<Action> actionMapper = null; - - /** - * - */ - private CalendarServerRpcImpl rpc = new CalendarServerRpcImpl(); - - private Integer customFirstDayOfWeek; - - /** - * Returns the logger for the calendar - */ - protected Logger getLogger() { - return Logger.getLogger(Calendar.class.getName()); - } - - /** - * Construct a Vaadin Calendar with a BasicEventProvider and no caption. - * Default date range is one week. - */ - public Calendar() { - this(null, new BasicEventProvider()); - } - - /** - * Construct a Vaadin Calendar with a BasicEventProvider and the provided - * caption. Default date range is one week. - * - * @param caption - */ - public Calendar(String caption) { - this(caption, new BasicEventProvider()); - } - - /** - * <p> - * Construct a Vaadin Calendar with event provider. Event provider is - * obligatory, because calendar component will query active events through - * it. - * </p> - * - * <p> - * By default, Vaadin Calendar will show dates from the start of the current - * week to the end of the current week. Use {@link #setStartDate(Date)} and - * {@link #setEndDate(Date)} to change this. - * </p> - * - * @param eventProvider - * Event provider, cannot be null. - */ - public Calendar(CalendarEventProvider eventProvider) { - this(null, eventProvider); - } - - /** - * <p> - * Construct a Vaadin Calendar with event provider and a caption. Event - * provider is obligatory, because calendar component will query active - * events through it. - * </p> - * - * <p> - * By default, Vaadin Calendar will show dates from the start of the current - * week to the end of the current week. Use {@link #setStartDate(Date)} and - * {@link #setEndDate(Date)} to change this. - * </p> - * - * @param eventProvider - * Event provider, cannot be null. - */ - // this is the constructor every other constructor calls - public Calendar(String caption, CalendarEventProvider eventProvider) { - registerRpc(rpc); - setCaption(caption); - handlers = new HashMap<String, EventListener>(); - setDefaultHandlers(); - currentCalendar.setTime(new Date()); - setEventProvider(eventProvider); - getState().firstDayOfWeek = firstDay; - getState().lastVisibleDayOfWeek = lastDay; - getState().firstHourOfDay = firstHour; - getState().lastHourOfDay = lastHour; - setTimeFormat(null); - - } - - @Override - public CalendarState getState() { - return (CalendarState) super.getState(); - } - - @Override - protected CalendarState getState(boolean markAsDirty) { - return (CalendarState) super.getState(markAsDirty); - } - - @Override - public void beforeClientResponse(boolean initial) { - super.beforeClientResponse(initial); - - initCalendarWithLocale(); - - getState().format24H = TimeFormat.Format24H == getTimeFormat(); - setupDaysAndActions(); - setupCalendarEvents(); - rpc.scroll(scrollTop); - } - - /** - * Set all the wanted default handlers here. This is always called after - * constructing this object. All other events have default handlers except - * range and event click. - */ - protected void setDefaultHandlers() { - setHandler(new BasicBackwardHandler()); - setHandler(new BasicForwardHandler()); - setHandler(new BasicWeekClickHandler()); - setHandler(new BasicDateClickHandler()); - setHandler(new BasicEventMoveHandler()); - setHandler(new BasicEventResizeHandler()); - } - - /** - * Gets the calendar's start date. - * - * @return First visible date. - */ - public Date getStartDate() { - if (startDate == null) { - currentCalendar.set(java.util.Calendar.MILLISECOND, 0); - currentCalendar.set(java.util.Calendar.SECOND, 0); - currentCalendar.set(java.util.Calendar.MINUTE, 0); - currentCalendar.set(java.util.Calendar.HOUR_OF_DAY, 0); - currentCalendar.set(java.util.Calendar.DAY_OF_WEEK, - currentCalendar.getFirstDayOfWeek()); - return currentCalendar.getTime(); - } - return startDate; - } - - /** - * Sets start date for the calendar. This and {@link #setEndDate(Date)} - * control the range of dates visible on the component. The default range is - * one week. - * - * @param date - * First visible date to show. - */ - public void setStartDate(Date date) { - if (!date.equals(startDate)) { - startDate = date; - markAsDirty(); - } - } - - /** - * Gets the calendar's end date. - * - * @return Last visible date. - */ - public Date getEndDate() { - if (endDate == null) { - currentCalendar.set(java.util.Calendar.MILLISECOND, 0); - currentCalendar.set(java.util.Calendar.SECOND, 59); - currentCalendar.set(java.util.Calendar.MINUTE, 59); - currentCalendar.set(java.util.Calendar.HOUR_OF_DAY, 23); - currentCalendar.set(java.util.Calendar.DAY_OF_WEEK, - currentCalendar.getFirstDayOfWeek() + 6); - return currentCalendar.getTime(); - } - return endDate; - } - - /** - * Sets end date for the calendar. Starting from startDate, only six weeks - * will be shown if duration to endDate is longer than six weeks. - * - * This and {@link #setStartDate(Date)} control the range of dates visible - * on the component. The default range is one week. - * - * @param date - * Last visible date to show. - */ - public void setEndDate(Date date) { - if (startDate != null && startDate.after(date)) { - startDate = (Date) date.clone(); - markAsDirty(); - } else if (!date.equals(endDate)) { - endDate = date; - markAsDirty(); - } - } - - /** - * Sets the locale to be used in the Calendar component. - * - * @see com.vaadin.ui.AbstractComponent#setLocale(java.util.Locale) - */ - @Override - public void setLocale(Locale newLocale) { - super.setLocale(newLocale); - initCalendarWithLocale(); - } - - /** - * Initialize the java calendar instance with the current locale and - * timezone. - */ - private void initCalendarWithLocale() { - if (timezone != null) { - currentCalendar = java.util.Calendar.getInstance(timezone, - getLocale()); - - } else { - currentCalendar = java.util.Calendar.getInstance(getLocale()); - } - - if (customFirstDayOfWeek != null) { - currentCalendar.setFirstDayOfWeek(customFirstDayOfWeek); - } - } - - private void setupCalendarEvents() { - int durationInDays = (int) (((endDate.getTime()) - startDate.getTime()) - / DateConstants.DAYINMILLIS); - durationInDays++; - if (durationInDays > 60) { - throw new RuntimeException( - "Daterange is too big (max 60) = " + durationInDays); - } - - Date firstDateToShow = expandStartDate(startDate, durationInDays > 7); - Date lastDateToShow = expandEndDate(endDate, durationInDays > 7); - - currentCalendar.setTime(firstDateToShow); - events = getEventProvider().getEvents(firstDateToShow, lastDateToShow); - - List<CalendarState.Event> calendarStateEvents = new ArrayList<CalendarState.Event>(); - if (events != null) { - for (int i = 0; i < events.size(); i++) { - CalendarEvent e = events.get(i); - CalendarState.Event event = new CalendarState.Event(); - event.index = i; - event.caption = e.getCaption() == null ? "" : e.getCaption(); - event.dateFrom = df_date.format(e.getStart()); - event.dateTo = df_date.format(e.getEnd()); - event.timeFrom = df_time.format(e.getStart()); - event.timeTo = df_time.format(e.getEnd()); - event.description = e.getDescription() == null ? "" - : e.getDescription(); - event.styleName = e.getStyleName() == null ? "" - : e.getStyleName(); - event.allDay = e.isAllDay(); - calendarStateEvents.add(event); - } - } - getState().events = calendarStateEvents; - } - - private void setupDaysAndActions() { - // Make sure we have a up-to-date locale - initCalendarWithLocale(); - - CalendarState state = getState(); - - state.firstDayOfWeek = currentCalendar.getFirstDayOfWeek(); - - // If only one is null, throw exception - // If both are null, set defaults - if (startDate == null ^ endDate == null) { - String message = "Schedule cannot be painted without a proper date range.\n"; - if (startDate == null) { - throw new IllegalStateException(message - + "You must set a start date using setStartDate(Date)."); - - } else { - throw new IllegalStateException(message - + "You must set an end date using setEndDate(Date)."); - } - - } else if (startDate == null && endDate == null) { - // set defaults - startDate = getStartDate(); - endDate = getEndDate(); - } - - int durationInDays = (int) (((endDate.getTime()) - startDate.getTime()) - / DateConstants.DAYINMILLIS); - durationInDays++; - if (durationInDays > 60) { - throw new RuntimeException( - "Daterange is too big (max 60) = " + durationInDays); - } - - state.dayNames = getDayNamesShort(); - state.monthNames = getMonthNamesShort(); - - // Use same timezone in all dates this component handles. - // Show "now"-marker in browser within given timezone. - Date now = new Date(); - currentCalendar.setTime(now); - now = currentCalendar.getTime(); - - // Reset time zones for custom date formats - df_date.setTimeZone(currentCalendar.getTimeZone()); - df_time.setTimeZone(currentCalendar.getTimeZone()); - - state.now = (df_date.format(now) + " " + df_time.format(now)); - - Date firstDateToShow = expandStartDate(startDate, durationInDays > 7); - Date lastDateToShow = expandEndDate(endDate, durationInDays > 7); - - currentCalendar.setTime(firstDateToShow); - - DateFormat weeklyCaptionFormatter = getWeeklyCaptionFormatter(); - weeklyCaptionFormatter.setTimeZone(currentCalendar.getTimeZone()); - - Map<CalendarDateRange, Set<Action>> actionMap = new HashMap<CalendarDateRange, Set<Action>>(); - - List<CalendarState.Day> days = new ArrayList<CalendarState.Day>(); - - // Send all dates to client from server. This - // approach was taken because gwt doesn't - // support date localization properly. - while (currentCalendar.getTime().compareTo(lastDateToShow) < 1) { - final Date date = currentCalendar.getTime(); - final CalendarState.Day day = new CalendarState.Day(); - day.date = df_date.format(date); - day.localizedDateFormat = weeklyCaptionFormatter.format(date); - day.dayOfWeek = getDowByLocale(currentCalendar); - day.week = getWeek(currentCalendar); - day.yearOfWeek = getYearOfWeek(currentCalendar); - - days.add(day); - - // Get actions for a specific date - if (actionHandlers != null) { - for (Action.Handler actionHandler : actionHandlers) { - - // Create calendar which omits time - GregorianCalendar cal = new GregorianCalendar(getTimeZone(), - getLocale()); - cal.clear(); - cal.set(currentCalendar.get(java.util.Calendar.YEAR), - currentCalendar.get(java.util.Calendar.MONTH), - currentCalendar.get(java.util.Calendar.DATE)); - - // Get day start and end times - Date start = cal.getTime(); - cal.add(java.util.Calendar.DATE, 1); - cal.add(java.util.Calendar.SECOND, -1); - Date end = cal.getTime(); - - boolean monthView = (durationInDays > 7); - - /** - * If in day or week view add actions for each half-an-hour. - * If in month view add actions for each day - */ - if (monthView) { - setActionsForDay(actionMap, start, end, actionHandler); - } else { - setActionsForEachHalfHour(actionMap, start, end, - actionHandler); - } - - } - } - - currentCalendar.add(java.util.Calendar.DATE, 1); - } - state.days = days; - state.actions = createActionsList(actionMap); - } - - private int getWeek(java.util.Calendar calendar) { - return calendar.get(java.util.Calendar.WEEK_OF_YEAR); - } - - private int getYearOfWeek(java.util.Calendar calendar) { - // Would use calendar.getWeekYear() but it's only available since 1.7. - int week = getWeek(calendar); - int month = calendar.get(java.util.Calendar.MONTH); - int year = calendar.get(java.util.Calendar.YEAR); - - if (week == 1 && month == java.util.Calendar.DECEMBER) { - return year + 1; - } - - return year; - } - - private void setActionsForEachHalfHour( - Map<CalendarDateRange, Set<Action>> actionMap, Date start, Date end, - Action.Handler actionHandler) { - GregorianCalendar cal = new GregorianCalendar(getTimeZone(), - getLocale()); - cal.setTime(start); - while (cal.getTime().before(end)) { - Date s = cal.getTime(); - cal.add(java.util.Calendar.MINUTE, 30); - Date e = cal.getTime(); - CalendarDateRange range = new CalendarDateRange(s, e, - getTimeZone()); - Action[] actions = actionHandler.getActions(range, this); - if (actions != null) { - Set<Action> actionSet = new LinkedHashSet<Action>( - Arrays.asList(actions)); - actionMap.put(range, actionSet); - } - } - } - - private void setActionsForDay(Map<CalendarDateRange, Set<Action>> actionMap, - Date start, Date end, Action.Handler actionHandler) { - CalendarDateRange range = new CalendarDateRange(start, end, - getTimeZone()); - Action[] actions = actionHandler.getActions(range, this); - if (actions != null) { - Set<Action> actionSet = new LinkedHashSet<Action>( - Arrays.asList(actions)); - actionMap.put(range, actionSet); - } - } - - private List<CalendarState.Action> createActionsList( - Map<CalendarDateRange, Set<Action>> actionMap) { - if (actionMap.isEmpty()) { - return null; - } - - List<CalendarState.Action> calendarActions = new ArrayList<CalendarState.Action>(); - - SimpleDateFormat formatter = new SimpleDateFormat( - DateConstants.ACTION_DATE_FORMAT_PATTERN); - formatter.setTimeZone(getTimeZone()); - - for (Entry<CalendarDateRange, Set<Action>> entry : actionMap - .entrySet()) { - CalendarDateRange range = entry.getKey(); - Set<Action> actions = entry.getValue(); - for (Action action : actions) { - String key = actionMapper.key(action); - CalendarState.Action calendarAction = new CalendarState.Action(); - calendarAction.actionKey = key; - calendarAction.caption = action.getCaption(); - setResource(key, action.getIcon()); - calendarAction.iconKey = key; - calendarAction.startDate = formatter.format(range.getStart()); - calendarAction.endDate = formatter.format(range.getEnd()); - calendarActions.add(calendarAction); - } - } - - return calendarActions; - } - - /** - * Gets currently active time format. Value is either TimeFormat.Format12H - * or TimeFormat.Format24H. - * - * @return TimeFormat Format for the time. - */ - public TimeFormat getTimeFormat() { - if (currentTimeFormat == null) { - SimpleDateFormat f; - if (getLocale() == null) { - f = (SimpleDateFormat) SimpleDateFormat - .getTimeInstance(SimpleDateFormat.SHORT); - } else { - f = (SimpleDateFormat) SimpleDateFormat - .getTimeInstance(SimpleDateFormat.SHORT, getLocale()); - } - String p = f.toPattern(); - if (p.indexOf("HH") != -1 || p.indexOf("H") != -1) { - return TimeFormat.Format24H; - } - return TimeFormat.Format12H; - } - return currentTimeFormat; - } - - /** - * Example: <code>setTimeFormat(TimeFormat.Format12H);</code></br> - * Set to null, if you want the format being defined by the locale. - * - * @param format - * Set 12h or 24h format. Default is defined by the locale. - */ - public void setTimeFormat(TimeFormat format) { - currentTimeFormat = format; - markAsDirty(); - } - - /** - * Returns a time zone that is currently used by this component. - * - * @return Component's Time zone - */ - public TimeZone getTimeZone() { - if (timezone == null) { - return currentCalendar.getTimeZone(); - } - return timezone; - } - - /** - * Set time zone that this component will use. Null value sets the default - * time zone. - * - * @param zone - * Time zone to use - */ - public void setTimeZone(TimeZone zone) { - timezone = zone; - if (!currentCalendar.getTimeZone().equals(zone)) { - if (zone == null) { - zone = TimeZone.getDefault(); - } - currentCalendar.setTimeZone(zone); - df_date_time.setTimeZone(zone); - markAsDirty(); - } - } - - /** - * Get the internally used Calendar instance. This is the currently used - * instance of {@link java.util.Calendar} but is bound to change during the - * lifetime of the component. - * - * @return the currently used java calendar - */ - public java.util.Calendar getInternalCalendar() { - return currentCalendar; - } - - /** - * <p> - * This method restricts the weekdays that are shown. This affects both the - * monthly and the weekly view. The general contract is that <b>firstDay < - * lastDay</b>. - * </p> - * - * <p> - * Note that this only affects the rendering process. Events are still - * requested by the dates set by {@link #setStartDate(Date)} and - * {@link #setEndDate(Date)}. - * </p> - * - * @param firstDay - * the first day of the week to show, between 1 and 7 - */ - public void setFirstVisibleDayOfWeek(int firstDay) { - if (this.firstDay != firstDay && firstDay >= 1 && firstDay <= 7 - && getLastVisibleDayOfWeek() >= firstDay) { - this.firstDay = firstDay; - getState().firstVisibleDayOfWeek = firstDay; - } - } - - /** - * Get the first visible day of the week. Returns the weekdays as integers - * represented by {@link java.util.Calendar#DAY_OF_WEEK} - * - * @return An integer representing the week day according to - * {@link java.util.Calendar#DAY_OF_WEEK} - */ - public int getFirstVisibleDayOfWeek() { - return firstDay; - } - - /** - * <p> - * This method restricts the weekdays that are shown. This affects both the - * monthly and the weekly view. The general contract is that <b>firstDay < - * lastDay</b>. - * </p> - * - * <p> - * Note that this only affects the rendering process. Events are still - * requested by the dates set by {@link #setStartDate(Date)} and - * {@link #setEndDate(Date)}. - * </p> - * - * @param lastDay - * the first day of the week to show, between 1 and 7 - */ - public void setLastVisibleDayOfWeek(int lastDay) { - if (this.lastDay != lastDay && lastDay >= 1 && lastDay <= 7 - && getFirstVisibleDayOfWeek() <= lastDay) { - this.lastDay = lastDay; - getState().lastVisibleDayOfWeek = lastDay; - } - } - - /** - * Get the last visible day of the week. Returns the weekdays as integers - * represented by {@link java.util.Calendar#DAY_OF_WEEK} - * - * @return An integer representing the week day according to - * {@link java.util.Calendar#DAY_OF_WEEK} - */ - public int getLastVisibleDayOfWeek() { - return lastDay; - } - - /** - * <p> - * This method restricts the hours that are shown per day. This affects the - * weekly view. The general contract is that <b>firstHour < lastHour</b>. - * </p> - * - * <p> - * Note that this only affects the rendering process. Events are still - * requested by the dates set by {@link #setStartDate(Date)} and - * {@link #setEndDate(Date)}. - * </p> - * - * @param firstHour - * the first hour of the day to show, between 0 and 23 - */ - public void setFirstVisibleHourOfDay(int firstHour) { - if (this.firstHour != firstHour && firstHour >= 0 && firstHour <= 23 - && firstHour <= getLastVisibleHourOfDay()) { - this.firstHour = firstHour; - getState().firstHourOfDay = firstHour; - } - } - - /** - * Returns the first visible hour in the week view. Returns the hour using a - * 24h time format - * - */ - public int getFirstVisibleHourOfDay() { - return firstHour; - } - - /** - * <p> - * This method restricts the hours that are shown per day. This affects the - * weekly view. The general contract is that <b>firstHour < lastHour</b>. - * </p> - * - * <p> - * Note that this only affects the rendering process. Events are still - * requested by the dates set by {@link #setStartDate(Date)} and - * {@link #setEndDate(Date)}. - * </p> - * - * @param lastHour - * the first hour of the day to show, between 0 and 23 - */ - public void setLastVisibleHourOfDay(int lastHour) { - if (this.lastHour != lastHour && lastHour >= 0 && lastHour <= 23 - && lastHour >= getFirstVisibleHourOfDay()) { - this.lastHour = lastHour; - getState().lastHourOfDay = lastHour; - } - } - - /** - * Returns the last visible hour in the week view. Returns the hour using a - * 24h time format - * - */ - public int getLastVisibleHourOfDay() { - return lastHour; - } - - /** - * Gets the date caption format for the weekly view. - * - * @return The pattern used in caption of dates in weekly view. - */ - public String getWeeklyCaptionFormat() { - return weeklyCaptionFormat; - } - - /** - * Sets custom date format for the weekly view. This is the caption of the - * date. Format could be like "mmm MM/dd". - * - * @param dateFormatPattern - * The date caption pattern. - */ - public void setWeeklyCaptionFormat(String dateFormatPattern) { - if ((weeklyCaptionFormat == null && dateFormatPattern != null) - || (weeklyCaptionFormat != null - && !weeklyCaptionFormat.equals(dateFormatPattern))) { - weeklyCaptionFormat = dateFormatPattern; - markAsDirty(); - } - } - - private DateFormat getWeeklyCaptionFormatter() { - if (weeklyCaptionFormat != null) { - return new SimpleDateFormat(weeklyCaptionFormat, getLocale()); - } else { - return SimpleDateFormat.getDateInstance(SimpleDateFormat.SHORT, - getLocale()); - } - } - - /** - * Get the day of week by the given calendar and its locale - * - * @param calendar - * The calendar to use - * @return - */ - private static int getDowByLocale(java.util.Calendar calendar) { - int fow = calendar.get(java.util.Calendar.DAY_OF_WEEK); - - // monday first - if (calendar.getFirstDayOfWeek() == java.util.Calendar.MONDAY) { - fow = (fow == java.util.Calendar.SUNDAY) ? 7 : fow - 1; - } - - return fow; - } - - /** - * Is the user allowed to trigger events which alters the events - * - * @return true if the client is allowed to send changes to server - * @see #isEventClickAllowed() - */ - protected boolean isClientChangeAllowed() { - return !isReadOnly(); - } - - /** - * Is the user allowed to trigger click events. Returns {@code true} by - * default. Subclass can override this method to disallow firing event - * clicks got from the client side. - * - * @return true if the client is allowed to click events - * @see #isClientChangeAllowed() - * @deprecated As of 7.4, override {@link #fireEventClick(Integer)} instead. - */ - @Deprecated - protected boolean isEventClickAllowed() { - return true; - } - - /** - * Fires an event when the user selecing moving forward/backward in the - * calendar. - * - * @param forward - * True if the calendar moved forward else backward is assumed. - */ - protected void fireNavigationEvent(boolean forward) { - if (forward) { - fireEvent(new ForwardEvent(this)); - } else { - fireEvent(new BackwardEvent(this)); - } - } - - /** - * Fires an event move event to all server side move listerners - * - * @param index - * The index of the event in the events list - * @param newFromDatetime - * The changed from date time - */ - protected void fireEventMove(int index, Date newFromDatetime) { - MoveEvent event = new MoveEvent(this, events.get(index), - newFromDatetime); - - if (calendarEventProvider instanceof EventMoveHandler) { - // Notify event provider if it is an event move handler - ((EventMoveHandler) calendarEventProvider).eventMove(event); - } - - // Notify event move handler attached by using the - // setHandler(EventMoveHandler) method - fireEvent(event); - } - - /** - * Fires event when a week was clicked in the calendar. - * - * @param week - * The week that was clicked - * @param year - * The year of the week - */ - protected void fireWeekClick(int week, int year) { - fireEvent(new WeekClick(this, week, year)); - } - - /** - * Fires event when a date was clicked in the calendar. Uses an existing - * event from the event cache. - * - * @param index - * The index of the event in the event cache. - */ - protected void fireEventClick(Integer index) { - fireEvent(new EventClick(this, events.get(index))); - } - - /** - * Fires event when a date was clicked in the calendar. Creates a new event - * for the date and passes it to the listener. - * - * @param date - * The date and time that was clicked - */ - protected void fireDateClick(Date date) { - fireEvent(new DateClickEvent(this, date)); - } - - /** - * Fires an event range selected event. The event is fired when a user - * highlights an area in the calendar. The highlighted areas start and end - * dates are returned as arguments. - * - * @param from - * The start date and time of the highlighted area - * @param to - * The end date and time of the highlighted area - * @param monthlyMode - * Is the calendar in monthly mode - */ - protected void fireRangeSelect(Date from, Date to, boolean monthlyMode) { - fireEvent(new RangeSelectEvent(this, from, to, monthlyMode)); - } - - /** - * Fires an event resize event. The event is fired when a user resizes the - * event in the calendar causing the time range of the event to increase or - * decrease. The new start and end times are returned as arguments to this - * method. - * - * @param index - * The index of the event in the event cache - * @param startTime - * The new start date and time of the event - * @param endTime - * The new end date and time of the event - */ - protected void fireEventResize(int index, Date startTime, Date endTime) { - EventResize event = new EventResize(this, events.get(index), startTime, - endTime); - - if (calendarEventProvider instanceof EventResizeHandler) { - // Notify event provider if it is an event resize handler - ((EventResizeHandler) calendarEventProvider).eventResize(event); - } - - // Notify event resize handler attached by using the - // setHandler(EventMoveHandler) method - fireEvent(event); - } - - /** - * Localized display names for week days starting from sunday. Returned - * array's length is always 7. - * - * @return Array of localized weekday names. - */ - protected String[] getDayNamesShort() { - DateFormatSymbols s = new DateFormatSymbols(getLocale()); - return Arrays.copyOfRange(s.getWeekdays(), 1, 8); - } - - /** - * Localized display names for months starting from January. Returned - * array's length is always 12. - * - * @return Array of localized month names. - */ - protected String[] getMonthNamesShort() { - DateFormatSymbols s = new DateFormatSymbols(getLocale()); - return Arrays.copyOf(s.getShortMonths(), 12); - } - - /** - * Gets a date that is first day in the week that target given date belongs - * to. - * - * @param date - * Target date - * @return Date that is first date in same week that given date is. - */ - protected Date getFirstDateForWeek(Date date) { - int firstDayOfWeek = currentCalendar.getFirstDayOfWeek(); - currentCalendar.setTime(date); - while (firstDayOfWeek != currentCalendar - .get(java.util.Calendar.DAY_OF_WEEK)) { - currentCalendar.add(java.util.Calendar.DATE, -1); - } - return currentCalendar.getTime(); - } - - /** - * Gets a date that is last day in the week that target given date belongs - * to. - * - * @param date - * Target date - * @return Date that is last date in same week that given date is. - */ - protected Date getLastDateForWeek(Date date) { - currentCalendar.setTime(date); - currentCalendar.add(java.util.Calendar.DATE, 1); - int firstDayOfWeek = currentCalendar.getFirstDayOfWeek(); - // Roll to weeks last day using firstdayofweek. Roll until FDofW is - // found and then roll back one day. - while (firstDayOfWeek != currentCalendar - .get(java.util.Calendar.DAY_OF_WEEK)) { - currentCalendar.add(java.util.Calendar.DATE, 1); - } - currentCalendar.add(java.util.Calendar.DATE, -1); - return currentCalendar.getTime(); - } - - /** - * Calculates the end time of the day using the given calendar and date - * - * @param date - * @param calendar - * the calendar instance to be used in the calculation. The given - * instance is unchanged in this operation. - * @return the given date, with time set to the end of the day - */ - private static Date getEndOfDay(java.util.Calendar calendar, Date date) { - java.util.Calendar calendarClone = (java.util.Calendar) calendar - .clone(); - - calendarClone.setTime(date); - calendarClone.set(java.util.Calendar.MILLISECOND, - calendarClone.getActualMaximum(java.util.Calendar.MILLISECOND)); - calendarClone.set(java.util.Calendar.SECOND, - calendarClone.getActualMaximum(java.util.Calendar.SECOND)); - calendarClone.set(java.util.Calendar.MINUTE, - calendarClone.getActualMaximum(java.util.Calendar.MINUTE)); - calendarClone.set(java.util.Calendar.HOUR, - calendarClone.getActualMaximum(java.util.Calendar.HOUR)); - calendarClone.set(java.util.Calendar.HOUR_OF_DAY, - calendarClone.getActualMaximum(java.util.Calendar.HOUR_OF_DAY)); - - return calendarClone.getTime(); - } - - /** - * Calculates the end time of the day using the given calendar and date - * - * @param date - * @param calendar - * the calendar instance to be used in the calculation. The given - * instance is unchanged in this operation. - * @return the given date, with time set to the end of the day - */ - private static Date getStartOfDay(java.util.Calendar calendar, Date date) { - java.util.Calendar calendarClone = (java.util.Calendar) calendar - .clone(); - - calendarClone.setTime(date); - calendarClone.set(java.util.Calendar.MILLISECOND, 0); - calendarClone.set(java.util.Calendar.SECOND, 0); - calendarClone.set(java.util.Calendar.MINUTE, 0); - calendarClone.set(java.util.Calendar.HOUR, 0); - calendarClone.set(java.util.Calendar.HOUR_OF_DAY, 0); - - return calendarClone.getTime(); - } - - /** - * Finds the first day of the week and returns a day representing the start - * of that day - * - * @param start - * The actual date - * @param expandToFullWeek - * Should the returned date be moved to the start of the week - * @return If expandToFullWeek is set then it returns the first day of the - * week, else it returns a clone of the actual date with the time - * set to the start of the day - */ - protected Date expandStartDate(Date start, boolean expandToFullWeek) { - // If the duration is more than week, use monthly view and get startweek - // and endweek. Example if views daterange is from tuesday to next weeks - // wednesday->expand to monday to nextweeks sunday. If firstdayofweek = - // monday - if (expandToFullWeek) { - start = getFirstDateForWeek(start); - - } else { - start = (Date) start.clone(); - } - - // Always expand to the start of the first day to the end of the last - // day - start = getStartOfDay(currentCalendar, start); - - return start; - } - - /** - * Finds the last day of the week and returns a day representing the end of - * that day - * - * @param end - * The actual date - * @param expandToFullWeek - * Should the returned date be moved to the end of the week - * @return If expandToFullWeek is set then it returns the last day of the - * week, else it returns a clone of the actual date with the time - * set to the end of the day - */ - protected Date expandEndDate(Date end, boolean expandToFullWeek) { - // If the duration is more than week, use monthly view and get startweek - // and endweek. Example if views daterange is from tuesday to next weeks - // wednesday->expand to monday to nextweeks sunday. If firstdayofweek = - // monday - if (expandToFullWeek) { - end = getLastDateForWeek(end); - - } else { - end = (Date) end.clone(); - } - - // Always expand to the start of the first day to the end of the last - // day - end = getEndOfDay(currentCalendar, end); - - return end; - } - - /** - * Set the {@link com.vaadin.addon.calendar.event.CalendarEventProvider - * CalendarEventProvider} to be used with this calendar. The EventProvider - * is used to query for events to show, and must be non-null. By default a - * {@link com.vaadin.addon.calendar.event.BasicEventProvider - * BasicEventProvider} is used. - * - * @param calendarEventProvider - * the calendarEventProvider to set. Cannot be null. - */ - public void setEventProvider(CalendarEventProvider calendarEventProvider) { - if (calendarEventProvider == null) { - throw new IllegalArgumentException( - "Calendar event provider cannot be null"); - } - - // remove old listener - if (getEventProvider() instanceof EventSetChangeNotifier) { - ((EventSetChangeNotifier) getEventProvider()) - .removeEventSetChangeListener(this); - } - - this.calendarEventProvider = calendarEventProvider; - - // add new listener - if (calendarEventProvider instanceof EventSetChangeNotifier) { - ((EventSetChangeNotifier) calendarEventProvider) - .addEventSetChangeListener(this); - } - } - - /** - * @return the {@link com.vaadin.addon.calendar.event.CalendarEventProvider - * CalendarEventProvider} currently used - */ - public CalendarEventProvider getEventProvider() { - return calendarEventProvider; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.calendar.ui.CalendarEvents.EventChangeListener# - * eventChange (com.vaadin.addon.calendar.ui.CalendarEvents.EventChange) - */ - @Override - public void eventSetChange(EventSetChangeEvent changeEvent) { - // sanity check - if (calendarEventProvider == changeEvent.getProvider()) { - markAsDirty(); - } - } - - /** - * Set the handler for the given type information. Mirrors - * {@link #addListener(String, Class, Object, Method) addListener} from - * AbstractComponent - * - * @param eventId - * A unique id for the event. Usually one of - * {@link CalendarEventId} - * @param eventType - * The class of the event, most likely a subclass of - * {@link CalendarComponentEvent} - * @param listener - * A listener that listens to the given event - * @param listenerMethod - * The method on the lister to call when the event is triggered - */ - protected void setHandler(String eventId, Class<?> eventType, - EventListener listener, Method listenerMethod) { - if (handlers.get(eventId) != null) { - removeListener(eventId, eventType, handlers.get(eventId)); - handlers.remove(eventId); - } - - if (listener != null) { - addListener(eventId, eventType, listener, listenerMethod); - handlers.put(eventId, listener); - } - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.ui.CalendarComponentEvents.NavigationNotifier - * #addListener - * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.ForwardHandler) - */ - @Override - public void setHandler(ForwardHandler listener) { - setHandler(ForwardEvent.EVENT_ID, ForwardEvent.class, listener, - ForwardHandler.forwardMethod); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.ui.CalendarComponentEvents.NavigationNotifier - * #addListener - * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.BackwardHandler) - */ - @Override - public void setHandler(BackwardHandler listener) { - setHandler(BackwardEvent.EVENT_ID, BackwardEvent.class, listener, - BackwardHandler.backwardMethod); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.ui.CalendarComponentEvents.NavigationNotifier - * #addListener - * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.DateClickHandler) - */ - @Override - public void setHandler(DateClickHandler listener) { - setHandler(DateClickEvent.EVENT_ID, DateClickEvent.class, listener, - DateClickHandler.dateClickMethod); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.ui.CalendarComponentEvents.NavigationNotifier - * #addListener - * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventClickHandler) - */ - @Override - public void setHandler(EventClickHandler listener) { - setHandler(EventClick.EVENT_ID, EventClick.class, listener, - EventClickHandler.eventClickMethod); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.ui.CalendarComponentEvents.NavigationNotifier - * #addListener - * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.WeekClickHandler) - */ - @Override - public void setHandler(WeekClickHandler listener) { - setHandler(WeekClick.EVENT_ID, WeekClick.class, listener, - WeekClickHandler.weekClickMethod); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventResizeNotifier - * #addListener - * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventResizeHandler - * ) - */ - @Override - public void setHandler(EventResizeHandler listener) { - setHandler(EventResize.EVENT_ID, EventResize.class, listener, - EventResizeHandler.eventResizeMethod); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.ui.CalendarComponentEvents.RangeSelectNotifier - * #addListener - * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.RangeSelectHandler - * ) - */ - @Override - public void setHandler(RangeSelectHandler listener) { - setHandler(RangeSelectEvent.EVENT_ID, RangeSelectEvent.class, listener, - RangeSelectHandler.rangeSelectMethod); - - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventMoveNotifier - * #addListener - * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventMoveHandler) - */ - @Override - public void setHandler(EventMoveHandler listener) { - setHandler(MoveEvent.EVENT_ID, MoveEvent.class, listener, - EventMoveHandler.eventMoveMethod); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.calendar.ui.CalendarComponentEvents. - * CalendarEventNotifier #getHandler(java.lang.String) - */ - @Override - public EventListener getHandler(String eventId) { - return handlers.get(eventId); - } - - /** - * Get the currently active drop handler - */ - @Override - public DropHandler getDropHandler() { - return dropHandler; - } - - /** - * Set the drop handler for the calendar See {@link DropHandler} for - * implementation details. - * - * @param dropHandler - * The drop handler to set - */ - public void setDropHandler(DropHandler dropHandler) { - this.dropHandler = dropHandler; - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.event.dd.DropTarget#translateDropTargetDetails(java.util.Map) - */ - @Override - public TargetDetails translateDropTargetDetails( - Map<String, Object> clientVariables) { - Map<String, Object> serverVariables = new HashMap<String, Object>(); - - if (clientVariables.containsKey("dropSlotIndex")) { - int slotIndex = (Integer) clientVariables.get("dropSlotIndex"); - int dayIndex = (Integer) clientVariables.get("dropDayIndex"); - - currentCalendar.setTime(getStartOfDay(currentCalendar, startDate)); - currentCalendar.add(java.util.Calendar.DATE, dayIndex); - - // change this if slot length is modified - currentCalendar.add(java.util.Calendar.MINUTE, slotIndex * 30); - - serverVariables.put("dropTime", currentCalendar.getTime()); - - } else { - int dayIndex = (Integer) clientVariables.get("dropDayIndex"); - currentCalendar.setTime(expandStartDate(startDate, true)); - currentCalendar.add(java.util.Calendar.DATE, dayIndex); - serverVariables.put("dropDay", currentCalendar.getTime()); - } - serverVariables.put("mouseEvent", clientVariables.get("mouseEvent")); - - CalendarTargetDetails td = new CalendarTargetDetails(serverVariables, - this); - td.setHasDropTime(clientVariables.containsKey("dropSlotIndex")); - - return td; - } - - /** - * Sets a container as a data source for the events in the calendar. - * Equivalent for doing - * <code>Calendar.setEventProvider(new ContainerEventProvider(container))</code> - * - * Use this method if you are adding a container which uses the default - * property ids like {@link BeanItemContainer} for instance. If you are - * using custom properties instead use - * {@link Calendar#setContainerDataSource(com.vaadin.data.Container.Indexed, Object, Object, Object, Object, Object)} - * - * Please note that the container must be sorted by date! - * - * @param container - * The container to use as a datasource - */ - public void setContainerDataSource(Container.Indexed container) { - ContainerEventProvider provider = new ContainerEventProvider(container); - provider.addEventSetChangeListener( - new CalendarEventProvider.EventSetChangeListener() { - @Override - public void eventSetChange( - EventSetChangeEvent changeEvent) { - // Repaint if events change - markAsDirty(); - } - }); - provider.addEventChangeListener(new EventChangeListener() { - @Override - public void eventChange(EventChangeEvent changeEvent) { - // Repaint if event changes - markAsDirty(); - } - }); - setEventProvider(provider); - } - - /** - * Sets a container as a data source for the events in the calendar. - * Equivalent for doing - * <code>Calendar.setEventProvider(new ContainerEventProvider(container))</code> - * - * Please note that the container must be sorted by date! - * - * @param container - * The container to use as a data source - * @param captionProperty - * The property that has the caption, null if no caption property - * is present - * @param descriptionProperty - * The property that has the description, null if no description - * property is present - * @param startDateProperty - * The property that has the starting date - * @param endDateProperty - * The property that has the ending date - * @param styleNameProperty - * The property that has the stylename, null if no stylname - * property is present - */ - public void setContainerDataSource(Container.Indexed container, - Object captionProperty, Object descriptionProperty, - Object startDateProperty, Object endDateProperty, - Object styleNameProperty) { - ContainerEventProvider provider = new ContainerEventProvider(container); - provider.setCaptionProperty(captionProperty); - provider.setDescriptionProperty(descriptionProperty); - provider.setStartDateProperty(startDateProperty); - provider.setEndDateProperty(endDateProperty); - provider.setStyleNameProperty(styleNameProperty); - provider.addEventSetChangeListener( - new CalendarEventProvider.EventSetChangeListener() { - @Override - public void eventSetChange( - EventSetChangeEvent changeEvent) { - // Repaint if events change - markAsDirty(); - } - }); - provider.addEventChangeListener(new EventChangeListener() { - @Override - public void eventChange(EventChangeEvent changeEvent) { - // Repaint if event changes - markAsDirty(); - } - }); - setEventProvider(provider); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.event.CalendarEventProvider#getEvents(java. - * util.Date, java.util.Date) - */ - @Override - public List<CalendarEvent> getEvents(Date startDate, Date endDate) { - return getEventProvider().getEvents(startDate, endDate); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.event.CalendarEditableEventProvider#addEvent - * (com.vaadin.addon.calendar.event.CalendarEvent) - */ - @Override - public void addEvent(CalendarEvent event) { - if (getEventProvider() instanceof CalendarEditableEventProvider) { - CalendarEditableEventProvider provider = (CalendarEditableEventProvider) getEventProvider(); - provider.addEvent(event); - markAsDirty(); - } else { - throw new UnsupportedOperationException( - "Event provider does not support adding events"); - } - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.event.CalendarEditableEventProvider#removeEvent - * (com.vaadin.addon.calendar.event.CalendarEvent) - */ - @Override - public void removeEvent(CalendarEvent event) { - if (getEventProvider() instanceof CalendarEditableEventProvider) { - CalendarEditableEventProvider provider = (CalendarEditableEventProvider) getEventProvider(); - provider.removeEvent(event); - markAsDirty(); - } else { - throw new UnsupportedOperationException( - "Event provider does not support removing events"); - } - } - - /** - * Adds an action handler to the calender that handles event produced by the - * context menu. - * - * <p> - * The {@link Handler#getActions(Object, Object)} parameters depend on what - * view the Calendar is in: - * <ul> - * <li>If the Calendar is in <i>Day or Week View</i> then the target - * parameter will be a {@link CalendarDateRange} with a range of - * half-an-hour. The {@link Handler#getActions(Object, Object)} method will - * be called once per half-hour slot.</li> - * <li>If the Calendar is in <i>Month View</i> then the target parameter - * will be a {@link CalendarDateRange} with a range of one day. The - * {@link Handler#getActions(Object, Object)} will be called once for each - * day. - * </ul> - * The Dates passed into the {@link CalendarDateRange} are in the same - * timezone as the calendar is. - * </p> - * - * <p> - * The {@link Handler#handleAction(Action, Object, Object)} parameters - * depend on what the context menu is called upon: - * <ul> - * <li>If the context menu is called upon an event then the target parameter - * is the event, i.e. instanceof {@link CalendarEvent}</li> - * <li>If the context menu is called upon an empty slot then the target is a - * {@link Date} representing that slot - * </ul> - * </p> - */ - @Override - public void addActionHandler(Handler actionHandler) { - if (actionHandler != null) { - if (actionHandlers == null) { - actionHandlers = new LinkedList<Action.Handler>(); - actionMapper = new KeyMapper<Action>(); - } - if (!actionHandlers.contains(actionHandler)) { - actionHandlers.add(actionHandler); - markAsDirty(); - } - } - } - - /** - * Is the calendar in a mode where all days of the month is shown - * - * @return Returns true if calendar is in monthly mode and false if it is in - * weekly mode - */ - public boolean isMonthlyMode() { - CalendarState state = getState(false); - if (state.days != null) { - return state.days.size() > 7; - } else { - // Default mode - return true; - } - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.event.Action.Container#removeActionHandler(com.vaadin.event - * .Action.Handler) - */ - @Override - public void removeActionHandler(Handler actionHandler) { - if (actionHandlers != null && actionHandlers.contains(actionHandler)) { - actionHandlers.remove(actionHandler); - if (actionHandlers.isEmpty()) { - actionHandlers = null; - actionMapper = null; - } - markAsDirty(); - } - } - - private class CalendarServerRpcImpl implements CalendarServerRpc { - - @Override - public void eventMove(int eventIndex, String newDate) { - if (!isClientChangeAllowed()) { - return; - } - if (newDate != null) { - try { - Date d = df_date_time.parse(newDate); - if (eventIndex >= 0 && eventIndex < events.size() - && events.get(eventIndex) != null) { - fireEventMove(eventIndex, d); - } - } catch (ParseException e) { - getLogger().log(Level.WARNING, e.getMessage()); - } - } - } - - @Override - public void rangeSelect(String range) { - if (!isClientChangeAllowed()) { - return; - } - - if (range != null && range.length() > 14 && range.contains("TO")) { - String[] dates = range.split("TO"); - try { - Date d1 = df_date.parse(dates[0]); - Date d2 = df_date.parse(dates[1]); - - fireRangeSelect(d1, d2, true); - - } catch (ParseException e) { - // NOP - } - } else if (range != null && range.length() > 12 - && range.contains(":")) { - String[] dates = range.split(":"); - if (dates.length == 3) { - try { - Date d = df_date.parse(dates[0]); - currentCalendar.setTime(d); - int startMinutes = Integer.parseInt(dates[1]); - int endMinutes = Integer.parseInt(dates[2]); - currentCalendar.add(java.util.Calendar.MINUTE, - startMinutes); - Date start = currentCalendar.getTime(); - currentCalendar.add(java.util.Calendar.MINUTE, - endMinutes - startMinutes); - Date end = currentCalendar.getTime(); - fireRangeSelect(start, end, false); - } catch (ParseException e) { - // NOP - } catch (NumberFormatException e) { - // NOP - } - } - } - } - - @Override - public void forward() { - fireEvent(new ForwardEvent(Calendar.this)); - } - - @Override - public void backward() { - fireEvent(new BackwardEvent(Calendar.this)); - } - - @Override - public void dateClick(String date) { - if (date != null && date.length() > 6) { - try { - Date d = df_date.parse(date); - fireDateClick(d); - } catch (ParseException e) { - } - } - } - - @Override - public void weekClick(String event) { - if (event.length() > 0 && event.contains("w")) { - String[] splitted = event.split("w"); - if (splitted.length == 2) { - try { - int yr = Integer.parseInt(splitted[0]); - int week = Integer.parseInt(splitted[1]); - fireWeekClick(week, yr); - } catch (NumberFormatException e) { - // NOP - } - } - } - } - - @Override - public void eventClick(int eventIndex) { - if (!isEventClickAllowed()) { - return; - } - if (eventIndex >= 0 && eventIndex < events.size() - && events.get(eventIndex) != null) { - fireEventClick(eventIndex); - } - } - - @Override - public void eventResize(int eventIndex, String newStartDate, - String newEndDate) { - if (!isClientChangeAllowed()) { - return; - } - if (newStartDate != null && !"".equals(newStartDate) - && newEndDate != null && !"".equals(newEndDate)) { - try { - Date newStartTime = df_date_time.parse(newStartDate); - Date newEndTime = df_date_time.parse(newEndDate); - - fireEventResize(eventIndex, newStartTime, newEndTime); - } catch (ParseException e) { - // NOOP - } - } - } - - @Override - public void scroll(int scrollPosition) { - scrollTop = scrollPosition; - markAsDirty(); - } - - @Override - public void actionOnEmptyCell(String actionKey, String startDate, - String endDate) { - Action action = actionMapper.get(actionKey); - SimpleDateFormat formatter = new SimpleDateFormat( - DateConstants.ACTION_DATE_FORMAT_PATTERN); - formatter.setTimeZone(getTimeZone()); - try { - Date start = formatter.parse(startDate); - for (Action.Handler ah : actionHandlers) { - ah.handleAction(action, Calendar.this, start); - } - - } catch (ParseException e) { - getLogger().log(Level.WARNING, - "Could not parse action date string"); - } - - } - - @Override - public void actionOnEvent(String actionKey, String startDate, - String endDate, int eventIndex) { - Action action = actionMapper.get(actionKey); - SimpleDateFormat formatter = new SimpleDateFormat( - DateConstants.ACTION_DATE_FORMAT_PATTERN); - formatter.setTimeZone(getTimeZone()); - for (Action.Handler ah : actionHandlers) { - ah.handleAction(action, Calendar.this, events.get(eventIndex)); - } - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.server.VariableOwner#changeVariables(java.lang.Object, - * java.util.Map) - */ - @Override - public void changeVariables(Object source, Map<String, Object> variables) { - /* - * Only defined to fulfill the LegacyComponent interface used for - * calendar drag & drop. No implementation required. - */ - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.ui.LegacyComponent#paintContent(com.vaadin.server.PaintTarget) - */ - @Override - public void paintContent(PaintTarget target) throws PaintException { - if (dropHandler != null) { - dropHandler.getAcceptCriterion().paint(target); - } - } - - /** - * Sets whether the event captions are rendered as HTML. - * <p> - * If set to true, the captions are rendered in the browser as HTML and the - * developer is responsible for ensuring no harmful HTML is used. If set to - * false, the caption is rendered in the browser as plain text. - * <p> - * The default is false, i.e. to render that caption as plain text. - * - * @param captionAsHtml - * true if the captions are rendered as HTML, false if rendered - * as plain text - */ - public void setEventCaptionAsHtml(boolean eventCaptionAsHtml) { - getState().eventCaptionAsHtml = eventCaptionAsHtml; - } - - /** - * Checks whether event captions are rendered as HTML - * <p> - * The default is false, i.e. to render that caption as plain text. - * - * @return true if the captions are rendered as HTML, false if rendered as - * plain text - */ - public boolean isEventCaptionAsHtml() { - return getState(false).eventCaptionAsHtml; - } - - @Override - public void readDesign(Element design, DesignContext designContext) { - super.readDesign(design, designContext); - - Attributes attr = design.attributes(); - if (design.hasAttr("time-format")) { - setTimeFormat(TimeFormat.valueOf( - "Format" + design.attr("time-format").toUpperCase())); - } - - if (design.hasAttr("start-date")) { - setStartDate(DesignAttributeHandler.readAttribute("start-date", - attr, Date.class)); - } - if (design.hasAttr("end-date")) { - setEndDate(DesignAttributeHandler.readAttribute("end-date", attr, - Date.class)); - } - }; - - @Override - public void writeDesign(Element design, DesignContext designContext) { - super.writeDesign(design, designContext); - - if (currentTimeFormat != null) { - design.attr("time-format", - (currentTimeFormat == TimeFormat.Format12H ? "12h" - : "24h")); - } - if (startDate != null) { - design.attr("start-date", df_date.format(getStartDate())); - } - if (endDate != null) { - design.attr("end-date", df_date.format(getEndDate())); - } - if (!getTimeZone().equals(TimeZone.getDefault())) { - design.attr("time-zone", getTimeZone().getID()); - } - } - - @Override - protected Collection<String> getCustomAttributes() { - Collection<String> customAttributes = super.getCustomAttributes(); - customAttributes.add("time-format"); - customAttributes.add("start-date"); - customAttributes.add("end-date"); - return customAttributes; - } - - /** - * Allow setting first day of week independent of Locale. Set to null if you - * want first day of week being defined by the locale - * - * @since 7.6 - * @param dayOfWeek - * any of java.util.Calendar.SUNDAY..java.util.Calendar.SATURDAY - * or null to revert to default first day of week by locale - */ - public void setFirstDayOfWeek(Integer dayOfWeek) { - int minimalSupported = java.util.Calendar.SUNDAY; - int maximalSupported = java.util.Calendar.SATURDAY; - if (dayOfWeek != null && (dayOfWeek < minimalSupported - || dayOfWeek > maximalSupported)) { - throw new IllegalArgumentException(String.format( - "Day of week must be between %s and %s. Actually received: %s", - minimalSupported, maximalSupported, dayOfWeek)); - } - customFirstDayOfWeek = dayOfWeek; - markAsDirty(); - } -} diff --git a/server/src/main/java/com/vaadin/ui/ColorPicker.java b/server/src/main/java/com/vaadin/ui/ColorPicker.java deleted file mode 100644 index 67002373d0..0000000000 --- a/server/src/main/java/com/vaadin/ui/ColorPicker.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui; - -import com.vaadin.shared.ui.colorpicker.Color; - -/** - * A class that defines default (button-like) implementation for a color picker - * component. - * - * @since 7.0.0 - * - * @see ColorPickerArea - * - */ -public class ColorPicker extends AbstractColorPicker { - - /** - * Instantiates a new color picker. - */ - public ColorPicker() { - super(); - } - - /** - * Instantiates a new color picker. - * - * @param popupCaption - * caption of the color select popup - */ - public ColorPicker(String popupCaption) { - super(popupCaption); - } - - /** - * Instantiates a new color picker. - * - * @param popupCaption - * caption of the color select popup - * @param initialColor - * the initial color - */ - public ColorPicker(String popupCaption, Color initialColor) { - super(popupCaption, initialColor); - setDefaultCaptionEnabled(true); - } - - @Override - protected void setDefaultStyles() { - setPrimaryStyleName(STYLENAME_BUTTON); - addStyleName(STYLENAME_DEFAULT); - } - -} diff --git a/server/src/main/java/com/vaadin/ui/ColorPickerArea.java b/server/src/main/java/com/vaadin/ui/ColorPickerArea.java deleted file mode 100644 index c4f3971259..0000000000 --- a/server/src/main/java/com/vaadin/ui/ColorPickerArea.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui; - -import com.vaadin.shared.ui.colorpicker.Color; - -/** - * A class that defines area-like implementation for a color picker component. - * - * @since 7.0.0 - * - * @see ColorPicker - * - */ -public class ColorPickerArea extends AbstractColorPicker { - - /** - * Instantiates a new color picker. - */ - public ColorPickerArea() { - super(); - } - - /** - * Instantiates a new color picker. - * - * @param popupCaption - * caption of the color select popup - */ - public ColorPickerArea(String popupCaption) { - super(popupCaption); - } - - /** - * Instantiates a new color picker. - * - * @param popupCaption - * caption of the color select popup - * @param initialColor - * the initial color - */ - public ColorPickerArea(String popupCaption, Color initialColor) { - super(popupCaption, initialColor); - setDefaultCaptionEnabled(false); - } - - @Override - protected void setDefaultStyles() { - // state already has correct default - } - - @Override - public void beforeClientResponse(boolean initial) { - super.beforeClientResponse(initial); - - if ("".equals(getState().height)) { - getState().height = "30px"; - } - if ("".equals(getState().width)) { - getState().width = "30px"; - } - } - -} diff --git a/server/src/main/java/com/vaadin/ui/ComboBox.java b/server/src/main/java/com/vaadin/ui/ComboBox.java deleted file mode 100644 index a78823d9a3..0000000000 --- a/server/src/main/java/com/vaadin/ui/ComboBox.java +++ /dev/null @@ -1,925 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import com.vaadin.data.Container; -import com.vaadin.data.util.filter.SimpleStringFilter; -import com.vaadin.event.FieldEvents; -import com.vaadin.event.FieldEvents.BlurEvent; -import com.vaadin.event.FieldEvents.BlurListener; -import com.vaadin.event.FieldEvents.FocusAndBlurServerRpcImpl; -import com.vaadin.event.FieldEvents.FocusEvent; -import com.vaadin.event.FieldEvents.FocusListener; -import com.vaadin.server.PaintException; -import com.vaadin.server.PaintTarget; -import com.vaadin.server.Resource; -import com.vaadin.shared.ui.combobox.ComboBoxServerRpc; -import com.vaadin.shared.ui.combobox.ComboBoxState; -import com.vaadin.shared.ui.combobox.FilteringMode; - -/** - * A filtering dropdown single-select. Suitable for newItemsAllowed, but it's - * turned of by default to avoid mistakes. Items are filtered based on user - * input, and loaded dynamically ("lazy-loading") from the server. You can turn - * on newItemsAllowed and change filtering mode (and also turn it off), but you - * can not turn on multi-select mode. - * - */ -@SuppressWarnings("serial") -public class ComboBox extends AbstractSelect - implements AbstractSelect.Filtering, FieldEvents.BlurNotifier, - FieldEvents.FocusNotifier { - - /** - * ItemStyleGenerator can be used to add custom styles to combo box items - * shown in the popup. The CSS class name that will be added to the item - * style names is <tt>v-filterselect-item-[style name]</tt>. - * - * @since 7.5.6 - * @see ComboBox#setItemStyleGenerator(ItemStyleGenerator) - */ - public interface ItemStyleGenerator extends Serializable { - - /** - * Called by ComboBox when an item is painted. - * - * @param source - * the source combo box - * @param itemId - * The itemId of the item to be painted. Can be - * <code>null</code> if null selection is allowed. - * @return The style name to add to this item. (the CSS class name will - * be v-filterselect-item-[style name] - */ - public String getStyle(ComboBox source, Object itemId); - } - - private ComboBoxServerRpc rpc = new ComboBoxServerRpc() { - @Override - public void createNewItem(String itemValue) { - if (isNewItemsAllowed()) { - // New option entered (and it is allowed) - if (itemValue != null && itemValue.length() > 0) { - getNewItemHandler().addNewItem(itemValue); - // rebuild list - filterstring = null; - prevfilterstring = null; - } - } - } - - @Override - public void setSelectedItem(String item) { - if (item == null) { - setValue(null, true); - } else { - final Object id = itemIdMapper.get(item); - if (id != null && id.equals(getNullSelectionItemId())) { - setValue(null, true); - } else { - setValue(id, true); - } - } - } - - @Override - public void requestPage(String filter, int page) { - filterstring = filter; - if (filterstring != null) { - filterstring = filterstring.toLowerCase(getLocale()); - } - currentPage = page; - - // TODO this should trigger a data-only update instead of a full - // repaint - requestRepaint(); - } - }; - - FocusAndBlurServerRpcImpl focusBlurRpc = new FocusAndBlurServerRpcImpl( - this) { - @Override - protected void fireEvent(Component.Event event) { - ComboBox.this.fireEvent(event); - } - }; - - // Current page when the user is 'paging' trough options - private int currentPage = -1; - - private String filterstring; - private String prevfilterstring; - - /** - * Number of options that pass the filter, excluding the null item if any. - */ - private int filteredSize; - - /** - * Cache of filtered options, used only by the in-memory filtering system. - */ - private List<Object> filteredOptions; - - /** - * Flag to indicate that request repaint is called by filter request only - */ - private boolean optionRequest; - - /** - * True while painting to suppress item set change notifications that could - * be caused by temporary filtering. - */ - private boolean isPainting; - - /** - * Flag to indicate whether to scroll the selected item visible (select the - * page on which it is) when opening the popup or not. Only applies to - * single select mode. - * - * This requires finding the index of the item, which can be expensive in - * many large lazy loading containers. - */ - private boolean scrollToSelectedItem = true; - - private ItemStyleGenerator itemStyleGenerator = null; - - public ComboBox() { - init(); - } - - public ComboBox(String caption, Collection<?> options) { - super(caption, options); - init(); - } - - public ComboBox(String caption, Container dataSource) { - super(caption, dataSource); - init(); - } - - public ComboBox(String caption) { - super(caption); - init(); - } - - /** - * Initialize the ComboBox with default settings and register client to - * server RPC implementation. - */ - private void init() { - registerRpc(rpc); - registerRpc(focusBlurRpc); - - setNewItemsAllowed(false); - setImmediate(true); - } - - /** - * Gets the current input prompt. - * - * @see #setInputPrompt(String) - * @return the current input prompt, or null if not enabled - */ - public String getInputPrompt() { - return getState(false).inputPrompt; - } - - /** - * Sets the input prompt - a textual prompt that is displayed when the - * select would otherwise be empty, to prompt the user for input. - * - * @param inputPrompt - * the desired input prompt, or null to disable - */ - public void setInputPrompt(String inputPrompt) { - getState().inputPrompt = inputPrompt; - } - - private boolean isFilteringNeeded() { - return filterstring != null && filterstring.length() > 0 - && getFilteringMode() != FilteringMode.OFF; - } - - /** - * A class representing an item in a ComboBox for server to client - * communication. This class is for internal use only and subject to change. - * - * @since - */ - private static class ComboBoxItem implements Serializable { - String key = ""; - String caption = ""; - String style = null; - Resource icon = null; - - // constructor for a null item - public ComboBoxItem() { - } - - public ComboBoxItem(String key, String caption, String style, - Resource icon) { - this.key = key; - this.caption = caption; - this.style = style; - this.icon = icon; - } - } - - @Override - public void paintContent(PaintTarget target) throws PaintException { - isPainting = true; - try { - // clear caption change listeners - getCaptionChangeListener().clear(); - - if (isNewItemsAllowed()) { - target.addAttribute("allownewitem", true); - } - - boolean needNullSelectOption = false; - if (isNullSelectionAllowed()) { - target.addAttribute("nullselect", true); - needNullSelectOption = (getNullSelectionItemId() == null); - if (!needNullSelectOption) { - target.addAttribute("nullselectitem", true); - } - } - - // Constructs selected keys array - String[] selectedKeys = new String[(getValue() == null - && getNullSelectionItemId() == null ? 0 : 1)]; - - // Paints the options and create array of selected id keys - int keyIndex = 0; - - if (currentPage < 0) { - optionRequest = false; - currentPage = 0; - filterstring = ""; - } - - boolean nullFilteredOut = isFilteringNeeded(); - // null option is needed and not filtered out, even if not on - // current page - boolean nullOptionVisible = needNullSelectOption - && !nullFilteredOut; - - // first try if using container filters is possible - List<?> options = getOptionsWithFilter(nullOptionVisible); - if (null == options) { - // not able to use container filters, perform explicit in-memory - // filtering - options = getFilteredOptions(); - filteredSize = options.size(); - options = sanitetizeList(options, nullOptionVisible); - } - - final boolean paintNullSelection = needNullSelectOption - && currentPage == 0 && !nullFilteredOut; - - List<ComboBoxItem> items = new ArrayList<ComboBoxItem>(); - - if (paintNullSelection) { - ComboBoxItem item = new ComboBoxItem(); - item.style = getItemStyle(null); - items.add(item); - } - - final Iterator<?> i = options.iterator(); - // Paints the available selection options from data source - - while (i.hasNext()) { - - final Object id = i.next(); - - if (!isNullSelectionAllowed() && id != null - && id.equals(getNullSelectionItemId()) - && !isSelected(id)) { - continue; - } - - // Gets the option attribute values - final String key = itemIdMapper.key(id); - final String caption = getItemCaption(id); - final Resource icon = getItemIcon(id); - - getCaptionChangeListener().addNotifierForItem(id); - - // Prepare to paint the option - ComboBoxItem item = new ComboBoxItem(key, caption, - getItemStyle(id), icon); - items.add(item); - if (keyIndex < selectedKeys.length && isSelected(id)) { - // at most one item can be selected at a time - selectedKeys[keyIndex++] = key; - } - } - - // paint the items - target.startTag("options"); - for (ComboBoxItem item : items) { - target.startTag("so"); - if (item.icon != null) { - target.addAttribute("icon", item.icon); - } - target.addAttribute("caption", item.caption); - target.addAttribute("key", item.key); - if (item.style != null) { - target.addAttribute("style", item.style); - } - - target.endTag("so"); - } - target.endTag("options"); - - target.addAttribute("totalitems", - size() + (needNullSelectOption ? 1 : 0)); - if (filteredSize > 0 || nullOptionVisible) { - target.addAttribute("totalMatches", - filteredSize + (nullOptionVisible ? 1 : 0)); - } - - // Paint variables - target.addVariable(this, "selected", selectedKeys); - if (getValue() != null && selectedKeys[0] == null) { - // not always available, e.g. scrollToSelectedIndex=false - // Give the caption for selected item still, not to make it look - // like there is no selection at all - target.addAttribute("selectedCaption", - getItemCaption(getValue())); - } - if (isNewItemsAllowed()) { - target.addVariable(this, "newitem", ""); - } - - target.addVariable(this, "filter", filterstring); - target.addVariable(this, "page", currentPage); - - currentPage = -1; // current page is always set by client - - optionRequest = true; - } finally { - isPainting = false; - } - - } - - private String getItemStyle(Object itemId) throws PaintException { - if (itemStyleGenerator != null) { - return itemStyleGenerator.getStyle(this, itemId); - } - return null; - } - - /** - * Sets whether it is possible to input text into the field or whether the - * field area of the component is just used to show what is selected. By - * disabling text input, the comboBox will work in the same way as a - * {@link NativeSelect} - * - * @see #isTextInputAllowed() - * - * @param textInputAllowed - * true to allow entering text, false to just show the current - * selection - */ - public void setTextInputAllowed(boolean textInputAllowed) { - getState().textInputAllowed = textInputAllowed; - } - - /** - * Returns true if the user can enter text into the field to either filter - * the selections or enter a new value if {@link #isNewItemsAllowed()} - * returns true. If text input is disabled, the comboBox will work in the - * same way as a {@link NativeSelect} - * - * @return - */ - public boolean isTextInputAllowed() { - return getState(false).textInputAllowed; - } - - @Override - protected ComboBoxState getState() { - return (ComboBoxState) super.getState(); - } - - @Override - protected ComboBoxState getState(boolean markAsDirty) { - return (ComboBoxState) super.getState(markAsDirty); - } - - /** - * Returns the filtered options for the current page using a container - * filter. - * - * As a size effect, {@link #filteredSize} is set to the total number of - * items passing the filter. - * - * The current container must be {@link Filterable} and {@link Indexed}, and - * the filtering mode must be suitable for container filtering (tested with - * {@link #canUseContainerFilter()}). - * - * Use {@link #getFilteredOptions()} and - * {@link #sanitetizeList(List, boolean)} if this is not the case. - * - * @param needNullSelectOption - * @return filtered list of options (may be empty) or null if cannot use - * container filters - */ - protected List<?> getOptionsWithFilter(boolean needNullSelectOption) { - Container container = getContainerDataSource(); - - if (getPageLength() == 0 && !isFilteringNeeded()) { - // no paging or filtering: return all items - filteredSize = container.size(); - assert filteredSize >= 0; - return new ArrayList<Object>(container.getItemIds()); - } - - if (!(container instanceof Filterable) - || !(container instanceof Indexed) - || getItemCaptionMode() != ITEM_CAPTION_MODE_PROPERTY) { - return null; - } - - Filterable filterable = (Filterable) container; - - Filter filter = buildFilter(filterstring, getFilteringMode()); - - // adding and removing filters leads to extraneous item set - // change events from the underlying container, but the ComboBox does - // not process or propagate them based on the flag filteringContainer - if (filter != null) { - filterable.addContainerFilter(filter); - } - - // try-finally to ensure that the filter is removed from container even - // if a exception is thrown... - try { - Indexed indexed = (Indexed) container; - - int indexToEnsureInView = -1; - - // if not an option request (item list when user changes page), go - // to page with the selected item after filtering if accepted by - // filter - Object selection = getValue(); - if (isScrollToSelectedItem() && !optionRequest - && selection != null) { - // ensure proper page - indexToEnsureInView = indexed.indexOfId(selection); - } - - filteredSize = container.size(); - assert filteredSize >= 0; - currentPage = adjustCurrentPage(currentPage, needNullSelectOption, - indexToEnsureInView, filteredSize); - int first = getFirstItemIndexOnCurrentPage(needNullSelectOption, - filteredSize); - int last = getLastItemIndexOnCurrentPage(needNullSelectOption, - filteredSize, first); - - // Compute the number of items to fetch from the indexes given or - // based on the filtered size of the container - int lastItemToFetch = Math.min(last, filteredSize - 1); - int nrOfItemsToFetch = (lastItemToFetch + 1) - first; - - List<?> options = indexed.getItemIds(first, nrOfItemsToFetch); - - return options; - } finally { - // to the outside, filtering should not be visible - if (filter != null) { - filterable.removeContainerFilter(filter); - } - } - } - - /** - * Constructs a filter instance to use when using a Filterable container in - * the <code>ITEM_CAPTION_MODE_PROPERTY</code> mode. - * - * Note that the client side implementation expects the filter string to - * apply to the item caption string it sees, so changing the behavior of - * this method can cause problems. - * - * @param filterString - * @param filteringMode - * @return - */ - protected Filter buildFilter(String filterString, - FilteringMode filteringMode) { - Filter filter = null; - - if (null != filterString && !"".equals(filterString)) { - switch (filteringMode) { - case OFF: - break; - case STARTSWITH: - filter = new SimpleStringFilter(getItemCaptionPropertyId(), - filterString, true, true); - break; - case CONTAINS: - filter = new SimpleStringFilter(getItemCaptionPropertyId(), - filterString, true, false); - break; - } - } - return filter; - } - - @Override - public void containerItemSetChange(Container.ItemSetChangeEvent event) { - if (!isPainting) { - super.containerItemSetChange(event); - } - } - - /** - * Makes correct sublist of given list of options. - * - * If paint is not an option request (affected by page or filter change), - * page will be the one where possible selection exists. - * - * Detects proper first and last item in list to return right page of - * options. Also, if the current page is beyond the end of the list, it will - * be adjusted. - * - * @param options - * @param needNullSelectOption - * flag to indicate if nullselect option needs to be taken into - * consideration - */ - private List<?> sanitetizeList(List<?> options, - boolean needNullSelectOption) { - - if (getPageLength() != 0 && options.size() > getPageLength()) { - - int indexToEnsureInView = -1; - - // if not an option request (item list when user changes page), go - // to page with the selected item after filtering if accepted by - // filter - Object selection = getValue(); - if (isScrollToSelectedItem() && !optionRequest - && selection != null) { - // ensure proper page - indexToEnsureInView = options.indexOf(selection); - } - - int size = options.size(); - currentPage = adjustCurrentPage(currentPage, needNullSelectOption, - indexToEnsureInView, size); - int first = getFirstItemIndexOnCurrentPage(needNullSelectOption, - size); - int last = getLastItemIndexOnCurrentPage(needNullSelectOption, size, - first); - return options.subList(first, last + 1); - } else { - return options; - } - } - - /** - * Returns the index of the first item on the current page. The index is to - * the underlying (possibly filtered) contents. The null item, if any, does - * not have an index but takes up a slot on the first page. - * - * @param needNullSelectOption - * true if a null option should be shown before any other options - * (takes up the first slot on the first page, not counted in - * index) - * @param size - * number of items after filtering (not including the null item, - * if any) - * @return first item to show on the UI (index to the filtered list of - * options, not taking the null item into consideration if any) - */ - private int getFirstItemIndexOnCurrentPage(boolean needNullSelectOption, - int size) { - // Not all options are visible, find out which ones are on the - // current "page". - int first = currentPage * getPageLength(); - if (needNullSelectOption && currentPage > 0) { - first--; - } - return first; - } - - /** - * Returns the index of the last item on the current page. The index is to - * the underlying (possibly filtered) contents. If needNullSelectOption is - * true, the null item takes up the first slot on the first page, - * effectively reducing the first page size by one. - * - * @param needNullSelectOption - * true if a null option should be shown before any other options - * (takes up the first slot on the first page, not counted in - * index) - * @param size - * number of items after filtering (not including the null item, - * if any) - * @param first - * index in the filtered view of the first item of the page - * @return index in the filtered view of the last item on the page - */ - private int getLastItemIndexOnCurrentPage(boolean needNullSelectOption, - int size, int first) { - // page length usable for non-null items - int effectivePageLength = getPageLength() - - (needNullSelectOption && (currentPage == 0) ? 1 : 0); - return Math.min(size - 1, first + effectivePageLength - 1); - } - - /** - * Adjusts the index of the current page if necessary: make sure the current - * page is not after the end of the contents, and optionally go to the page - * containg a specific item. There are no side effects but the adjusted page - * index is returned. - * - * @param page - * page number to use as the starting point - * @param needNullSelectOption - * true if a null option should be shown before any other options - * (takes up the first slot on the first page, not counted in - * index) - * @param indexToEnsureInView - * index of an item that should be included on the page (in the - * data set, not counting the null item if any), -1 for none - * @param size - * number of items after filtering (not including the null item, - * if any) - */ - private int adjustCurrentPage(int page, boolean needNullSelectOption, - int indexToEnsureInView, int size) { - if (indexToEnsureInView != -1) { - int newPage = (indexToEnsureInView + (needNullSelectOption ? 1 : 0)) - / getPageLength(); - page = newPage; - } - // adjust the current page if beyond the end of the list - if (page * getPageLength() > size) { - page = (size + (needNullSelectOption ? 1 : 0)) / getPageLength(); - } - return page; - } - - /** - * Filters the options in memory and returns the full filtered list. - * - * This can be less efficient than using container filters, so use - * {@link #getOptionsWithFilter(boolean)} if possible (filterable container - * and suitable item caption mode etc.). - * - * @return - */ - protected List<?> getFilteredOptions() { - if (!isFilteringNeeded()) { - prevfilterstring = null; - filteredOptions = new LinkedList<Object>(getItemIds()); - return filteredOptions; - } - - if (filterstring.equals(prevfilterstring)) { - return filteredOptions; - } - - Collection<?> items; - if (prevfilterstring != null - && filterstring.startsWith(prevfilterstring)) { - items = filteredOptions; - } else { - items = getItemIds(); - } - prevfilterstring = filterstring; - - filteredOptions = new LinkedList<Object>(); - for (final Iterator<?> it = items.iterator(); it.hasNext();) { - final Object itemId = it.next(); - String caption = getItemCaption(itemId); - if (caption == null || caption.equals("")) { - continue; - } else { - caption = caption.toLowerCase(getLocale()); - } - switch (getFilteringMode()) { - case CONTAINS: - if (caption.indexOf(filterstring) > -1) { - filteredOptions.add(itemId); - } - break; - case STARTSWITH: - default: - if (caption.startsWith(filterstring)) { - filteredOptions.add(itemId); - } - break; - } - } - - return filteredOptions; - } - - /** - * Invoked when the value of a variable has changed. - * - * @see com.vaadin.ui.AbstractComponent#changeVariables(java.lang.Object, - * java.util.Map) - */ - @Override - public void changeVariables(Object source, Map<String, Object> variables) { - // Not calling super.changeVariables due the history of select - // component hierarchy - - // all the client to server requests are now handled by RPC - } - - @Override - public void setFilteringMode(FilteringMode filteringMode) { - getState().filteringMode = filteringMode; - } - - @Override - public FilteringMode getFilteringMode() { - return getState(false).filteringMode; - } - - @Override - public void addBlurListener(BlurListener listener) { - addListener(BlurEvent.EVENT_ID, BlurEvent.class, listener, - BlurListener.blurMethod); - } - - @Override - public void removeBlurListener(BlurListener listener) { - removeListener(BlurEvent.EVENT_ID, BlurEvent.class, listener); - } - - @Override - public void addFocusListener(FocusListener listener) { - addListener(FocusEvent.EVENT_ID, FocusEvent.class, listener, - FocusListener.focusMethod); - } - - @Override - public void removeFocusListener(FocusListener listener) { - removeListener(FocusEvent.EVENT_ID, FocusEvent.class, listener); - } - - /** - * ComboBox does not support multi select mode. - * - * @deprecated As of 7.0, use {@link ListSelect}, {@link OptionGroup} or - * {@link TwinColSelect} instead - * @see com.vaadin.ui.AbstractSelect#setMultiSelect(boolean) - * @throws UnsupportedOperationException - * if trying to activate multiselect mode - */ - @Deprecated - @Override - public void setMultiSelect(boolean multiSelect) { - if (multiSelect) { - throw new UnsupportedOperationException( - "Multiselect not supported"); - } - } - - /** - * ComboBox does not support multi select mode. - * - * @deprecated As of 7.0, use {@link ListSelect}, {@link OptionGroup} or - * {@link TwinColSelect} instead - * - * @see com.vaadin.ui.AbstractSelect#isMultiSelect() - * - * @return false - */ - @Deprecated - @Override - public boolean isMultiSelect() { - return false; - } - - /** - * Returns the page length of the suggestion popup. - * - * @return the pageLength - */ - public int getPageLength() { - return getState(false).pageLength; - } - - /** - * Returns the suggestion pop-up's width as a CSS string. - * - * @see #setPopupWidth - * @since 7.7 - */ - public String getPopupWidth() { - return getState(false).suggestionPopupWidth; - } - - /** - * Sets the page length for the suggestion popup. Setting the page length to - * 0 will disable suggestion popup paging (all items visible). - * - * @param pageLength - * the pageLength to set - */ - public void setPageLength(int pageLength) { - getState().pageLength = pageLength; - } - - /** - * Sets the suggestion pop-up's width as a CSS string. By using relative - * units (e.g. "50%") it's possible to set the popup's width relative to the - * ComboBox itself. - * - * @see #getPopupWidth() - * @since 7.7 - * @param width - * the width - */ - public void setPopupWidth(String width) { - getState().suggestionPopupWidth = width; - } - - /** - * Sets whether to scroll the selected item visible (directly open the page - * on which it is) when opening the combo box popup or not. Only applies to - * single select mode. - * - * This requires finding the index of the item, which can be expensive in - * many large lazy loading containers. - * - * @param scrollToSelectedItem - * true to find the page with the selected item when opening the - * selection popup - */ - public void setScrollToSelectedItem(boolean scrollToSelectedItem) { - this.scrollToSelectedItem = scrollToSelectedItem; - } - - /** - * Returns true if the select should find the page with the selected item - * when opening the popup (single select combo box only). - * - * @see #setScrollToSelectedItem(boolean) - * - * @return true if the page with the selected item will be shown when - * opening the popup - */ - public boolean isScrollToSelectedItem() { - return scrollToSelectedItem; - } - - /** - * Sets the item style generator that is used to produce custom styles for - * showing items in the popup. The CSS class name that will be added to the - * item style names is <tt>v-filterselect-item-[style name]</tt>. - * - * @param itemStyleGenerator - * the item style generator to set, or <code>null</code> to not - * use any custom item styles - * @since 7.5.6 - */ - public void setItemStyleGenerator(ItemStyleGenerator itemStyleGenerator) { - this.itemStyleGenerator = itemStyleGenerator; - markAsDirty(); - } - - /** - * Gets the currently used item style generator. - * - * @return the itemStyleGenerator the currently used item style generator, - * or <code>null</code> if no generator is used - * @since 7.5.6 - */ - public ItemStyleGenerator getItemStyleGenerator() { - return itemStyleGenerator; - } - -} diff --git a/server/src/main/java/com/vaadin/ui/Tree.java b/server/src/main/java/com/vaadin/ui/Tree.java deleted file mode 100644 index 5da499f94e..0000000000 --- a/server/src/main/java/com/vaadin/ui/Tree.java +++ /dev/null @@ -1,1984 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui; - -import java.io.Serializable; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.Map; -import java.util.Set; -import java.util.Stack; -import java.util.StringTokenizer; - -import org.jsoup.nodes.Element; - -import com.vaadin.data.Container; -import com.vaadin.data.Item; -import com.vaadin.data.util.ContainerHierarchicalWrapper; -import com.vaadin.data.util.HierarchicalContainer; -import com.vaadin.event.Action; -import com.vaadin.event.Action.Handler; -import com.vaadin.event.ContextClickEvent; -import com.vaadin.event.DataBoundTransferable; -import com.vaadin.event.ItemClickEvent; -import com.vaadin.event.ItemClickEvent.ItemClickListener; -import com.vaadin.event.ItemClickEvent.ItemClickNotifier; -import com.vaadin.event.Transferable; -import com.vaadin.event.dd.DragAndDropEvent; -import com.vaadin.event.dd.DragSource; -import com.vaadin.event.dd.DropHandler; -import com.vaadin.event.dd.DropTarget; -import com.vaadin.event.dd.TargetDetails; -import com.vaadin.event.dd.acceptcriteria.ClientSideCriterion; -import com.vaadin.event.dd.acceptcriteria.ServerSideCriterion; -import com.vaadin.event.dd.acceptcriteria.TargetDetailIs; -import com.vaadin.server.KeyMapper; -import com.vaadin.server.PaintException; -import com.vaadin.server.PaintTarget; -import com.vaadin.server.Resource; -import com.vaadin.shared.MouseEventDetails; -import com.vaadin.shared.ui.MultiSelectMode; -import com.vaadin.shared.ui.dd.VerticalDropLocation; -import com.vaadin.shared.ui.tree.TreeConstants; -import com.vaadin.shared.ui.tree.TreeServerRpc; -import com.vaadin.shared.ui.tree.TreeState; -import com.vaadin.ui.declarative.DesignAttributeHandler; -import com.vaadin.ui.declarative.DesignContext; -import com.vaadin.ui.declarative.DesignException; -import com.vaadin.util.ReflectTools; - -/** - * Tree component. A Tree can be used to select an item (or multiple items) from - * a hierarchical set of items. - * - * @author Vaadin Ltd. - * @since 3.0 - */ -@SuppressWarnings({ "serial", "deprecation" }) -public class Tree extends AbstractSelect implements Container.Hierarchical, - Action.Container, ItemClickNotifier, DragSource, DropTarget { - - /** - * ContextClickEvent for the Tree Component. - * - * @since 7.6 - */ - public static class TreeContextClickEvent extends ContextClickEvent { - - private final Object itemId; - - public TreeContextClickEvent(Tree source, Object itemId, - MouseEventDetails mouseEventDetails) { - super(source, mouseEventDetails); - this.itemId = itemId; - } - - @Override - public Tree getComponent() { - return (Tree) super.getComponent(); - } - - /** - * Returns the item id of context clicked row. - * - * @return item id of clicked row; <code>null</code> if no row is - * present at the location - */ - public Object getItemId() { - return itemId; - } - } - - /* Private members */ - - private static final String NULL_ALT_EXCEPTION_MESSAGE = "Parameter 'altText' needs to be non null"; - - /** - * Item icons alt texts. - */ - private final HashMap<Object, String> itemIconAlts = new HashMap<Object, String>(); - - /** - * Set of expanded nodes. - */ - private HashSet<Object> expanded = new HashSet<Object>(); - - /** - * List of action handlers. - */ - private LinkedList<Action.Handler> actionHandlers = null; - - /** - * Action mapper. - */ - private KeyMapper<Action> actionMapper = null; - - /** - * Is the tree selectable on the client side. - */ - private boolean selectable = true; - - /** - * Flag to indicate sub-tree loading - */ - private boolean partialUpdate = false; - - /** - * Holds a itemId which was recently expanded - */ - private Object expandedItemId; - - /** - * a flag which indicates initial paint. After this flag set true partial - * updates are allowed. - */ - private boolean initialPaint = true; - - /** - * Item tooltip generator - */ - private ItemDescriptionGenerator itemDescriptionGenerator; - - /** - * Supported drag modes for Tree. - */ - public enum TreeDragMode { - /** - * When drag mode is NONE, dragging from Tree is not supported. Browsers - * may still support selecting text/icons from Tree which can initiate - * HTML 5 style drag and drop operation. - */ - NONE, - /** - * When drag mode is NODE, users can initiate drag from Tree nodes that - * represent {@link Item}s in from the backed {@link Container}. - */ - NODE - // , SUBTREE - } - - private TreeDragMode dragMode = TreeDragMode.NONE; - - private MultiSelectMode multiSelectMode = MultiSelectMode.DEFAULT; - - /* Tree constructors */ - - /** - * Creates a new empty tree. - */ - public Tree() { - this(null); - - registerRpc(new TreeServerRpc() { - @Override - public void contextClick(String rowKey, MouseEventDetails details) { - fireEvent(new TreeContextClickEvent(Tree.this, - itemIdMapper.get(rowKey), details)); - } - }); - } - - /** - * Creates a new empty tree with caption. - * - * @param caption - */ - public Tree(String caption) { - this(caption, new HierarchicalContainer()); - } - - /** - * Creates a new tree with caption and connect it to a Container. - * - * @param caption - * @param dataSource - */ - public Tree(String caption, Container dataSource) { - super(caption, dataSource); - } - - @Override - public void setItemIcon(Object itemId, Resource icon) { - setItemIcon(itemId, icon, ""); - } - - /** - * Sets the icon for an item. - * - * @param itemId - * the id of the item to be assigned an icon. - * @param icon - * the icon to use or null. - * - * @param altText - * the alternative text for the icon - */ - public void setItemIcon(Object itemId, Resource icon, String altText) { - if (itemId != null) { - super.setItemIcon(itemId, icon); - - if (icon == null) { - itemIconAlts.remove(itemId); - } else if (altText == null) { - throw new IllegalArgumentException(NULL_ALT_EXCEPTION_MESSAGE); - } else { - itemIconAlts.put(itemId, altText); - } - markAsDirty(); - } - } - - /** - * Set the alternate text for an item. - * - * Used when the item has an icon. - * - * @param itemId - * the id of the item to be assigned an icon. - * @param altText - * the alternative text for the icon - */ - public void setItemIconAlternateText(Object itemId, String altText) { - if (itemId != null) { - if (altText == null) { - throw new IllegalArgumentException(NULL_ALT_EXCEPTION_MESSAGE); - } else { - itemIconAlts.put(itemId, altText); - } - } - } - - /** - * Return the alternate text of an icon in a tree item. - * - * @param itemId - * Object with the ID of the item - * @return String with the alternate text of the icon, or null when no icon - * was set - */ - public String getItemIconAlternateText(Object itemId) { - String storedAlt = itemIconAlts.get(itemId); - return storedAlt == null ? "" : storedAlt; - } - - /* Expanding and collapsing */ - - /** - * Check is an item is expanded - * - * @param itemId - * the item id. - * @return true iff the item is expanded. - */ - public boolean isExpanded(Object itemId) { - return expanded.contains(itemId); - } - - /** - * Expands an item. - * - * @param itemId - * the item id. - * @return True iff the expand operation succeeded - */ - public boolean expandItem(Object itemId) { - boolean success = expandItem(itemId, true); - markAsDirty(); - return success; - } - - /** - * Expands an item. - * - * @param itemId - * the item id. - * @param sendChildTree - * flag to indicate if client needs subtree or not (may be - * cached) - * @return True if the expand operation succeeded - */ - private boolean expandItem(Object itemId, boolean sendChildTree) { - - // Succeeds if the node is already expanded - if (isExpanded(itemId)) { - return true; - } - - // Nodes that can not have children are not expandable - if (!areChildrenAllowed(itemId)) { - return false; - } - - // Expands - expanded.add(itemId); - - expandedItemId = itemId; - if (initialPaint) { - markAsDirty(); - } else if (sendChildTree) { - requestPartialRepaint(); - } - fireExpandEvent(itemId); - - return true; - } - - @Override - public void markAsDirty() { - super.markAsDirty(); - partialUpdate = false; - } - - private void requestPartialRepaint() { - super.markAsDirty(); - partialUpdate = true; - } - - /** - * Expands the items recursively - * - * Expands all the children recursively starting from an item. Operation - * succeeds only if all expandable items are expanded. - * - * @param startItemId - * @return True iff the expand operation succeeded - */ - public boolean expandItemsRecursively(Object startItemId) { - - boolean result = true; - - // Initial stack - final Stack<Object> todo = new Stack<Object>(); - todo.add(startItemId); - - // Expands recursively - while (!todo.isEmpty()) { - final Object id = todo.pop(); - if (areChildrenAllowed(id) && !expandItem(id, false)) { - result = false; - } - if (hasChildren(id)) { - todo.addAll(getChildren(id)); - } - } - markAsDirty(); - return result; - } - - /** - * Collapses an item. - * - * @param itemId - * the item id. - * @return True iff the collapse operation succeeded - */ - public boolean collapseItem(Object itemId) { - - // Succeeds if the node is already collapsed - if (!isExpanded(itemId)) { - return true; - } - - // Collapse - expanded.remove(itemId); - markAsDirty(); - fireCollapseEvent(itemId); - - return true; - } - - /** - * Collapses the items recursively. - * - * Collapse all the children recursively starting from an item. Operation - * succeeds only if all expandable items are collapsed. - * - * @param startItemId - * @return True iff the collapse operation succeeded - */ - public boolean collapseItemsRecursively(Object startItemId) { - - boolean result = true; - - // Initial stack - final Stack<Object> todo = new Stack<Object>(); - todo.add(startItemId); - - // Collapse recursively - while (!todo.isEmpty()) { - final Object id = todo.pop(); - if (areChildrenAllowed(id) && !collapseItem(id)) { - result = false; - } - if (hasChildren(id)) { - todo.addAll(getChildren(id)); - } - } - - return result; - } - - /** - * Returns the current selectable state. Selectable determines if the a node - * can be selected on the client side. Selectable does not affect - * {@link #setValue(Object)} or {@link #select(Object)}. - * - * <p> - * The tree is selectable by default. - * </p> - * - * @return the current selectable state. - */ - public boolean isSelectable() { - return selectable; - } - - /** - * Sets the selectable state. Selectable determines if the a node can be - * selected on the client side. Selectable does not affect - * {@link #setValue(Object)} or {@link #select(Object)}. - * - * <p> - * The tree is selectable by default. - * </p> - * - * @param selectable - * The new selectable state. - */ - public void setSelectable(boolean selectable) { - if (this.selectable != selectable) { - this.selectable = selectable; - markAsDirty(); - } - } - - /** - * Sets the behavior of the multiselect mode - * - * @param mode - * The mode to set - */ - public void setMultiselectMode(MultiSelectMode mode) { - if (multiSelectMode != mode && mode != null) { - multiSelectMode = mode; - markAsDirty(); - } - } - - /** - * Returns the mode the multiselect is in. The mode controls how - * multiselection can be done. - * - * @return The mode - */ - public MultiSelectMode getMultiselectMode() { - return multiSelectMode; - } - - /* Component API */ - - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.AbstractSelect#changeVariables(java.lang.Object, - * java.util.Map) - */ - @Override - public void changeVariables(Object source, Map<String, Object> variables) { - - if (variables.containsKey("clickedKey")) { - String key = (String) variables.get("clickedKey"); - - Object id = itemIdMapper.get(key); - MouseEventDetails details = MouseEventDetails - .deSerialize((String) variables.get("clickEvent")); - Item item = getItem(id); - if (item != null) { - fireEvent(new ItemClickEvent(this, item, id, null, details)); - } - } - - if (!isSelectable() && variables.containsKey("selected")) { - // Not-selectable is a special case, AbstractSelect does not support - // TODO could be optimized. - variables = new HashMap<String, Object>(variables); - variables.remove("selected"); - } - - // Collapses the nodes - if (variables.containsKey("collapse")) { - final String[] keys = (String[]) variables.get("collapse"); - for (int i = 0; i < keys.length; i++) { - final Object id = itemIdMapper.get(keys[i]); - if (id != null && isExpanded(id)) { - expanded.remove(id); - if (expandedItemId == id) { - expandedItemId = null; - } - fireCollapseEvent(id); - } - } - } - - // Expands the nodes - if (variables.containsKey("expand")) { - boolean sendChildTree = false; - if (variables.containsKey("requestChildTree")) { - sendChildTree = true; - } - final String[] keys = (String[]) variables.get("expand"); - for (int i = 0; i < keys.length; i++) { - final Object id = itemIdMapper.get(keys[i]); - if (id != null) { - expandItem(id, sendChildTree); - } - } - } - - // AbstractSelect cannot handle multiselection so we handle - // it ourself - if (variables.containsKey("selected") && isMultiSelect() - && multiSelectMode == MultiSelectMode.DEFAULT) { - handleSelectedItems(variables); - variables = new HashMap<String, Object>(variables); - variables.remove("selected"); - } - - // Selections are handled by the select component - super.changeVariables(source, variables); - - // Actions - if (variables.containsKey("action")) { - final StringTokenizer st = new StringTokenizer( - (String) variables.get("action"), ","); - if (st.countTokens() == 2) { - final Object itemId = itemIdMapper.get(st.nextToken()); - final Action action = actionMapper.get(st.nextToken()); - if (action != null && (itemId == null || containsId(itemId)) - && actionHandlers != null) { - for (Handler ah : actionHandlers) { - ah.handleAction(action, this, itemId); - } - } - } - } - } - - /** - * Handles the selection - * - * @param variables - * The variables sent to the server from the client - */ - private void handleSelectedItems(Map<String, Object> variables) { - final String[] ka = (String[]) variables.get("selected"); - - // Converts the key-array to id-set - final LinkedList<Object> s = new LinkedList<Object>(); - for (int i = 0; i < ka.length; i++) { - final Object id = itemIdMapper.get(ka[i]); - if (!isNullSelectionAllowed() - && (id == null || id == getNullSelectionItemId())) { - // skip empty selection if nullselection is not allowed - markAsDirty(); - } else if (id != null && containsId(id)) { - s.add(id); - } - } - - if (!isNullSelectionAllowed() && s.size() < 1) { - // empty selection not allowed, keep old value - markAsDirty(); - return; - } - - setValue(s, true); - } - - /** - * Paints any needed component-specific things to the given UIDL stream. - * - * @see com.vaadin.ui.AbstractComponent#paintContent(PaintTarget) - */ - @Override - public void paintContent(PaintTarget target) throws PaintException { - initialPaint = false; - - if (partialUpdate) { - target.addAttribute("partialUpdate", true); - target.addAttribute("rootKey", itemIdMapper.key(expandedItemId)); - } else { - getCaptionChangeListener().clear(); - - // The tab ordering number - if (getTabIndex() > 0) { - target.addAttribute("tabindex", getTabIndex()); - } - - // Paint tree attributes - if (isSelectable()) { - target.addAttribute("selectmode", - (isMultiSelect() ? "multi" : "single")); - if (isMultiSelect()) { - target.addAttribute("multiselectmode", - multiSelectMode.toString()); - } - } else { - target.addAttribute("selectmode", "none"); - } - if (isNewItemsAllowed()) { - target.addAttribute("allownewitem", true); - } - - if (isNullSelectionAllowed()) { - target.addAttribute("nullselect", true); - } - - if (dragMode != TreeDragMode.NONE) { - target.addAttribute("dragMode", dragMode.ordinal()); - } - - if (isHtmlContentAllowed()) { - target.addAttribute(TreeConstants.ATTRIBUTE_HTML_ALLOWED, true); - } - - } - - // Initialize variables - final Set<Action> actionSet = new LinkedHashSet<Action>(); - - // rendered selectedKeys - LinkedList<String> selectedKeys = new LinkedList<String>(); - - final LinkedList<String> expandedKeys = new LinkedList<String>(); - - // Iterates through hierarchical tree using a stack of iterators - final Stack<Iterator<?>> iteratorStack = new Stack<Iterator<?>>(); - Collection<?> ids; - if (partialUpdate) { - ids = getChildren(expandedItemId); - } else { - ids = rootItemIds(); - } - - if (ids != null) { - iteratorStack.push(ids.iterator()); - } - - /* - * Body actions - Actions which has the target null and can be invoked - * by right clicking on the Tree body - */ - if (actionHandlers != null) { - final ArrayList<String> keys = new ArrayList<String>(); - for (Handler ah : actionHandlers) { - - // Getting action for the null item, which in this case - // means the body item - final Action[] aa = ah.getActions(null, this); - if (aa != null) { - for (int ai = 0; ai < aa.length; ai++) { - final String akey = actionMapper.key(aa[ai]); - actionSet.add(aa[ai]); - keys.add(akey); - } - } - } - target.addAttribute("alb", keys.toArray()); - } - - while (!iteratorStack.isEmpty()) { - - // Gets the iterator for current tree level - final Iterator<?> i = iteratorStack.peek(); - - // If the level is finished, back to previous tree level - if (!i.hasNext()) { - - // Removes used iterator from the stack - iteratorStack.pop(); - - // Closes node - if (!iteratorStack.isEmpty()) { - target.endTag("node"); - } - } - - // Adds the item on current level - else { - final Object itemId = i.next(); - - // Starts the item / node - final boolean isNode = areChildrenAllowed(itemId); - if (isNode) { - target.startTag("node"); - } else { - target.startTag("leaf"); - } - - if (itemStyleGenerator != null) { - String stylename = itemStyleGenerator.getStyle(this, - itemId); - if (stylename != null) { - target.addAttribute(TreeConstants.ATTRIBUTE_NODE_STYLE, - stylename); - } - } - - if (itemDescriptionGenerator != null) { - String description = itemDescriptionGenerator - .generateDescription(this, itemId, null); - if (description != null && !description.equals("")) { - target.addAttribute("descr", description); - } - } - - // Adds the attributes - target.addAttribute(TreeConstants.ATTRIBUTE_NODE_CAPTION, - getItemCaption(itemId)); - final Resource icon = getItemIcon(itemId); - if (icon != null) { - target.addAttribute(TreeConstants.ATTRIBUTE_NODE_ICON, - getItemIcon(itemId)); - target.addAttribute(TreeConstants.ATTRIBUTE_NODE_ICON_ALT, - getItemIconAlternateText(itemId)); - } - final String key = itemIdMapper.key(itemId); - target.addAttribute("key", key); - if (isSelected(itemId)) { - target.addAttribute("selected", true); - selectedKeys.add(key); - } - if (areChildrenAllowed(itemId) && isExpanded(itemId)) { - target.addAttribute("expanded", true); - expandedKeys.add(key); - } - - // Add caption change listener - getCaptionChangeListener().addNotifierForItem(itemId); - - // Actions - if (actionHandlers != null) { - final ArrayList<String> keys = new ArrayList<String>(); - final Iterator<Action.Handler> ahi = actionHandlers - .iterator(); - while (ahi.hasNext()) { - final Action[] aa = ahi.next().getActions(itemId, this); - if (aa != null) { - for (int ai = 0; ai < aa.length; ai++) { - final String akey = actionMapper.key(aa[ai]); - actionSet.add(aa[ai]); - keys.add(akey); - } - } - } - target.addAttribute("al", keys.toArray()); - } - - // Adds the children if expanded, or close the tag - if (isExpanded(itemId) && hasChildren(itemId) - && areChildrenAllowed(itemId)) { - iteratorStack.push(getChildren(itemId).iterator()); - } else { - if (isNode) { - target.endTag("node"); - } else { - target.endTag("leaf"); - } - } - } - } - - // Actions - if (!actionSet.isEmpty()) { - target.addVariable(this, "action", ""); - target.startTag("actions"); - final Iterator<Action> i = actionSet.iterator(); - while (i.hasNext()) { - final Action a = i.next(); - target.startTag("action"); - if (a.getCaption() != null) { - target.addAttribute(TreeConstants.ATTRIBUTE_ACTION_CAPTION, - a.getCaption()); - } - if (a.getIcon() != null) { - target.addAttribute(TreeConstants.ATTRIBUTE_ACTION_ICON, - a.getIcon()); - } - target.addAttribute("key", actionMapper.key(a)); - target.endTag("action"); - } - target.endTag("actions"); - } - - if (partialUpdate) { - partialUpdate = false; - } else { - // Selected - target.addVariable(this, "selected", - selectedKeys.toArray(new String[selectedKeys.size()])); - - // Expand and collapse - target.addVariable(this, "expand", new String[] {}); - target.addVariable(this, "collapse", new String[] {}); - - // New items - target.addVariable(this, "newitem", new String[] {}); - - if (dropHandler != null) { - dropHandler.getAcceptCriterion().paint(target); - } - - } - } - - /* Container.Hierarchical API */ - - /** - * Tests if the Item with given ID can have any children. - * - * @see com.vaadin.data.Container.Hierarchical#areChildrenAllowed(Object) - */ - @Override - public boolean areChildrenAllowed(Object itemId) { - return ((Container.Hierarchical) items).areChildrenAllowed(itemId); - } - - /** - * Gets the IDs of all Items that are children of the specified Item. - * - * @see com.vaadin.data.Container.Hierarchical#getChildren(Object) - */ - @Override - public Collection<?> getChildren(Object itemId) { - return ((Container.Hierarchical) items).getChildren(itemId); - } - - /** - * Gets the ID of the parent Item of the specified Item. - * - * @see com.vaadin.data.Container.Hierarchical#getParent(Object) - */ - @Override - public Object getParent(Object itemId) { - return ((Container.Hierarchical) items).getParent(itemId); - } - - /** - * Tests if the Item specified with <code>itemId</code> has child Items. - * - * @see com.vaadin.data.Container.Hierarchical#hasChildren(Object) - */ - @Override - public boolean hasChildren(Object itemId) { - return ((Container.Hierarchical) items).hasChildren(itemId); - } - - /** - * Tests if the Item specified with <code>itemId</code> is a root Item. - * - * @see com.vaadin.data.Container.Hierarchical#isRoot(Object) - */ - @Override - public boolean isRoot(Object itemId) { - return ((Container.Hierarchical) items).isRoot(itemId); - } - - /** - * Gets the IDs of all Items in the container that don't have a parent. - * - * @see com.vaadin.data.Container.Hierarchical#rootItemIds() - */ - @Override - public Collection<?> rootItemIds() { - return ((Container.Hierarchical) items).rootItemIds(); - } - - /** - * Sets the given Item's capability to have children. - * - * @see com.vaadin.data.Container.Hierarchical#setChildrenAllowed(Object, - * boolean) - */ - @Override - public boolean setChildrenAllowed(Object itemId, - boolean areChildrenAllowed) { - final boolean success = ((Container.Hierarchical) items) - .setChildrenAllowed(itemId, areChildrenAllowed); - if (success) { - markAsDirty(); - } - return success; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Hierarchical#setParent(java.lang.Object , - * java.lang.Object) - */ - @Override - public boolean setParent(Object itemId, Object newParentId) { - final boolean success = ((Container.Hierarchical) items) - .setParent(itemId, newParentId); - if (success) { - markAsDirty(); - } - return success; - } - - /* Overriding select behavior */ - - /** - * Sets the Container that serves as the data source of the viewer. - * - * @see com.vaadin.data.Container.Viewer#setContainerDataSource(Container) - */ - @Override - public void setContainerDataSource(Container newDataSource) { - if (newDataSource == null) { - newDataSource = new HierarchicalContainer(); - } - - // Assure that the data source is ordered by making unordered - // containers ordered by wrapping them - if (Container.Hierarchical.class - .isAssignableFrom(newDataSource.getClass())) { - super.setContainerDataSource(newDataSource); - } else { - super.setContainerDataSource( - new ContainerHierarchicalWrapper(newDataSource)); - } - - /* - * Ensure previous expanded items are cleaned up if they don't exist in - * the new container - */ - if (expanded != null) { - /* - * We need to check that the expanded-field is not null since - * setContainerDataSource() is called from the parent constructor - * (AbstractSelect()) and at that time the expanded field is not yet - * initialized. - */ - cleanupExpandedItems(); - } - - } - - @Override - public void containerItemSetChange( - com.vaadin.data.Container.ItemSetChangeEvent event) { - super.containerItemSetChange(event); - if (getContainerDataSource() instanceof Filterable) { - boolean hasFilters = !((Filterable) getContainerDataSource()) - .getContainerFilters().isEmpty(); - if (!hasFilters) { - /* - * If Container is not filtered then the itemsetchange is caused - * by either adding or removing items to the container. To - * prevent a memory leak we should cleanup the expanded list - * from items which was removed. - * - * However, there will still be a leak if the container is - * filtered to show only a subset of the items in the tree and - * later unfiltered items are removed from the container. In - * that case references to the unfiltered item ids will remain - * in the expanded list until the Tree instance is removed and - * the list is destroyed, or the container data source is - * replaced/updated. To force the removal of the removed items - * the application developer needs to a) remove the container - * filters temporarly or b) re-apply the container datasource - * using setContainerDataSource(getContainerDataSource()) - */ - cleanupExpandedItems(); - } - } - - } - - /* Expand event and listener */ - - /** - * Event to fired when a node is expanded. ExapandEvent is fired when a node - * is to be expanded. it can me used to dynamically fill the sub-nodes of - * the node. - * - * @author Vaadin Ltd. - * @since 3.0 - */ - public static class ExpandEvent extends Component.Event { - - private final Object expandedItemId; - - /** - * New instance of options change event - * - * @param source - * the Source of the event. - * @param expandedItemId - */ - public ExpandEvent(Component source, Object expandedItemId) { - super(source); - this.expandedItemId = expandedItemId; - } - - /** - * Node where the event occurred. - * - * @return the Source of the event. - */ - public Object getItemId() { - return expandedItemId; - } - } - - /** - * Expand event listener. - * - * @author Vaadin Ltd. - * @since 3.0 - */ - public interface ExpandListener extends Serializable { - - public static final Method EXPAND_METHOD = ReflectTools.findMethod( - ExpandListener.class, "nodeExpand", ExpandEvent.class); - - /** - * A node has been expanded. - * - * @param event - * the Expand event. - */ - public void nodeExpand(ExpandEvent event); - } - - /** - * Adds the expand listener. - * - * @param listener - * the Listener to be added. - */ - public void addExpandListener(ExpandListener listener) { - addListener(ExpandEvent.class, listener, ExpandListener.EXPAND_METHOD); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #addExpandListener(ExpandListener)} - **/ - @Deprecated - public void addListener(ExpandListener listener) { - addExpandListener(listener); - } - - /** - * Removes the expand listener. - * - * @param listener - * the Listener to be removed. - */ - public void removeExpandListener(ExpandListener listener) { - removeListener(ExpandEvent.class, listener, - ExpandListener.EXPAND_METHOD); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #removeExpandListener(ExpandListener)} - **/ - @Deprecated - public void removeListener(ExpandListener listener) { - removeExpandListener(listener); - } - - /** - * Emits the expand event. - * - * @param itemId - * the item id. - */ - protected void fireExpandEvent(Object itemId) { - fireEvent(new ExpandEvent(this, itemId)); - } - - /* Collapse event */ - - /** - * Collapse event - * - * @author Vaadin Ltd. - * @since 3.0 - */ - public static class CollapseEvent extends Component.Event { - - private final Object collapsedItemId; - - /** - * New instance of options change event. - * - * @param source - * the Source of the event. - * @param collapsedItemId - */ - public CollapseEvent(Component source, Object collapsedItemId) { - super(source); - this.collapsedItemId = collapsedItemId; - } - - /** - * Gets tge Collapsed Item id. - * - * @return the collapsed item id. - */ - public Object getItemId() { - return collapsedItemId; - } - } - - /** - * Collapse event listener. - * - * @author Vaadin Ltd. - * @since 3.0 - */ - public interface CollapseListener extends Serializable { - - public static final Method COLLAPSE_METHOD = ReflectTools.findMethod( - CollapseListener.class, "nodeCollapse", CollapseEvent.class); - - /** - * A node has been collapsed. - * - * @param event - * the Collapse event. - */ - public void nodeCollapse(CollapseEvent event); - } - - /** - * Adds the collapse listener. - * - * @param listener - * the Listener to be added. - */ - public void addCollapseListener(CollapseListener listener) { - addListener(CollapseEvent.class, listener, - CollapseListener.COLLAPSE_METHOD); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #addCollapseListener(CollapseListener)} - **/ - @Deprecated - public void addListener(CollapseListener listener) { - addCollapseListener(listener); - } - - /** - * Removes the collapse listener. - * - * @param listener - * the Listener to be removed. - */ - public void removeCollapseListener(CollapseListener listener) { - removeListener(CollapseEvent.class, listener, - CollapseListener.COLLAPSE_METHOD); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #removeCollapseListener(CollapseListener)} - **/ - @Deprecated - public void removeListener(CollapseListener listener) { - removeCollapseListener(listener); - } - - /** - * Emits collapse event. - * - * @param itemId - * the item id. - */ - protected void fireCollapseEvent(Object itemId) { - fireEvent(new CollapseEvent(this, itemId)); - } - - /* Action container */ - - /** - * Adds an action handler. - * - * @see com.vaadin.event.Action.Container#addActionHandler(Action.Handler) - */ - @Override - public void addActionHandler(Action.Handler actionHandler) { - - if (actionHandler != null) { - - if (actionHandlers == null) { - actionHandlers = new LinkedList<Action.Handler>(); - actionMapper = new KeyMapper<Action>(); - } - - if (!actionHandlers.contains(actionHandler)) { - actionHandlers.add(actionHandler); - markAsDirty(); - } - } - } - - /** - * Removes an action handler. - * - * @see com.vaadin.event.Action.Container#removeActionHandler(Action.Handler) - */ - @Override - public void removeActionHandler(Action.Handler actionHandler) { - - if (actionHandlers != null && actionHandlers.contains(actionHandler)) { - - actionHandlers.remove(actionHandler); - - if (actionHandlers.isEmpty()) { - actionHandlers = null; - actionMapper = null; - } - - markAsDirty(); - } - } - - /** - * Removes all action handlers - */ - public void removeAllActionHandlers() { - actionHandlers = null; - actionMapper = null; - markAsDirty(); - } - - /** - * Gets the visible item ids. - * - * @see com.vaadin.ui.Select#getVisibleItemIds() - */ - @Override - public Collection<?> getVisibleItemIds() { - - final LinkedList<Object> visible = new LinkedList<Object>(); - - // Iterates trough hierarchical tree using a stack of iterators - final Stack<Iterator<?>> iteratorStack = new Stack<Iterator<?>>(); - final Collection<?> ids = rootItemIds(); - if (ids != null) { - iteratorStack.push(ids.iterator()); - } - while (!iteratorStack.isEmpty()) { - - // Gets the iterator for current tree level - final Iterator<?> i = iteratorStack.peek(); - - // If the level is finished, back to previous tree level - if (!i.hasNext()) { - - // Removes used iterator from the stack - iteratorStack.pop(); - } - - // Adds the item on current level - else { - final Object itemId = i.next(); - - visible.add(itemId); - - // Adds children if expanded, or close the tag - if (isExpanded(itemId) && hasChildren(itemId)) { - iteratorStack.push(getChildren(itemId).iterator()); - } - } - } - - return visible; - } - - /** - * Tree does not support <code>setNullSelectionItemId</code>. - * - * @see com.vaadin.ui.AbstractSelect#setNullSelectionItemId(java.lang.Object) - */ - @Override - public void setNullSelectionItemId(Object nullSelectionItemId) - throws UnsupportedOperationException { - if (nullSelectionItemId != null) { - throw new UnsupportedOperationException(); - } - - } - - /** - * Adding new items is not supported. - * - * @throws UnsupportedOperationException - * if set to true. - * @see com.vaadin.ui.Select#setNewItemsAllowed(boolean) - */ - @Override - public void setNewItemsAllowed(boolean allowNewOptions) - throws UnsupportedOperationException { - if (allowNewOptions) { - throw new UnsupportedOperationException(); - } - } - - private ItemStyleGenerator itemStyleGenerator; - - private DropHandler dropHandler; - - private boolean htmlContentAllowed; - - @Override - public void addItemClickListener(ItemClickListener listener) { - addListener(TreeConstants.ITEM_CLICK_EVENT_ID, ItemClickEvent.class, - listener, ItemClickEvent.ITEM_CLICK_METHOD); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #addItemClickListener(ItemClickListener)} - **/ - @Override - @Deprecated - public void addListener(ItemClickListener listener) { - addItemClickListener(listener); - } - - @Override - public void removeItemClickListener(ItemClickListener listener) { - removeListener(TreeConstants.ITEM_CLICK_EVENT_ID, ItemClickEvent.class, - listener); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #removeItemClickListener(ItemClickListener)} - **/ - @Override - @Deprecated - public void removeListener(ItemClickListener listener) { - removeItemClickListener(listener); - } - - /** - * Sets the {@link ItemStyleGenerator} to be used with this tree. - * - * @param itemStyleGenerator - * item style generator or null to remove generator - */ - public void setItemStyleGenerator(ItemStyleGenerator itemStyleGenerator) { - if (this.itemStyleGenerator != itemStyleGenerator) { - this.itemStyleGenerator = itemStyleGenerator; - markAsDirty(); - } - } - - /** - * @return the current {@link ItemStyleGenerator} for this tree. Null if - * {@link ItemStyleGenerator} is not set. - */ - public ItemStyleGenerator getItemStyleGenerator() { - return itemStyleGenerator; - } - - /** - * ItemStyleGenerator can be used to add custom styles to tree items. The - * CSS class name that will be added to the item content is - * <tt>v-tree-node-[style name]</tt>. - */ - public interface ItemStyleGenerator extends Serializable { - - /** - * Called by Tree when an item is painted. - * - * @param source - * the source Tree - * @param itemId - * The itemId of the item to be painted - * @return The style name to add to this item. (the CSS class name will - * be v-tree-node-[style name] - */ - public abstract String getStyle(Tree source, Object itemId); - } - - // Overriden so javadoc comes from Container.Hierarchical - @Override - public boolean removeItem(Object itemId) - throws UnsupportedOperationException { - return super.removeItem(itemId); - } - - @Override - public DropHandler getDropHandler() { - return dropHandler; - } - - public void setDropHandler(DropHandler dropHandler) { - this.dropHandler = dropHandler; - } - - /** - * A {@link TargetDetails} implementation with Tree specific api. - * - * @since 6.3 - */ - public class TreeTargetDetails extends AbstractSelectTargetDetails { - - TreeTargetDetails(Map<String, Object> rawVariables) { - super(rawVariables); - } - - @Override - public Tree getTarget() { - return (Tree) super.getTarget(); - } - - /** - * If the event is on a node that can not have children (see - * {@link Tree#areChildrenAllowed(Object)}), this method returns the - * parent item id of the target item (see {@link #getItemIdOver()} ). - * The identifier of the parent node is also returned if the cursor is - * on the top part of node. Else this method returns the same as - * {@link #getItemIdOver()}. - * <p> - * In other words this method returns the identifier of the "folder" - * into the drag operation is targeted. - * <p> - * If the method returns null, the current target is on a root node or - * on other undefined area over the tree component. - * <p> - * The default Tree implementation marks the targetted tree node with - * CSS classnames v-tree-node-dragfolder and - * v-tree-node-caption-dragfolder (for the caption element). - */ - public Object getItemIdInto() { - - Object itemIdOver = getItemIdOver(); - if (areChildrenAllowed(itemIdOver) - && getDropLocation() == VerticalDropLocation.MIDDLE) { - return itemIdOver; - } - return getParent(itemIdOver); - } - - /** - * If drop is targeted into "folder node" (see {@link #getItemIdInto()} - * ), this method returns the item id of the node after the drag was - * targeted. This method is useful when implementing drop into specific - * location (between specific nodes) in tree. - * - * @return the id of the item after the user targets the drop or null if - * "target" is a first item in node list (or the first in root - * node list) - */ - public Object getItemIdAfter() { - Object itemIdOver = getItemIdOver(); - Object itemIdInto2 = getItemIdInto(); - if (itemIdOver.equals(itemIdInto2)) { - return null; - } - VerticalDropLocation dropLocation = getDropLocation(); - if (VerticalDropLocation.TOP == dropLocation) { - // if on top of the caption area, add before - Collection<?> children; - Object itemIdInto = getItemIdInto(); - if (itemIdInto != null) { - // seek the previous from child list - children = getChildren(itemIdInto); - } else { - children = rootItemIds(); - } - Object ref = null; - for (Object object : children) { - if (object.equals(itemIdOver)) { - return ref; - } - ref = object; - } - } - return itemIdOver; - } - - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.event.dd.DropTarget#translateDropTargetDetails(java.util.Map) - */ - @Override - public TreeTargetDetails translateDropTargetDetails( - Map<String, Object> clientVariables) { - return new TreeTargetDetails(clientVariables); - } - - /** - * Helper API for {@link TreeDropCriterion} - * - * @param itemId - * @return - */ - private String key(Object itemId) { - return itemIdMapper.key(itemId); - } - - /** - * Sets the drag mode that controls how Tree behaves as a {@link DragSource} - * . - * - * @param dragMode - */ - public void setDragMode(TreeDragMode dragMode) { - this.dragMode = dragMode; - markAsDirty(); - } - - /** - * @return the drag mode that controls how Tree behaves as a - * {@link DragSource}. - * - * @see TreeDragMode - */ - public TreeDragMode getDragMode() { - return dragMode; - } - - /** - * Concrete implementation of {@link DataBoundTransferable} for data - * transferred from a tree. - * - * @see {@link DataBoundTransferable}. - * - * @since 6.3 - */ - protected class TreeTransferable extends DataBoundTransferable { - - public TreeTransferable(Component sourceComponent, - Map<String, Object> rawVariables) { - super(sourceComponent, rawVariables); - } - - @Override - public Object getItemId() { - return getData("itemId"); - } - - @Override - public Object getPropertyId() { - return getItemCaptionPropertyId(); - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.event.dd.DragSource#getTransferable(java.util.Map) - */ - @Override - public Transferable getTransferable(Map<String, Object> payload) { - TreeTransferable transferable = new TreeTransferable(this, payload); - // updating drag source variables - Object object = payload.get("itemId"); - if (object != null) { - transferable.setData("itemId", itemIdMapper.get((String) object)); - } - - return transferable; - } - - /** - * Lazy loading accept criterion for Tree. Accepted target nodes are loaded - * from server once per drag and drop operation. Developer must override one - * method that decides accepted tree nodes for the whole Tree. - * - * <p> - * Initially pretty much no data is sent to client. On first required - * criterion check (per drag request) the client side data structure is - * initialized from server and no subsequent requests requests are needed - * during that drag and drop operation. - */ - public static abstract class TreeDropCriterion extends ServerSideCriterion { - - private Tree tree; - - private Set<Object> allowedItemIds; - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.event.dd.acceptCriteria.ServerSideCriterion#getIdentifier - * () - */ - @Override - protected String getIdentifier() { - return TreeDropCriterion.class.getCanonicalName(); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.event.dd.acceptCriteria.AcceptCriterion#accepts(com.vaadin - * .event.dd.DragAndDropEvent) - */ - @Override - public boolean accept(DragAndDropEvent dragEvent) { - AbstractSelectTargetDetails dropTargetData = (AbstractSelectTargetDetails) dragEvent - .getTargetDetails(); - tree = (Tree) dragEvent.getTargetDetails().getTarget(); - allowedItemIds = getAllowedItemIds(dragEvent, tree); - - return allowedItemIds.contains(dropTargetData.getItemIdOver()); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.event.dd.acceptCriteria.AcceptCriterion#paintResponse( - * com.vaadin.server.PaintTarget) - */ - @Override - public void paintResponse(PaintTarget target) throws PaintException { - /* - * send allowed nodes to client so subsequent requests can be - * avoided - */ - Object[] array = allowedItemIds.toArray(); - for (int i = 0; i < array.length; i++) { - String key = tree.key(array[i]); - array[i] = key; - } - target.addAttribute("allowedIds", array); - } - - protected abstract Set<Object> getAllowedItemIds( - DragAndDropEvent dragEvent, Tree tree); - - } - - /** - * A criterion that accepts {@link Transferable} only directly on a tree - * node that can have children. - * <p> - * Class is singleton, use {@link TargetItemAllowsChildren#get()} to get the - * instance. - * - * @see Tree#setChildrenAllowed(Object, boolean) - * - * @since 6.3 - */ - public static class TargetItemAllowsChildren extends TargetDetailIs { - - private static TargetItemAllowsChildren instance = new TargetItemAllowsChildren(); - - public static TargetItemAllowsChildren get() { - return instance; - } - - private TargetItemAllowsChildren() { - super("itemIdOverIsNode", Boolean.TRUE); - } - - /* - * Uses enhanced server side check - */ - @Override - public boolean accept(DragAndDropEvent dragEvent) { - try { - // must be over tree node and in the middle of it (not top or - // bottom - // part) - TreeTargetDetails eventDetails = (TreeTargetDetails) dragEvent - .getTargetDetails(); - - Object itemIdOver = eventDetails.getItemIdOver(); - if (!eventDetails.getTarget().areChildrenAllowed(itemIdOver)) { - return false; - } - // return true if directly over - return eventDetails - .getDropLocation() == VerticalDropLocation.MIDDLE; - } catch (Exception e) { - return false; - } - } - - } - - /** - * An accept criterion that checks the parent node (or parent hierarchy) for - * the item identifier given in constructor. If the parent is found, content - * is accepted. Criterion can be used to accepts drags on a specific sub - * tree only. - * <p> - * The root items is also consider to be valid target. - */ - public class TargetInSubtree extends ClientSideCriterion { - - private Object rootId; - private int depthToCheck = -1; - - /** - * Constructs a criteria that accepts the drag if the targeted Item is a - * descendant of Item identified by given id - * - * @param parentItemId - * the item identifier of the parent node - */ - public TargetInSubtree(Object parentItemId) { - rootId = parentItemId; - } - - /** - * Constructs a criteria that accepts drops within given level below the - * subtree root identified by given id. - * - * @param rootId - * the item identifier to be sought for - * @param depthToCheck - * the depth that tree is traversed upwards to seek for the - * parent, -1 means that the whole structure should be - * checked - */ - public TargetInSubtree(Object rootId, int depthToCheck) { - this.rootId = rootId; - this.depthToCheck = depthToCheck; - } - - @Override - public boolean accept(DragAndDropEvent dragEvent) { - try { - TreeTargetDetails eventDetails = (TreeTargetDetails) dragEvent - .getTargetDetails(); - - if (eventDetails.getItemIdOver() != null) { - Object itemId = eventDetails.getItemIdOver(); - int i = 0; - while (itemId != null - && (depthToCheck == -1 || i <= depthToCheck)) { - if (itemId.equals(rootId)) { - return true; - } - itemId = getParent(itemId); - i++; - } - } - return false; - } catch (Exception e) { - return false; - } - } - - @Override - public void paintContent(PaintTarget target) throws PaintException { - super.paintContent(target); - target.addAttribute("depth", depthToCheck); - target.addAttribute("key", key(rootId)); - } - } - - /** - * Set the item description generator which generates tooltips for the tree - * items - * - * @param generator - * The generator to use or null to disable - */ - public void setItemDescriptionGenerator( - ItemDescriptionGenerator generator) { - if (generator != itemDescriptionGenerator) { - itemDescriptionGenerator = generator; - markAsDirty(); - } - } - - /** - * Get the item description generator which generates tooltips for tree - * items - */ - public ItemDescriptionGenerator getItemDescriptionGenerator() { - return itemDescriptionGenerator; - } - - private void cleanupExpandedItems() { - Set<Object> removedItemIds = new HashSet<Object>(); - for (Object expandedItemId : expanded) { - if (getItem(expandedItemId) == null) { - removedItemIds.add(expandedItemId); - if (this.expandedItemId == expandedItemId) { - this.expandedItemId = null; - } - } - } - expanded.removeAll(removedItemIds); - } - - /** - * Reads an Item from a design and inserts it into the data source. - * Recursively handles any children of the item as well. - * - * @since 7.5.0 - * @param node - * an element representing the item (tree node). - * @param selected - * A set accumulating selected items. If the item that is read is - * marked as selected, its item id should be added to this set. - * @param context - * the DesignContext instance used in parsing - * @return the item id of the new item - * - * @throws DesignException - * if the tag name of the {@code node} element is not - * {@code node}. - */ - @Override - protected String readItem(Element node, Set<String> selected, - DesignContext context) { - - if (!"node".equals(node.tagName())) { - throw new DesignException("Unrecognized child element in " - + getClass().getSimpleName() + ": " + node.tagName()); - } - - String itemId = node.attr("text"); - addItem(itemId); - if (node.hasAttr("icon")) { - Resource icon = DesignAttributeHandler.readAttribute("icon", - node.attributes(), Resource.class); - setItemIcon(itemId, icon); - } - if (node.hasAttr("selected")) { - selected.add(itemId); - } - - for (Element child : node.children()) { - String childItemId = readItem(child, selected, context); - setParent(childItemId, itemId); - } - return itemId; - } - - /** - * Recursively writes the root items and their children to a design. - * - * @since 7.5.0 - * @param design - * the element into which to insert the items - * @param context - * the DesignContext instance used in writing - */ - @Override - protected void writeItems(Element design, DesignContext context) { - for (Object itemId : rootItemIds()) { - writeItem(design, itemId, context); - } - } - - /** - * Recursively writes a data source Item and its children to a design. - * - * @since 7.5.0 - * @param design - * the element into which to insert the item - * @param itemId - * the id of the item to write - * @param context - * the DesignContext instance used in writing - * @return - */ - @Override - protected Element writeItem(Element design, Object itemId, - DesignContext context) { - Element element = design.appendElement("node"); - - element.attr("text", itemId.toString()); - - Resource icon = getItemIcon(itemId); - if (icon != null) { - DesignAttributeHandler.writeAttribute("icon", element.attributes(), - icon, null, Resource.class); - } - - if (isSelected(itemId)) { - element.attr("selected", ""); - } - - Collection<?> children = getChildren(itemId); - if (children != null) { - // Yeah... see #5864 - for (Object childItemId : children) { - writeItem(element, childItemId, context); - } - } - - return element; - } - - /** - * Sets whether html is allowed in the item captions. If set to - * <code>true</code>, the captions are passed to the browser as html and the - * developer is responsible for ensuring no harmful html is used. If set to - * <code>false</code>, the content is passed to the browser as plain text. - * The default setting is <code>false</code> - * - * @since 7.6 - * @param htmlContentAllowed - * <code>true</code> if the captions are used as html, - * <code>false</code> if used as plain text - */ - public void setHtmlContentAllowed(boolean htmlContentAllowed) { - this.htmlContentAllowed = htmlContentAllowed; - markAsDirty(); - } - - /** - * Checks whether captions are interpreted as html or plain text. - * - * @since 7.6 - * @return <code>true</code> if the captions are displayed as html, - * <code>false</code> if displayed as plain text - * @see #setHtmlContentAllowed(boolean) - */ - public boolean isHtmlContentAllowed() { - return htmlContentAllowed; - } - - @Override - protected TreeState getState() { - return (TreeState) super.getState(); - } -} diff --git a/server/src/main/java/com/vaadin/ui/TwinColSelect.java b/server/src/main/java/com/vaadin/ui/TwinColSelect.java deleted file mode 100644 index 261d813ffa..0000000000 --- a/server/src/main/java/com/vaadin/ui/TwinColSelect.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui; - -import java.util.Collection; - -import com.vaadin.data.Container; -import com.vaadin.server.PaintException; -import com.vaadin.server.PaintTarget; -import com.vaadin.shared.ui.twincolselect.TwinColSelectConstants; -import com.vaadin.shared.ui.twincolselect.TwinColSelectState; - -/** - * Multiselect component with two lists: left side for available items and right - * side for selected items. - */ -@SuppressWarnings("serial") -public class TwinColSelect extends AbstractSelect { - - private int rows = 0; - - private String leftColumnCaption; - private String rightColumnCaption; - - /** - * - */ - public TwinColSelect() { - super(); - setMultiSelect(true); - } - - /** - * @param caption - */ - public TwinColSelect(String caption) { - super(caption); - setMultiSelect(true); - } - - /** - * @param caption - * @param dataSource - */ - public TwinColSelect(String caption, Container dataSource) { - super(caption, dataSource); - setMultiSelect(true); - } - - public int getRows() { - return rows; - } - - /** - * Sets the number of rows in the editor. If the number of rows is set to 0, - * the actual number of displayed rows is determined implicitly by the - * adapter. - * <p> - * If a height if set (using {@link #setHeight(String)} or - * {@link #setHeight(float, int)}) it overrides the number of rows. Leave - * the height undefined to use this method. This is the opposite of how - * {@link #setColumns(int)} work. - * - * - * @param rows - * the number of rows to set. - */ - public void setRows(int rows) { - if (rows < 0) { - rows = 0; - } - if (this.rows != rows) { - this.rows = rows; - markAsDirty(); - } - } - - /** - * @param caption - * @param options - */ - public TwinColSelect(String caption, Collection<?> options) { - super(caption, options); - setMultiSelect(true); - } - - @Override - public void paintContent(PaintTarget target) throws PaintException { - // Adds the number of columns - // Adds the number of rows - if (rows != 0) { - target.addAttribute("rows", rows); - } - - // Right and left column captions and/or icons (if set) - String lc = getLeftColumnCaption(); - String rc = getRightColumnCaption(); - if (lc != null) { - target.addAttribute(TwinColSelectConstants.ATTRIBUTE_LEFT_CAPTION, - lc); - } - if (rc != null) { - target.addAttribute(TwinColSelectConstants.ATTRIBUTE_RIGHT_CAPTION, - rc); - } - - super.paintContent(target); - } - - /** - * Sets the text shown above the right column. - * - * @param caption - * The text to show - */ - public void setRightColumnCaption(String rightColumnCaption) { - this.rightColumnCaption = rightColumnCaption; - markAsDirty(); - } - - /** - * Returns the text shown above the right column. - * - * @return The text shown or null if not set. - */ - public String getRightColumnCaption() { - return rightColumnCaption; - } - - /** - * Sets the text shown above the left column. - * - * @param caption - * The text to show - */ - public void setLeftColumnCaption(String leftColumnCaption) { - this.leftColumnCaption = leftColumnCaption; - markAsDirty(); - } - - /** - * Returns the text shown above the left column. - * - * @return The text shown or null if not set. - */ - public String getLeftColumnCaption() { - return leftColumnCaption; - } - - @Override - protected TwinColSelectState getState() { - return (TwinColSelectState) super.getState(); - } - -} diff --git a/server/src/main/java/com/vaadin/ui/components/calendar/CalendarComponentEvent.java b/server/src/main/java/com/vaadin/ui/components/calendar/CalendarComponentEvent.java deleted file mode 100644 index f007f0cf34..0000000000 --- a/server/src/main/java/com/vaadin/ui/components/calendar/CalendarComponentEvent.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui.components.calendar; - -import com.vaadin.ui.Calendar; -import com.vaadin.ui.Component; - -/** - * All Calendar events extends this class. - * - * @since 7.1 - * @author Vaadin Ltd. - * - */ -@SuppressWarnings("serial") -public class CalendarComponentEvent extends Component.Event { - - /** - * Set the source of the event - * - * @param source - * The source calendar - * - */ - public CalendarComponentEvent(Calendar source) { - super(source); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.Component.Event#getComponent() - */ - @Override - public Calendar getComponent() { - return (Calendar) super.getComponent(); - } -} diff --git a/server/src/main/java/com/vaadin/ui/components/calendar/CalendarComponentEvents.java b/server/src/main/java/com/vaadin/ui/components/calendar/CalendarComponentEvents.java deleted file mode 100644 index 2c4fec95d4..0000000000 --- a/server/src/main/java/com/vaadin/ui/components/calendar/CalendarComponentEvents.java +++ /dev/null @@ -1,603 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui.components.calendar; - -import java.io.Serializable; -import java.lang.reflect.Method; -import java.util.Date; -import java.util.EventListener; - -import com.vaadin.shared.ui.calendar.CalendarEventId; -import com.vaadin.ui.Calendar; -import com.vaadin.ui.components.calendar.event.CalendarEvent; -import com.vaadin.util.ReflectTools; - -/** - * Interface for all Vaadin Calendar events. - * - * @since 7.1.0 - * @author Vaadin Ltd. - */ -public interface CalendarComponentEvents extends Serializable { - - /** - * Notifier interface for notifying listener of calendar events - */ - public interface CalendarEventNotifier extends Serializable { - /** - * Get the assigned event handler for the given eventId. - * - * @param eventId - * @return the assigned eventHandler, or null if no handler is assigned - */ - public EventListener getHandler(String eventId); - } - - /** - * Notifier interface for event drag & drops. - */ - public interface EventMoveNotifier extends CalendarEventNotifier { - - /** - * Set the EventMoveHandler. - * - * @param listener - * EventMoveHandler to be added - */ - public void setHandler(EventMoveHandler listener); - - } - - /** - * MoveEvent is sent when existing event is dragged to a new position. - */ - @SuppressWarnings("serial") - public class MoveEvent extends CalendarComponentEvent { - - public static final String EVENT_ID = CalendarEventId.EVENTMOVE; - - /** Index for the moved Schedule.Event. */ - private CalendarEvent calendarEvent; - - /** New starting date for the moved Calendar.Event. */ - private Date newStart; - - /** - * MoveEvent needs the target event and new start date. - * - * @param source - * Calendar component. - * @param calendarEvent - * Target event. - * @param newStart - * Target event's new start date. - */ - public MoveEvent(Calendar source, CalendarEvent calendarEvent, - Date newStart) { - super(source); - - this.calendarEvent = calendarEvent; - this.newStart = newStart; - } - - /** - * Get target event. - * - * @return Target event. - */ - public CalendarEvent getCalendarEvent() { - return calendarEvent; - } - - /** - * Get new start date. - * - * @return New start date. - */ - public Date getNewStart() { - return newStart; - } - } - - /** - * Handler interface for when events are being dragged on the calendar - * - */ - public interface EventMoveHandler extends EventListener, Serializable { - - /** Trigger method for the MoveEvent. */ - public static final Method eventMoveMethod = ReflectTools.findMethod( - EventMoveHandler.class, "eventMove", MoveEvent.class); - - /** - * This method will be called when event has been moved to a new - * position. - * - * @param event - * MoveEvent containing specific information of the new - * position and target event. - */ - public void eventMove(MoveEvent event); - } - - /** - * Handler interface for day or time cell drag-marking with mouse. - */ - public interface RangeSelectNotifier - extends Serializable, CalendarEventNotifier { - - /** - * Set the RangeSelectHandler that listens for drag-marking. - * - * @param listener - * RangeSelectHandler to be added. - */ - public void setHandler(RangeSelectHandler listener); - } - - /** - * RangeSelectEvent is sent when day or time cells are drag-marked with - * mouse. - */ - @SuppressWarnings("serial") - public class RangeSelectEvent extends CalendarComponentEvent { - - public static final String EVENT_ID = CalendarEventId.RANGESELECT; - - /** Calendar event's start date. */ - private Date start; - - /** Calendar event's end date. */ - private Date end; - - /** - * Defines the event's view mode. - */ - private boolean monthlyMode; - - /** - * RangeSelectEvent needs a start and end date. - * - * @param source - * Calendar component. - * @param start - * Start date. - * @param end - * End date. - * @param monthlyMode - * Calendar view mode. - */ - public RangeSelectEvent(Calendar source, Date start, Date end, - boolean monthlyMode) { - super(source); - this.start = start; - this.end = end; - this.monthlyMode = monthlyMode; - } - - /** - * Get start date. - * - * @return Start date. - */ - public Date getStart() { - return start; - } - - /** - * Get end date. - * - * @return End date. - */ - public Date getEnd() { - return end; - } - - /** - * Gets the event's view mode. Calendar can be be either in monthly or - * weekly mode, depending on the active date range. - * - * @deprecated User {@link Calendar#isMonthlyMode()} instead - * - * @return Returns true when monthly view is active. - */ - @Deprecated - public boolean isMonthlyMode() { - return monthlyMode; - } - } - - /** RangeSelectHandler handles RangeSelectEvent. */ - public interface RangeSelectHandler extends EventListener, Serializable { - - /** Trigger method for the RangeSelectEvent. */ - public static final Method rangeSelectMethod = ReflectTools.findMethod( - RangeSelectHandler.class, "rangeSelect", - RangeSelectEvent.class); - - /** - * This method will be called when day or time cells are drag-marked - * with mouse. - * - * @param event - * RangeSelectEvent that contains range start and end date. - */ - public void rangeSelect(RangeSelectEvent event); - } - - /** Notifier interface for navigation listening. */ - public interface NavigationNotifier extends Serializable { - /** - * Add a forward navigation listener. - * - * @param handler - * ForwardHandler to be added. - */ - public void setHandler(ForwardHandler handler); - - /** - * Add a backward navigation listener. - * - * @param handler - * BackwardHandler to be added. - */ - public void setHandler(BackwardHandler handler); - - /** - * Add a date click listener. - * - * @param handler - * DateClickHandler to be added. - */ - public void setHandler(DateClickHandler handler); - - /** - * Add a event click listener. - * - * @param handler - * EventClickHandler to be added. - */ - public void setHandler(EventClickHandler handler); - - /** - * Add a week click listener. - * - * @param handler - * WeekClickHandler to be added. - */ - public void setHandler(WeekClickHandler handler); - } - - /** - * ForwardEvent is sent when forward navigation button is clicked. - */ - @SuppressWarnings("serial") - public class ForwardEvent extends CalendarComponentEvent { - - public static final String EVENT_ID = CalendarEventId.FORWARD; - - /** - * ForwardEvent needs only the source component. - * - * @param source - * Calendar component. - */ - public ForwardEvent(Calendar source) { - super(source); - } - } - - /** ForwardHandler handles ForwardEvent. */ - public interface ForwardHandler extends EventListener, Serializable { - - /** Trigger method for the ForwardEvent. */ - public static final Method forwardMethod = ReflectTools.findMethod( - ForwardHandler.class, "forward", ForwardEvent.class); - - /** - * This method will be called when date range is moved forward. - * - * @param event - * ForwardEvent - */ - public void forward(ForwardEvent event); - } - - /** - * BackwardEvent is sent when backward navigation button is clicked. - */ - @SuppressWarnings("serial") - public class BackwardEvent extends CalendarComponentEvent { - - public static final String EVENT_ID = CalendarEventId.BACKWARD; - - /** - * BackwardEvent needs only the source source component. - * - * @param source - * Calendar component. - */ - public BackwardEvent(Calendar source) { - super(source); - } - } - - /** BackwardHandler handles BackwardEvent. */ - public interface BackwardHandler extends EventListener, Serializable { - - /** Trigger method for the BackwardEvent. */ - public static final Method backwardMethod = ReflectTools.findMethod( - BackwardHandler.class, "backward", BackwardEvent.class); - - /** - * This method will be called when date range is moved backwards. - * - * @param event - * BackwardEvent - */ - public void backward(BackwardEvent event); - } - - /** - * DateClickEvent is sent when a date is clicked. - */ - @SuppressWarnings("serial") - public class DateClickEvent extends CalendarComponentEvent { - - public static final String EVENT_ID = CalendarEventId.DATECLICK; - - /** Date that was clicked. */ - private Date date; - - /** DateClickEvent needs the target date that was clicked. */ - public DateClickEvent(Calendar source, Date date) { - super(source); - this.date = date; - } - - /** - * Get clicked date. - * - * @return Clicked date. - */ - public Date getDate() { - return date; - } - } - - /** DateClickHandler handles DateClickEvent. */ - public interface DateClickHandler extends EventListener, Serializable { - - /** Trigger method for the DateClickEvent. */ - public static final Method dateClickMethod = ReflectTools.findMethod( - DateClickHandler.class, "dateClick", DateClickEvent.class); - - /** - * This method will be called when a date is clicked. - * - * @param event - * DateClickEvent containing the target date. - */ - public void dateClick(DateClickEvent event); - } - - /** - * EventClick is sent when an event is clicked. - */ - @SuppressWarnings("serial") - public class EventClick extends CalendarComponentEvent { - - public static final String EVENT_ID = CalendarEventId.EVENTCLICK; - - /** Clicked source event. */ - private CalendarEvent calendarEvent; - - /** Target source event is needed for the EventClick. */ - public EventClick(Calendar source, CalendarEvent calendarEvent) { - super(source); - this.calendarEvent = calendarEvent; - } - - /** - * Get the clicked event. - * - * @return Clicked event. - */ - public CalendarEvent getCalendarEvent() { - return calendarEvent; - } - } - - /** EventClickHandler handles EventClick. */ - public interface EventClickHandler extends EventListener, Serializable { - - /** Trigger method for the EventClick. */ - public static final Method eventClickMethod = ReflectTools.findMethod( - EventClickHandler.class, "eventClick", EventClick.class); - - /** - * This method will be called when an event is clicked. - * - * @param event - * EventClick containing the target event. - */ - public void eventClick(EventClick event); - } - - /** - * WeekClick is sent when week is clicked. - */ - @SuppressWarnings("serial") - public class WeekClick extends CalendarComponentEvent { - - public static final String EVENT_ID = CalendarEventId.WEEKCLICK; - - /** Target week. */ - private int week; - - /** Target year. */ - private int year; - - /** - * WeekClick needs a target year and week. - * - * @param source - * Target source. - * @param week - * Target week. - * @param year - * Target year. - */ - public WeekClick(Calendar source, int week, int year) { - super(source); - this.week = week; - this.year = year; - } - - /** - * Get week as a integer. See {@link java.util.Calendar} for the allowed - * values. - * - * @return Week as a integer. - */ - public int getWeek() { - return week; - } - - /** - * Get year as a integer. See {@link java.util.Calendar} for the allowed - * values. - * - * @return Year as a integer - */ - public int getYear() { - return year; - } - } - - /** WeekClickHandler handles WeekClicks. */ - public interface WeekClickHandler extends EventListener, Serializable { - - /** Trigger method for the WeekClick. */ - public static final Method weekClickMethod = ReflectTools.findMethod( - WeekClickHandler.class, "weekClick", WeekClick.class); - - /** - * This method will be called when a week is clicked. - * - * @param event - * WeekClick containing the target week and year. - */ - public void weekClick(WeekClick event); - } - - /** - * EventResize is sent when an event is resized - */ - @SuppressWarnings("serial") - public class EventResize extends CalendarComponentEvent { - - public static final String EVENT_ID = CalendarEventId.EVENTRESIZE; - - private CalendarEvent calendarEvent; - - private Date startTime; - - private Date endTime; - - public EventResize(Calendar source, CalendarEvent calendarEvent, - Date startTime, Date endTime) { - super(source); - this.calendarEvent = calendarEvent; - this.startTime = startTime; - this.endTime = endTime; - } - - /** - * Get target event. - * - * @return Target event. - */ - public CalendarEvent getCalendarEvent() { - return calendarEvent; - } - - /** - * @deprecated Use {@link #getNewStart()} instead - * - * @return the new start time - */ - @Deprecated - public Date getNewStartTime() { - return startTime; - } - - /** - * Returns the updated start date/time of the event - * - * @return The new date for the event - */ - public Date getNewStart() { - return startTime; - } - - /** - * @deprecated Use {@link #getNewEnd()} instead - * - * @return the new end time - */ - @Deprecated - public Date getNewEndTime() { - return endTime; - } - - /** - * Returns the updates end date/time of the event - * - * @return The new date for the event - */ - public Date getNewEnd() { - return endTime; - } - } - - /** - * Notifier interface for event resizing. - */ - public interface EventResizeNotifier extends Serializable { - - /** - * Set a EventResizeHandler. - * - * @param handler - * EventResizeHandler to be set - */ - public void setHandler(EventResizeHandler handler); - } - - /** - * Handler for EventResize event. - */ - public interface EventResizeHandler extends EventListener, Serializable { - - /** Trigger method for the EventResize. */ - public static final Method eventResizeMethod = ReflectTools.findMethod( - EventResizeHandler.class, "eventResize", EventResize.class); - - void eventResize(EventResize event); - } - -} diff --git a/server/src/main/java/com/vaadin/ui/components/calendar/CalendarDateRange.java b/server/src/main/java/com/vaadin/ui/components/calendar/CalendarDateRange.java deleted file mode 100644 index 09d6c80a7f..0000000000 --- a/server/src/main/java/com/vaadin/ui/components/calendar/CalendarDateRange.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui.components.calendar; - -import java.io.Serializable; -import java.util.Date; -import java.util.TimeZone; - -/** - * Class for representing a date range. - * - * @since 7.1.0 - * @author Vaadin Ltd. - * - */ -@SuppressWarnings("serial") -public class CalendarDateRange implements Serializable { - - private Date start; - - private Date end; - - private final transient TimeZone tz; - - /** - * Constructor - * - * @param start - * The start date and time of the date range - * @param end - * The end date and time of the date range - */ - public CalendarDateRange(Date start, Date end, TimeZone tz) { - super(); - this.start = start; - this.end = end; - this.tz = tz; - } - - /** - * Get the start date of the date range - * - * @return the start Date of the range - */ - public Date getStart() { - return start; - } - - /** - * Get the end date of the date range - * - * @return the end Date of the range - */ - public Date getEnd() { - return end; - } - - /** - * Is a date in the date range - * - * @param date - * The date to check - * @return true if the date range contains a date start and end of range - * inclusive; false otherwise - */ - public boolean inRange(Date date) { - if (date == null) { - return false; - } - - return date.compareTo(start) >= 0 && date.compareTo(end) <= 0; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return "CalendarDateRange [start=" + start + ", end=" + end + "]"; - } - -} diff --git a/server/src/main/java/com/vaadin/ui/components/calendar/CalendarTargetDetails.java b/server/src/main/java/com/vaadin/ui/components/calendar/CalendarTargetDetails.java deleted file mode 100644 index 3b71ab5a00..0000000000 --- a/server/src/main/java/com/vaadin/ui/components/calendar/CalendarTargetDetails.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui.components.calendar; - -import java.util.Date; -import java.util.Map; - -import com.vaadin.event.dd.DropTarget; -import com.vaadin.event.dd.TargetDetailsImpl; -import com.vaadin.ui.Calendar; - -/** - * Drop details for {@link com.vaadin.ui.addon.calendar.ui.Calendar Calendar}. - * When something is dropped on the Calendar, this class contains the specific - * details of the drop point. Specifically, this class gives access to the date - * where the drop happened. If the Calendar was in weekly mode, the date also - * includes the start time of the slot. - * - * @since 7.1 - * @author Vaadin Ltd. - */ -@SuppressWarnings("serial") -public class CalendarTargetDetails extends TargetDetailsImpl { - - private boolean hasDropTime; - - public CalendarTargetDetails(Map<String, Object> rawDropData, - DropTarget dropTarget) { - super(rawDropData, dropTarget); - } - - /** - * @return true if {@link #getDropTime()} will return a date object with the - * time set to the start of the time slot where the drop happened - */ - public boolean hasDropTime() { - return hasDropTime; - } - - /** - * Does the dropped item have a time associated with it - * - * @param hasDropTime - */ - public void setHasDropTime(boolean hasDropTime) { - this.hasDropTime = hasDropTime; - } - - /** - * @return the date where the drop happened - */ - public Date getDropTime() { - if (hasDropTime) { - return (Date) getData("dropTime"); - } else { - return (Date) getData("dropDay"); - } - } - - /** - * @return the {@link com.vaadin.ui.addon.calendar.ui.Calendar Calendar} - * instance which was the target of the drop - */ - public Calendar getTargetCalendar() { - return (Calendar) getTarget(); - } -} diff --git a/server/src/main/java/com/vaadin/ui/components/calendar/ContainerEventProvider.java b/server/src/main/java/com/vaadin/ui/components/calendar/ContainerEventProvider.java deleted file mode 100644 index b0a6aaa95a..0000000000 --- a/server/src/main/java/com/vaadin/ui/components/calendar/ContainerEventProvider.java +++ /dev/null @@ -1,566 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui.components.calendar; - -import java.util.Collections; -import java.util.Date; -import java.util.LinkedList; -import java.util.List; - -import com.vaadin.data.Container; -import com.vaadin.data.Container.Indexed; -import com.vaadin.data.Container.ItemSetChangeEvent; -import com.vaadin.data.Container.ItemSetChangeNotifier; -import com.vaadin.data.Item; -import com.vaadin.data.Property; -import com.vaadin.data.Property.ValueChangeEvent; -import com.vaadin.data.Property.ValueChangeNotifier; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventMoveHandler; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventResize; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventResizeHandler; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.MoveEvent; -import com.vaadin.ui.components.calendar.event.BasicEvent; -import com.vaadin.ui.components.calendar.event.CalendarEditableEventProvider; -import com.vaadin.ui.components.calendar.event.CalendarEvent; -import com.vaadin.ui.components.calendar.event.CalendarEvent.EventChangeListener; -import com.vaadin.ui.components.calendar.event.CalendarEvent.EventChangeNotifier; -import com.vaadin.ui.components.calendar.event.CalendarEventProvider; -import com.vaadin.ui.components.calendar.event.CalendarEventProvider.EventSetChangeNotifier; - -/** - * A event provider which uses a {@link Container} as a datasource. Container - * used as data source. - * - * NOTE: The data source must be sorted by date! - * - * @since 7.1.0 - * @author Vaadin Ltd. - */ -@SuppressWarnings("serial") -public class ContainerEventProvider - implements CalendarEditableEventProvider, EventSetChangeNotifier, - EventChangeNotifier, EventMoveHandler, EventResizeHandler, - Container.ItemSetChangeListener, Property.ValueChangeListener { - - // Default property ids - public static final String CAPTION_PROPERTY = "caption"; - public static final String DESCRIPTION_PROPERTY = "description"; - public static final String STARTDATE_PROPERTY = "start"; - public static final String ENDDATE_PROPERTY = "end"; - public static final String STYLENAME_PROPERTY = "styleName"; - public static final String ALL_DAY_PROPERTY = "allDay"; - - /** - * Internal class to keep the container index which item this event - * represents - * - */ - private class ContainerCalendarEvent extends BasicEvent { - private final int index; - - public ContainerCalendarEvent(int containerIndex) { - super(); - index = containerIndex; - } - - public int getContainerIndex() { - return index; - } - } - - /** - * Listeners attached to the container - */ - private final List<EventSetChangeListener> eventSetChangeListeners = new LinkedList<CalendarEventProvider.EventSetChangeListener>(); - private final List<EventChangeListener> eventChangeListeners = new LinkedList<CalendarEvent.EventChangeListener>(); - - /** - * The event cache contains the events previously created by - * {@link #getEvents(Date, Date)} - */ - private final List<CalendarEvent> eventCache = new LinkedList<CalendarEvent>(); - - /** - * The container used as datasource - */ - private Indexed container; - - /** - * Container properties. Defaults based on using the {@link BasicEvent} - * helper class. - */ - private Object captionProperty = CAPTION_PROPERTY; - private Object descriptionProperty = DESCRIPTION_PROPERTY; - private Object startDateProperty = STARTDATE_PROPERTY; - private Object endDateProperty = ENDDATE_PROPERTY; - private Object styleNameProperty = STYLENAME_PROPERTY; - private Object allDayProperty = ALL_DAY_PROPERTY; - - /** - * Constructor - * - * @param container - * Container to use as a data source. - */ - public ContainerEventProvider(Container.Indexed container) { - this.container = container; - listenToContainerEvents(); - } - - /** - * Set the container data source - * - * @param container - * The container to use as datasource - * - */ - public void setContainerDataSource(Container.Indexed container) { - // Detach the previous container - detachContainerDataSource(); - - this.container = container; - listenToContainerEvents(); - } - - /** - * Returns the container used as data source - * - */ - public Container.Indexed getContainerDataSource() { - return container; - } - - /** - * Attaches listeners to the container so container events can be processed - */ - private void listenToContainerEvents() { - if (container instanceof ItemSetChangeNotifier) { - ((ItemSetChangeNotifier) container).addItemSetChangeListener(this); - } - if (container instanceof ValueChangeNotifier) { - ((ValueChangeNotifier) container).addValueChangeListener(this); - } - } - - /** - * Removes listeners from the container so no events are processed - */ - private void ignoreContainerEvents() { - if (container instanceof ItemSetChangeNotifier) { - ((ItemSetChangeNotifier) container) - .removeItemSetChangeListener(this); - } - if (container instanceof ValueChangeNotifier) { - ((ValueChangeNotifier) container).removeValueChangeListener(this); - } - } - - /** - * Converts an event in the container to an {@link CalendarEvent} - * - * @param index - * The index of the item in the container to get the event for - * @return - */ - private CalendarEvent getEvent(int index) { - - // Check the event cache first - for (CalendarEvent e : eventCache) { - if (e instanceof ContainerCalendarEvent - && ((ContainerCalendarEvent) e) - .getContainerIndex() == index) { - return e; - } else if (container.getIdByIndex(index) == e) { - return e; - } - } - - final Object id = container.getIdByIndex(index); - Item item = container.getItem(id); - CalendarEvent event; - if (id instanceof CalendarEvent) { - /* - * If we are using the BeanItemContainer or another container which - * stores the objects as ids then just return the instances - */ - event = (CalendarEvent) id; - - } else { - /* - * Else we use the properties to create the event - */ - BasicEvent basicEvent = new ContainerCalendarEvent(index); - - // Set values from property values - if (captionProperty != null - && item.getItemPropertyIds().contains(captionProperty)) { - basicEvent.setCaption(String.valueOf( - item.getItemProperty(captionProperty).getValue())); - } - if (descriptionProperty != null && item.getItemPropertyIds() - .contains(descriptionProperty)) { - basicEvent.setDescription(String.valueOf( - item.getItemProperty(descriptionProperty).getValue())); - } - if (startDateProperty != null - && item.getItemPropertyIds().contains(startDateProperty)) { - basicEvent.setStart((Date) item - .getItemProperty(startDateProperty).getValue()); - } - if (endDateProperty != null - && item.getItemPropertyIds().contains(endDateProperty)) { - basicEvent.setEnd((Date) item.getItemProperty(endDateProperty) - .getValue()); - } - if (styleNameProperty != null - && item.getItemPropertyIds().contains(styleNameProperty)) { - basicEvent.setStyleName(String.valueOf( - item.getItemProperty(styleNameProperty).getValue())); - } - if (allDayProperty != null - && item.getItemPropertyIds().contains(allDayProperty)) { - basicEvent.setAllDay((Boolean) item - .getItemProperty(allDayProperty).getValue()); - } - event = basicEvent; - } - return event; - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.event.CalendarEventProvider#getEvents(java. - * util.Date, java.util.Date) - */ - @Override - public List<CalendarEvent> getEvents(Date startDate, Date endDate) { - eventCache.clear(); - int size = container.size(); - assert size >= 0; - - for (int i = 0; i < size; i++) { - Object id = container.getIdByIndex(i); - Item item = container.getItem(id); - boolean add = true; - if (startDate != null) { - Date eventEnd = (Date) item.getItemProperty(endDateProperty) - .getValue(); - if (eventEnd.compareTo(startDate) < 0) { - add = false; - } - } - if (add && endDate != null) { - Date eventStart = (Date) item.getItemProperty(startDateProperty) - .getValue(); - if (eventStart.compareTo(endDate) >= 0) { - break; // because container is sorted, all further events - // will be even later - } - } - if (add) { - eventCache.add(getEvent(i)); - } - } - return Collections.unmodifiableList(eventCache); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.calendar.event.CalendarEventProvider. - * EventSetChangeNotifier - * #addListener(com.vaadin.addon.calendar.event.CalendarEventProvider. - * EventSetChangeListener) - */ - @Override - public void addEventSetChangeListener(EventSetChangeListener listener) { - if (!eventSetChangeListeners.contains(listener)) { - eventSetChangeListeners.add(listener); - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.calendar.event.CalendarEventProvider. - * EventSetChangeNotifier - * #removeListener(com.vaadin.addon.calendar.event.CalendarEventProvider. - * EventSetChangeListener) - */ - @Override - public void removeEventSetChangeListener(EventSetChangeListener listener) { - eventSetChangeListeners.remove(listener); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.calendar.event.CalendarEvent.EventChangeNotifier# - * addListener - * (com.vaadin.addon.calendar.event.CalendarEvent.EventChangeListener) - */ - @Override - public void addEventChangeListener(EventChangeListener listener) { - if (eventChangeListeners.contains(listener)) { - eventChangeListeners.add(listener); - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.calendar.event.CalendarEvent.EventChangeNotifier# - * removeListener - * (com.vaadin.addon.calendar.event.CalendarEvent.EventChangeListener) - */ - @Override - public void removeEventChangeListener(EventChangeListener listener) { - eventChangeListeners.remove(listener); - } - - /** - * Get the property which provides the caption of the event - */ - public Object getCaptionProperty() { - return captionProperty; - } - - /** - * Set the property which provides the caption of the event - */ - public void setCaptionProperty(Object captionProperty) { - this.captionProperty = captionProperty; - } - - /** - * Get the property which provides the description of the event - */ - public Object getDescriptionProperty() { - return descriptionProperty; - } - - /** - * Set the property which provides the description of the event - */ - public void setDescriptionProperty(Object descriptionProperty) { - this.descriptionProperty = descriptionProperty; - } - - /** - * Get the property which provides the starting date and time of the event - */ - public Object getStartDateProperty() { - return startDateProperty; - } - - /** - * Set the property which provides the starting date and time of the event - */ - public void setStartDateProperty(Object startDateProperty) { - this.startDateProperty = startDateProperty; - } - - /** - * Get the property which provides the ending date and time of the event - */ - public Object getEndDateProperty() { - return endDateProperty; - } - - /** - * Set the property which provides the ending date and time of the event - */ - public void setEndDateProperty(Object endDateProperty) { - this.endDateProperty = endDateProperty; - } - - /** - * Get the property which provides the style name for the event - */ - public Object getStyleNameProperty() { - return styleNameProperty; - } - - /** - * Set the property which provides the style name for the event - */ - public void setStyleNameProperty(Object styleNameProperty) { - this.styleNameProperty = styleNameProperty; - } - - /** - * Set the all day property for the event - * - * @since 7.3.4 - */ - public void setAllDayProperty(Object allDayProperty) { - this.allDayProperty = allDayProperty; - } - - /** - * Get the all day property for the event - * - * @since 7.3.4 - */ - public Object getAllDayProperty() { - return allDayProperty; - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.Container.ItemSetChangeListener#containerItemSetChange - * (com.vaadin.data.Container.ItemSetChangeEvent) - */ - @Override - public void containerItemSetChange(ItemSetChangeEvent event) { - if (event.getContainer() == container) { - // Trigger an eventset change event when the itemset changes - for (EventSetChangeListener listener : eventSetChangeListeners) { - listener.eventSetChange(new EventSetChangeEvent(this)); - } - } - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.Property.ValueChangeListener#valueChange(com.vaadin.data - * .Property.ValueChangeEvent) - */ - @Override - public void valueChange(ValueChangeEvent event) { - /* - * TODO Need to figure out how to get the item which triggered the the - * valuechange event and then trigger a EventChange event to the - * listeners - */ - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventMoveHandler - * #eventMove - * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.MoveEvent) - */ - @Override - public void eventMove(MoveEvent event) { - CalendarEvent ce = event.getCalendarEvent(); - if (eventCache.contains(ce)) { - int index; - if (ce instanceof ContainerCalendarEvent) { - index = ((ContainerCalendarEvent) ce).getContainerIndex(); - } else { - index = container.indexOfId(ce); - } - - long eventLength = ce.getEnd().getTime() - ce.getStart().getTime(); - Date newEnd = new Date(event.getNewStart().getTime() + eventLength); - - ignoreContainerEvents(); - Item item = container.getItem(container.getIdByIndex(index)); - item.getItemProperty(startDateProperty) - .setValue(event.getNewStart()); - item.getItemProperty(endDateProperty).setValue(newEnd); - listenToContainerEvents(); - } - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventResizeHandler - * #eventResize - * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventResize) - */ - @Override - public void eventResize(EventResize event) { - CalendarEvent ce = event.getCalendarEvent(); - if (eventCache.contains(ce)) { - int index; - if (ce instanceof ContainerCalendarEvent) { - index = ((ContainerCalendarEvent) ce).getContainerIndex(); - } else { - index = container.indexOfId(ce); - } - ignoreContainerEvents(); - Item item = container.getItem(container.getIdByIndex(index)); - item.getItemProperty(startDateProperty) - .setValue(event.getNewStart()); - item.getItemProperty(endDateProperty).setValue(event.getNewEnd()); - listenToContainerEvents(); - } - } - - /** - * If you are reusing the container which previously have been attached to - * this ContainerEventProvider call this method to remove this event - * providers container listeners before attaching it to an other - * ContainerEventProvider - */ - public void detachContainerDataSource() { - ignoreContainerEvents(); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.event.CalendarEditableEventProvider#addEvent - * (com.vaadin.addon.calendar.event.CalendarEvent) - */ - @Override - public void addEvent(CalendarEvent event) { - Item item; - try { - item = container.addItem(event); - } catch (UnsupportedOperationException uop) { - // Thrown if container does not support adding items with custom - // ids. JPAContainer for example. - item = container.getItem(container.addItem()); - } - if (item != null) { - item.getItemProperty(getCaptionProperty()) - .setValue(event.getCaption()); - item.getItemProperty(getStartDateProperty()) - .setValue(event.getStart()); - item.getItemProperty(getEndDateProperty()).setValue(event.getEnd()); - item.getItemProperty(getStyleNameProperty()) - .setValue(event.getStyleName()); - item.getItemProperty(getDescriptionProperty()) - .setValue(event.getDescription()); - } - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.event.CalendarEditableEventProvider#removeEvent - * (com.vaadin.addon.calendar.event.CalendarEvent) - */ - @Override - public void removeEvent(CalendarEvent event) { - container.removeItem(event); - } -} diff --git a/server/src/main/java/com/vaadin/ui/components/calendar/event/BasicEvent.java b/server/src/main/java/com/vaadin/ui/components/calendar/event/BasicEvent.java deleted file mode 100644 index e2a580085a..0000000000 --- a/server/src/main/java/com/vaadin/ui/components/calendar/event/BasicEvent.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui.components.calendar.event; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -import com.vaadin.ui.components.calendar.event.CalendarEvent.EventChangeNotifier; - -/** - * Simple implementation of {@link com.vaadin.addon.calendar.event.CalendarEvent - * CalendarEvent}. Has setters for all required fields and fires events when - * this event is changed. - * - * @since 7.1.0 - * @author Vaadin Ltd. - */ -@SuppressWarnings("serial") -public class BasicEvent implements EditableCalendarEvent, EventChangeNotifier { - - private String caption; - private String description; - private Date end; - private Date start; - private String styleName; - private transient List<EventChangeListener> listeners = new ArrayList<EventChangeListener>(); - - private boolean isAllDay; - - /** - * Default constructor - */ - public BasicEvent() { - - } - - /** - * Constructor for creating an event with the same start and end date - * - * @param caption - * The caption for the event - * @param description - * The description for the event - * @param date - * The date the event occurred - */ - public BasicEvent(String caption, String description, Date date) { - this.caption = caption; - this.description = description; - start = date; - end = date; - } - - /** - * Constructor for creating an event with a start date and an end date. - * Start date should be before the end date - * - * @param caption - * The caption for the event - * @param description - * The description for the event - * @param startDate - * The start date of the event - * @param endDate - * The end date of the event - */ - public BasicEvent(String caption, String description, Date startDate, - Date endDate) { - this.caption = caption; - this.description = description; - start = startDate; - end = endDate; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.calendar.event.CalendarEvent#getCaption() - */ - @Override - public String getCaption() { - return caption; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.calendar.event.CalendarEvent#getDescription() - */ - @Override - public String getDescription() { - return description; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.calendar.event.CalendarEvent#getEnd() - */ - @Override - public Date getEnd() { - return end; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.calendar.event.CalendarEvent#getStart() - */ - @Override - public Date getStart() { - return start; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.calendar.event.CalendarEvent#getStyleName() - */ - @Override - public String getStyleName() { - return styleName; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.calendar.event.CalendarEvent#isAllDay() - */ - @Override - public boolean isAllDay() { - return isAllDay; - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.event.CalendarEventEditor#setCaption(java.lang - * .String) - */ - @Override - public void setCaption(String caption) { - this.caption = caption; - fireEventChange(); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.event.CalendarEventEditor#setDescription(java - * .lang.String) - */ - @Override - public void setDescription(String description) { - this.description = description; - fireEventChange(); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.event.CalendarEventEditor#setEnd(java.util. - * Date) - */ - @Override - public void setEnd(Date end) { - this.end = end; - fireEventChange(); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.event.CalendarEventEditor#setStart(java.util - * .Date) - */ - @Override - public void setStart(Date start) { - this.start = start; - fireEventChange(); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.event.CalendarEventEditor#setStyleName(java - * .lang.String) - */ - @Override - public void setStyleName(String styleName) { - this.styleName = styleName; - fireEventChange(); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.event.CalendarEventEditor#setAllDay(boolean) - */ - @Override - public void setAllDay(boolean isAllDay) { - this.isAllDay = isAllDay; - fireEventChange(); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventChangeNotifier - * #addListener - * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventChangeListener - * ) - */ - @Override - public void addEventChangeListener(EventChangeListener listener) { - listeners.add(listener); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventChangeNotifier - * #removeListener - * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventChangeListener - * ) - */ - @Override - public void removeEventChangeListener(EventChangeListener listener) { - listeners.remove(listener); - } - - /** - * Fires an event change event to the listeners. Should be triggered when - * some property of the event changes. - */ - protected void fireEventChange() { - EventChangeEvent event = new EventChangeEvent(this); - - for (EventChangeListener listener : listeners) { - listener.eventChange(event); - } - } -} diff --git a/server/src/main/java/com/vaadin/ui/components/calendar/event/BasicEventProvider.java b/server/src/main/java/com/vaadin/ui/components/calendar/event/BasicEventProvider.java deleted file mode 100644 index fbf197d3eb..0000000000 --- a/server/src/main/java/com/vaadin/ui/components/calendar/event/BasicEventProvider.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui.components.calendar.event; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -import com.vaadin.ui.components.calendar.event.CalendarEvent.EventChangeEvent; -import com.vaadin.ui.components.calendar.event.CalendarEventProvider.EventSetChangeNotifier; - -/** - * <p> - * Simple implementation of - * {@link com.vaadin.addon.calendar.event.CalendarEventProvider - * CalendarEventProvider}. Use {@link #addEvent(CalendarEvent)} and - * {@link #removeEvent(CalendarEvent)} to add / remove events. - * </p> - * - * <p> - * {@link com.vaadin.addon.calendar.event.CalendarEventProvider.EventSetChangeNotifier - * EventSetChangeNotifier} and - * {@link com.vaadin.addon.calendar.event.CalendarEvent.EventChangeListener - * EventChangeListener} are also implemented, so the Calendar is notified when - * an event is added, changed or removed. - * </p> - * - * @since 7.1.0 - * @author Vaadin Ltd. - */ -@SuppressWarnings("serial") -public class BasicEventProvider implements CalendarEditableEventProvider, - EventSetChangeNotifier, CalendarEvent.EventChangeListener { - - protected List<CalendarEvent> eventList = new ArrayList<CalendarEvent>(); - - private List<EventSetChangeListener> listeners = new ArrayList<EventSetChangeListener>(); - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.event.CalendarEventProvider#getEvents(java. - * util.Date, java.util.Date) - */ - @Override - public List<CalendarEvent> getEvents(Date startDate, Date endDate) { - ArrayList<CalendarEvent> activeEvents = new ArrayList<CalendarEvent>(); - - for (CalendarEvent ev : eventList) { - long from = startDate.getTime(); - long to = endDate.getTime(); - - if (ev.getStart() != null && ev.getEnd() != null) { - long f = ev.getStart().getTime(); - long t = ev.getEnd().getTime(); - // Select only events that overlaps with startDate and - // endDate. - if ((f <= to && f >= from) || (t >= from && t <= to) - || (f <= from && t >= to)) { - activeEvents.add(ev); - } - } - } - - return activeEvents; - } - - /** - * Does this event provider container this event - * - * @param event - * The event to check for - * @return If this provider has the event then true is returned, else false - */ - public boolean containsEvent(BasicEvent event) { - return eventList.contains(event); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.calendar.ui.CalendarComponentEvents. - * EventSetChangeNotifier #addListener - * (com.vaadin.addon.calendar.ui.CalendarComponentEvents. - * EventSetChangeListener ) - */ - @Override - public void addEventSetChangeListener(EventSetChangeListener listener) { - listeners.add(listener); - - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.calendar.ui.CalendarComponentEvents. - * EventSetChangeNotifier #removeListener - * (com.vaadin.addon.calendar.ui.CalendarComponentEvents. - * EventSetChangeListener ) - */ - @Override - public void removeEventSetChangeListener(EventSetChangeListener listener) { - listeners.remove(listener); - } - - /** - * Fires a eventsetchange event. The event is fired when either an event is - * added or removed to the event provider - */ - protected void fireEventSetChange() { - EventSetChangeEvent event = new EventSetChangeEvent(this); - - for (EventSetChangeListener listener : listeners) { - listener.eventSetChange(event); - } - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventChangeListener - * #eventChange - * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventSetChange) - */ - @Override - public void eventChange(EventChangeEvent changeEvent) { - // naive implementation - fireEventSetChange(); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.event.CalendarEditableEventProvider#addEvent - * (com.vaadin.addon.calendar.event.CalendarEvent) - */ - @Override - public void addEvent(CalendarEvent event) { - eventList.add(event); - if (event instanceof BasicEvent) { - ((BasicEvent) event).addEventChangeListener(this); - } - fireEventSetChange(); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.event.CalendarEditableEventProvider#removeEvent - * (com.vaadin.addon.calendar.event.CalendarEvent) - */ - @Override - public void removeEvent(CalendarEvent event) { - eventList.remove(event); - if (event instanceof BasicEvent) { - ((BasicEvent) event).removeEventChangeListener(this); - } - fireEventSetChange(); - } -} diff --git a/server/src/main/java/com/vaadin/ui/components/calendar/event/CalendarEditableEventProvider.java b/server/src/main/java/com/vaadin/ui/components/calendar/event/CalendarEditableEventProvider.java deleted file mode 100644 index aaa76418a6..0000000000 --- a/server/src/main/java/com/vaadin/ui/components/calendar/event/CalendarEditableEventProvider.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui.components.calendar.event; - -/** - * An event provider which allows adding and removing events - * - * @since 7.1.0 - * @author Vaadin Ltd. - */ -public interface CalendarEditableEventProvider extends CalendarEventProvider { - - /** - * Adds an event to the event provider - * - * @param event - * The event to add - */ - void addEvent(CalendarEvent event); - - /** - * Removes an event from the event provider - * - * @param event - * The event - */ - void removeEvent(CalendarEvent event); -} diff --git a/server/src/main/java/com/vaadin/ui/components/calendar/event/CalendarEvent.java b/server/src/main/java/com/vaadin/ui/components/calendar/event/CalendarEvent.java deleted file mode 100644 index b4195cf0b1..0000000000 --- a/server/src/main/java/com/vaadin/ui/components/calendar/event/CalendarEvent.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui.components.calendar.event; - -import java.io.Serializable; -import java.util.Date; - -/** - * <p> - * Event in the calendar. Customize your own event by implementing this - * interface. - * </p> - * - * <li>Start and end fields are mandatory.</li> - * - * <li>In "allDay" events longer than one day, starting and ending clock times - * are omitted in UI and only dates are shown.</li> - * - * @since 7.1.0 - * @author Vaadin Ltd. - * - */ -public interface CalendarEvent extends Serializable { - - /** - * Gets start date of event. - * - * @return Start date. - */ - public Date getStart(); - - /** - * Get end date of event. - * - * @return End date; - */ - public Date getEnd(); - - /** - * Gets caption of event. - * - * @return Caption text - */ - public String getCaption(); - - /** - * Gets description of event. Shown as a tooltip over the event. - * - * @return Description text. - */ - public String getDescription(); - - /** - * <p> - * Gets style name of event. In the client, style name will be set to the - * event's element class name and can be styled by CSS - * </p> - * Styling example:</br> - * <code>Java code: </br> - * event.setStyleName("color1"); - * </br></br> - * CSS:</br> - * .v-calendar-event-color1 {</br> - * background-color: #9effae;</br>}</code> - * - * @return Style name. - */ - public String getStyleName(); - - /** - * An all-day event typically does not occur at a specific time but targets - * a whole day or days. The rendering of all-day events differs from normal - * events. - * - * @return true if this event is an all-day event, false otherwise - */ - public boolean isAllDay(); - - /** - * Event to signal that an event has changed. - */ - @SuppressWarnings("serial") - public class EventChangeEvent implements Serializable { - - private CalendarEvent source; - - public EventChangeEvent(CalendarEvent source) { - this.source = source; - } - - /** - * @return the {@link com.vaadin.addon.calendar.event.CalendarEvent - * CalendarEvent} that has changed - */ - public CalendarEvent getCalendarEvent() { - return source; - } - } - - /** - * Listener for EventSetChange events. - */ - public interface EventChangeListener extends Serializable { - - /** - * Called when an Event has changed. - */ - public void eventChange(EventChangeEvent eventChangeEvent); - } - - /** - * Notifier interface for EventChange events. - */ - public interface EventChangeNotifier extends Serializable { - - /** - * Add a listener to listen for EventChangeEvents. These events are - * fired when a events properties are changed. - * - * @param listener - * The listener to add - */ - void addEventChangeListener(EventChangeListener listener); - - /** - * Remove a listener from the event provider. - * - * @param listener - * The listener to remove - */ - void removeEventChangeListener(EventChangeListener listener); - } - -} diff --git a/server/src/main/java/com/vaadin/ui/components/calendar/event/CalendarEventProvider.java b/server/src/main/java/com/vaadin/ui/components/calendar/event/CalendarEventProvider.java deleted file mode 100644 index 1d4fabed5a..0000000000 --- a/server/src/main/java/com/vaadin/ui/components/calendar/event/CalendarEventProvider.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui.components.calendar.event; - -import java.io.Serializable; -import java.util.Date; -import java.util.List; - -/** - * Interface for querying events. The Vaadin Calendar always has a - * CalendarEventProvider set. - * - * @since 7.1.0 - * @author Vaadin Ltd. - */ -public interface CalendarEventProvider extends Serializable { - /** - * <p> - * Gets all available events in the target date range between startDate and - * endDate. The Vaadin Calendar queries the events from the range that is - * shown, which is not guaranteed to be the same as the date range that is - * set. - * </p> - * - * <p> - * For example, if you set the date range to be monday 22.2.2010 - wednesday - * 24.2.2010, the used Event Provider will be queried for events between - * monday 22.2.2010 00:00 and sunday 28.2.2010 23:59. Generally you can - * expect the date range to be expanded to whole days and whole weeks. - * </p> - * - * @param startDate - * Start date - * @param endDate - * End date - * @return List of events - */ - public List<CalendarEvent> getEvents(Date startDate, Date endDate); - - /** - * Event to signal that the set of events has changed and the calendar - * should refresh its view from the - * {@link com.vaadin.addon.calendar.event.CalendarEventProvider - * CalendarEventProvider} . - * - */ - @SuppressWarnings("serial") - public class EventSetChangeEvent implements Serializable { - - private CalendarEventProvider source; - - public EventSetChangeEvent(CalendarEventProvider source) { - this.source = source; - } - - /** - * @return the - * {@link com.vaadin.addon.calendar.event.CalendarEventProvider - * CalendarEventProvider} that has changed - */ - public CalendarEventProvider getProvider() { - return source; - } - } - - /** - * Listener for EventSetChange events. - */ - public interface EventSetChangeListener extends Serializable { - - /** - * Called when the set of Events has changed. - */ - public void eventSetChange(EventSetChangeEvent changeEvent); - } - - /** - * Notifier interface for EventSetChange events. - */ - public interface EventSetChangeNotifier extends Serializable { - - /** - * Add a listener for listening to when new events are adding or removed - * from the event provider. - * - * @param listener - * The listener to add - */ - void addEventSetChangeListener(EventSetChangeListener listener); - - /** - * Remove a listener which listens to {@link EventSetChangeEvent}-events - * - * @param listener - * The listener to remove - */ - void removeEventSetChangeListener(EventSetChangeListener listener); - } -} diff --git a/server/src/main/java/com/vaadin/ui/components/calendar/event/EditableCalendarEvent.java b/server/src/main/java/com/vaadin/ui/components/calendar/event/EditableCalendarEvent.java deleted file mode 100644 index 5a44cae4ac..0000000000 --- a/server/src/main/java/com/vaadin/ui/components/calendar/event/EditableCalendarEvent.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui.components.calendar.event; - -import java.util.Date; - -/** - * <p> - * Extension to the basic {@link com.vaadin.addon.calendar.event.CalendarEvent - * CalendarEvent}. This interface provides setters (and thus editing - * capabilities) for all {@link com.vaadin.addon.calendar.event.CalendarEvent - * CalendarEvent} fields. For descriptions on the fields, refer to the extended - * interface. - * </p> - * - * <p> - * This interface is used by some of the basic Calendar event handlers in the - * <code>com.vaadin.addon.calendar.ui.handler</code> package to determine - * whether an event can be edited. - * </p> - * - * @since 7.1 - * @author Vaadin Ltd. - */ -public interface EditableCalendarEvent extends CalendarEvent { - - /** - * Set the visible text in the calendar for the event. - * - * @param caption - * The text to show in the calendar - */ - void setCaption(String caption); - - /** - * Set the description of the event. This is shown in the calendar when - * hoovering over the event. - * - * @param description - * The text which describes the event - */ - void setDescription(String description); - - /** - * Set the end date of the event. Must be after the start date. - * - * @param end - * The end date to set - */ - void setEnd(Date end); - - /** - * Set the start date for the event. Must be before the end date - * - * @param start - * The start date of the event - */ - void setStart(Date start); - - /** - * Set the style name for the event used for styling the event cells - * - * @param styleName - * The stylename to use - * - */ - void setStyleName(String styleName); - - /** - * Does the event span the whole day. If so then set this to true - * - * @param isAllDay - * True if the event spans the whole day. In this case the start - * and end times are ignored. - */ - void setAllDay(boolean isAllDay); - -} diff --git a/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicBackwardHandler.java b/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicBackwardHandler.java deleted file mode 100644 index 61f738fcd0..0000000000 --- a/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicBackwardHandler.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui.components.calendar.handler; - -import java.util.Calendar; -import java.util.Date; - -import com.vaadin.shared.ui.calendar.DateConstants; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.BackwardEvent; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.BackwardHandler; - -/** - * Implements basic functionality needed to enable backwards navigation. - * - * @since 7.1 - * @author Vaadin Ltd. - */ -@SuppressWarnings("serial") -public class BasicBackwardHandler implements BackwardHandler { - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.ui.CalendarComponentEvents.BackwardHandler# - * backward - * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.BackwardEvent) - */ - @Override - public void backward(BackwardEvent event) { - Date start = event.getComponent().getStartDate(); - Date end = event.getComponent().getEndDate(); - - // calculate amount to move back - int durationInDays = (int) (((end.getTime()) - start.getTime()) - / DateConstants.DAYINMILLIS); - durationInDays++; - // for week view durationInDays = -7, for day view durationInDays = -1 - durationInDays = -durationInDays; - - // set new start and end times - Calendar javaCalendar = event.getComponent().getInternalCalendar(); - javaCalendar.setTime(start); - javaCalendar.add(java.util.Calendar.DATE, durationInDays); - Date newStart = javaCalendar.getTime(); - - javaCalendar.setTime(end); - javaCalendar.add(java.util.Calendar.DATE, durationInDays); - Date newEnd = javaCalendar.getTime(); - - if (start.equals(end)) { // day view - int firstDay = event.getComponent().getFirstVisibleDayOfWeek(); - int lastDay = event.getComponent().getLastVisibleDayOfWeek(); - int dayOfWeek = javaCalendar.get(Calendar.DAY_OF_WEEK); - - // we suppose that 7 >= lastDay >= firstDay >= 1 - while (!(firstDay <= dayOfWeek && dayOfWeek <= lastDay)) { - javaCalendar.add(java.util.Calendar.DATE, -1); - dayOfWeek = javaCalendar.get(Calendar.DAY_OF_WEEK); - } - - newStart = javaCalendar.getTime(); - newEnd = javaCalendar.getTime(); - } - - setDates(event, newStart, newEnd); - } - - /** - * Set the start and end dates for the event - * - * @param event - * The event that the start and end dates should be set - * @param start - * The start date - * @param end - * The end date - */ - protected void setDates(BackwardEvent event, Date start, Date end) { - event.getComponent().setStartDate(start); - event.getComponent().setEndDate(end); - } -} diff --git a/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicDateClickHandler.java b/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicDateClickHandler.java deleted file mode 100644 index 0107e10e3d..0000000000 --- a/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicDateClickHandler.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui.components.calendar.handler; - -import java.util.Calendar; -import java.util.Date; - -import com.vaadin.ui.components.calendar.CalendarComponentEvents.DateClickEvent; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.DateClickHandler; - -/** - * Implements basic functionality needed to switch to day view when a single day - * is clicked. - * - * @since 7.1 - * @author Vaadin Ltd. - */ -@SuppressWarnings("serial") -public class BasicDateClickHandler implements DateClickHandler { - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.ui.CalendarComponentEvents.DateClickHandler - * #dateClick - * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.DateClickEvent) - */ - @Override - public void dateClick(DateClickEvent event) { - Date clickedDate = event.getDate(); - - Calendar javaCalendar = event.getComponent().getInternalCalendar(); - javaCalendar.setTime(clickedDate); - - // as times are expanded, this is all that is needed to show one day - Date start = javaCalendar.getTime(); - Date end = javaCalendar.getTime(); - - setDates(event, start, end); - } - - /** - * Set the start and end dates for the event - * - * @param event - * The event that the start and end dates should be set - * @param start - * The start date - * @param end - * The end date - */ - protected void setDates(DateClickEvent event, Date start, Date end) { - event.getComponent().setStartDate(start); - event.getComponent().setEndDate(end); - } -} diff --git a/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicEventMoveHandler.java b/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicEventMoveHandler.java deleted file mode 100644 index 60f0016312..0000000000 --- a/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicEventMoveHandler.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui.components.calendar.handler; - -import java.util.Date; - -import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventMoveHandler; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.MoveEvent; -import com.vaadin.ui.components.calendar.event.CalendarEvent; -import com.vaadin.ui.components.calendar.event.EditableCalendarEvent; - -/** - * Implements basic functionality needed to enable moving events. - * - * @since 7.1 - * @author Vaadin Ltd. - */ -@SuppressWarnings("serial") -public class BasicEventMoveHandler implements EventMoveHandler { - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventMoveHandler - * #eventMove - * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.MoveEvent) - */ - @Override - public void eventMove(MoveEvent event) { - CalendarEvent calendarEvent = event.getCalendarEvent(); - - if (calendarEvent instanceof EditableCalendarEvent) { - - EditableCalendarEvent editableEvent = (EditableCalendarEvent) calendarEvent; - - Date newFromTime = event.getNewStart(); - - // Update event dates - long length = editableEvent.getEnd().getTime() - - editableEvent.getStart().getTime(); - setDates(editableEvent, newFromTime, - new Date(newFromTime.getTime() + length)); - } - } - - /** - * Set the start and end dates for the event - * - * @param event - * The event that the start and end dates should be set - * @param start - * The start date - * @param end - * The end date - */ - protected void setDates(EditableCalendarEvent event, Date start, Date end) { - event.setStart(start); - event.setEnd(end); - } -} diff --git a/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicEventResizeHandler.java b/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicEventResizeHandler.java deleted file mode 100644 index 51e4bc1cbc..0000000000 --- a/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicEventResizeHandler.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui.components.calendar.handler; - -import java.util.Date; - -import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventResize; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventResizeHandler; -import com.vaadin.ui.components.calendar.event.CalendarEvent; -import com.vaadin.ui.components.calendar.event.EditableCalendarEvent; - -/** - * Implements basic functionality needed to enable event resizing. - * - * @since 7.1 - * @author Vaadin Ltd. - */ -@SuppressWarnings("serial") -public class BasicEventResizeHandler implements EventResizeHandler { - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventResizeHandler - * #eventResize - * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventResize) - */ - @Override - public void eventResize(EventResize event) { - CalendarEvent calendarEvent = event.getCalendarEvent(); - - if (calendarEvent instanceof EditableCalendarEvent) { - Date newStartTime = event.getNewStart(); - Date newEndTime = event.getNewEnd(); - - EditableCalendarEvent editableEvent = (EditableCalendarEvent) calendarEvent; - - setDates(editableEvent, newStartTime, newEndTime); - } - } - - /** - * Set the start and end dates for the event - * - * @param event - * The event that the start and end dates should be set - * @param start - * The start date - * @param end - * The end date - */ - protected void setDates(EditableCalendarEvent event, Date start, Date end) { - event.setStart(start); - event.setEnd(end); - } -} diff --git a/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicForwardHandler.java b/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicForwardHandler.java deleted file mode 100644 index 6cdc00bee2..0000000000 --- a/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicForwardHandler.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui.components.calendar.handler; - -import java.util.Calendar; -import java.util.Date; - -import com.vaadin.shared.ui.calendar.DateConstants; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.ForwardEvent; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.ForwardHandler; - -/** - * Implements basic functionality needed to enable forward navigation. - * - * @since 7.1 - * @author Vaadin Ltd. - */ -@SuppressWarnings("serial") -public class BasicForwardHandler implements ForwardHandler { - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.calendar.ui.CalendarComponentEvents.ForwardHandler# - * forward - * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.ForwardEvent) - */ - @Override - public void forward(ForwardEvent event) { - Date start = event.getComponent().getStartDate(); - Date end = event.getComponent().getEndDate(); - - // calculate amount to move forward - int durationInDays = (int) (((end.getTime()) - start.getTime()) - / DateConstants.DAYINMILLIS); - // for week view durationInDays = 7, for day view durationInDays = 1 - durationInDays++; - - // set new start and end times - Calendar javaCalendar = Calendar.getInstance(); - javaCalendar.setTime(start); - javaCalendar.add(java.util.Calendar.DATE, durationInDays); - Date newStart = javaCalendar.getTime(); - - javaCalendar.setTime(end); - javaCalendar.add(java.util.Calendar.DATE, durationInDays); - Date newEnd = javaCalendar.getTime(); - - if (start.equals(end)) { // day view - int firstDay = event.getComponent().getFirstVisibleDayOfWeek(); - int lastDay = event.getComponent().getLastVisibleDayOfWeek(); - int dayOfWeek = javaCalendar.get(Calendar.DAY_OF_WEEK); - - // we suppose that 7 >= lastDay >= firstDay >= 1 - while (!(firstDay <= dayOfWeek && dayOfWeek <= lastDay)) { - javaCalendar.add(java.util.Calendar.DATE, 1); - dayOfWeek = javaCalendar.get(Calendar.DAY_OF_WEEK); - } - - newStart = javaCalendar.getTime(); - newEnd = javaCalendar.getTime(); - } - - setDates(event, newStart, newEnd); - } - - /** - * Set the start and end dates for the event - * - * @param event - * The event that the start and end dates should be set - * @param start - * The start date - * @param end - * The end date - */ - protected void setDates(ForwardEvent event, Date start, Date end) { - event.getComponent().setStartDate(start); - event.getComponent().setEndDate(end); - } -} diff --git a/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicWeekClickHandler.java b/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicWeekClickHandler.java deleted file mode 100644 index 128c6abfbd..0000000000 --- a/server/src/main/java/com/vaadin/ui/components/calendar/handler/BasicWeekClickHandler.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui.components.calendar.handler; - -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; - -import com.vaadin.ui.components.calendar.CalendarComponentEvents.WeekClick; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.WeekClickHandler; - -/** - * Implements basic functionality needed to change to week view when a week - * number is clicked. - * - * @since 7.1 - * @author Vaadin Ltd. - */ -@SuppressWarnings("serial") -public class BasicWeekClickHandler implements WeekClickHandler { - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.calendar.ui.CalendarComponentEvents.WeekClickHandler - * #weekClick - * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.WeekClick) - */ - @Override - public void weekClick(WeekClick event) { - int week = event.getWeek(); - int year = event.getYear(); - - // set correct year and month - Calendar javaCalendar = event.getComponent().getInternalCalendar(); - javaCalendar.set(GregorianCalendar.YEAR, year); - javaCalendar.set(GregorianCalendar.WEEK_OF_YEAR, week); - - // starting at the beginning of the week - javaCalendar.set(GregorianCalendar.DAY_OF_WEEK, - javaCalendar.getFirstDayOfWeek()); - Date start = javaCalendar.getTime(); - - // ending at the end of the week - javaCalendar.add(GregorianCalendar.DATE, 6); - Date end = javaCalendar.getTime(); - - setDates(event, start, end); - - // times are automatically expanded, no need to worry about them - } - - /** - * Set the start and end dates for the event - * - * @param event - * The event that the start and end dates should be set - * @param start - * The start date - * @param end - * The end date - */ - protected void setDates(WeekClick event, Date start, Date end) { - event.getComponent().setStartDate(start); - event.getComponent().setEndDate(end); - } - -} diff --git a/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorChangeEvent.java b/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorChangeEvent.java deleted file mode 100644 index aa703deb19..0000000000 --- a/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorChangeEvent.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui.components.colorpicker; - -import com.vaadin.shared.ui.colorpicker.Color; -import com.vaadin.ui.Component; -import com.vaadin.ui.Component.Event; - -/** - * The color changed event which is passed to the listeners when a color change - * occurs. - * - * @since 7.0.0 - */ -public class ColorChangeEvent extends Event { - private final Color color; - - public ColorChangeEvent(Component source, Color color) { - super(source); - - this.color = color; - } - - /** - * Returns the new color. - */ - public Color getColor() { - return color; - } -} diff --git a/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorChangeListener.java b/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorChangeListener.java deleted file mode 100644 index b234dc3d5d..0000000000 --- a/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorChangeListener.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui.components.colorpicker; - -import java.io.Serializable; - -/** - * The listener interface for receiving colorChange events. The class that is - * interested in processing a {@link ColorChangeEvent} implements this - * interface, and the object created with that class is registered with a - * component using the component's <code>addColorChangeListener</code> method. - * When the colorChange event occurs, that object's appropriate method is - * invoked. - * - * @since 7.0.0 - * - * @see ColorChangeEvent - */ -public interface ColorChangeListener extends Serializable { - - /** - * Called when a new color has been selected. - * - * @param event - * An event containing information about the color change. - */ - void colorChanged(ColorChangeEvent event); - -} diff --git a/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerGradient.java b/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerGradient.java deleted file mode 100644 index 23748a967a..0000000000 --- a/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerGradient.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui.components.colorpicker; - -import java.lang.reflect.Method; - -import com.vaadin.shared.ui.colorpicker.Color; -import com.vaadin.shared.ui.colorpicker.ColorPickerGradientServerRpc; -import com.vaadin.shared.ui.colorpicker.ColorPickerGradientState; -import com.vaadin.ui.AbstractColorPicker.Coordinates2Color; -import com.vaadin.ui.AbstractComponent; - -/** - * A component that represents a color gradient within a color picker. - * - * @since 7.0.0 - */ -public class ColorPickerGradient extends AbstractComponent - implements ColorSelector { - - private static final Method COLOR_CHANGE_METHOD; - static { - try { - COLOR_CHANGE_METHOD = ColorChangeListener.class.getDeclaredMethod( - "colorChanged", new Class[] { ColorChangeEvent.class }); - } catch (final java.lang.NoSuchMethodException e) { - // This should never happen - throw new java.lang.RuntimeException( - "Internal error finding methods in ColorPicker"); - } - } - - private ColorPickerGradientServerRpc rpc = new ColorPickerGradientServerRpc() { - - @Override - public void select(int cursorX, int cursorY) { - x = cursorX; - y = cursorY; - color = converter.calculate(x, y); - - fireColorChanged(color); - } - }; - - /** The converter. */ - private Coordinates2Color converter; - - /** The foreground color. */ - private Color color; - - /** The x-coordinate. */ - private int x = 0; - - /** The y-coordinate. */ - private int y = 0; - - private ColorPickerGradient() { - registerRpc(rpc); - // width and height must be set here instead of in theme, otherwise - // coordinate calculations fail - getState().width = "220px"; - getState().height = "220px"; - } - - /** - * Instantiates a new color picker gradient. - * - * @param id - * the id - * @param converter - * the converter - */ - public ColorPickerGradient(String id, Coordinates2Color converter) { - this(); - addStyleName(id); - this.converter = converter; - } - - @Override - public void setColor(Color c) { - color = c; - - int[] coords = converter.calculate(c); - x = coords[0]; - y = coords[1]; - - getState().cursorX = x; - getState().cursorY = y; - - } - - @Override - public void addColorChangeListener(ColorChangeListener listener) { - addListener(ColorChangeEvent.class, listener, COLOR_CHANGE_METHOD); - } - - @Override - public void removeColorChangeListener(ColorChangeListener listener) { - removeListener(ColorChangeEvent.class, listener); - } - - /** - * Sets the background color. - * - * @param color - * the new background color - */ - public void setBackgroundColor(Color color) { - getState().bgColor = color.getCSS(); - } - - @Override - public Color getColor() { - return color; - } - - /** - * Notifies the listeners that the color has changed - * - * @param color - * The color which it changed to - */ - public void fireColorChanged(Color color) { - fireEvent(new ColorChangeEvent(this, color)); - } - - @Override - protected ColorPickerGradientState getState() { - return (ColorPickerGradientState) super.getState(); - } -} diff --git a/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerGrid.java b/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerGrid.java deleted file mode 100644 index 9e5580c719..0000000000 --- a/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerGrid.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui.components.colorpicker; - -import java.awt.Point; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Map; - -import com.vaadin.shared.ui.colorpicker.Color; -import com.vaadin.shared.ui.colorpicker.ColorPickerGridServerRpc; -import com.vaadin.shared.ui.colorpicker.ColorPickerGridState; -import com.vaadin.ui.AbstractComponent; - -/** - * A component that represents a color selection grid within a color picker. - * - * @since 7.0.0 - */ -public class ColorPickerGrid extends AbstractComponent - implements ColorSelector { - - private static final String STYLENAME = "v-colorpicker-grid"; - - private static final Method COLOR_CHANGE_METHOD; - static { - try { - COLOR_CHANGE_METHOD = ColorChangeListener.class.getDeclaredMethod( - "colorChanged", new Class[] { ColorChangeEvent.class }); - } catch (final java.lang.NoSuchMethodException e) { - // This should never happen - throw new java.lang.RuntimeException( - "Internal error finding methods in ColorPicker"); - } - } - - private ColorPickerGridServerRpc rpc = new ColorPickerGridServerRpc() { - - @Override - public void select(int x, int y) { - ColorPickerGrid.this.x = x; - ColorPickerGrid.this.y = y; - - fireColorChanged(colorGrid[y][x]); - } - - @Override - public void refresh() { - for (int row = 0; row < rows; row++) { - for (int col = 0; col < columns; col++) { - changedColors.put(new Point(row, col), colorGrid[row][col]); - } - } - sendChangedColors(); - markAsDirty(); - } - }; - - /** The x-coordinate. */ - private int x = 0; - - /** The y-coordinate. */ - private int y = 0; - - /** The rows. */ - private int rows; - - /** The columns. */ - private int columns; - - /** The color grid. */ - private Color[][] colorGrid = new Color[1][1]; - - /** The changed colors. */ - private final Map<Point, Color> changedColors = new HashMap<Point, Color>(); - - /** - * Instantiates a new color picker grid. - */ - public ColorPickerGrid() { - registerRpc(rpc); - setPrimaryStyleName(STYLENAME); - setColorGrid(new Color[1][1]); - setColor(Color.WHITE); - } - - /** - * Instantiates a new color picker grid. - * - * @param rows - * the rows - * @param columns - * the columns - */ - public ColorPickerGrid(int rows, int columns) { - registerRpc(rpc); - setPrimaryStyleName(STYLENAME); - setColorGrid(new Color[rows][columns]); - setColor(Color.WHITE); - } - - /** - * Instantiates a new color picker grid. - * - * @param colors - * the colors - */ - public ColorPickerGrid(Color[][] colors) { - registerRpc(rpc); - setPrimaryStyleName(STYLENAME); - setColorGrid(colors); - } - - private void setColumnCount(int columns) { - this.columns = columns; - getState().columnCount = columns; - } - - private void setRowCount(int rows) { - this.rows = rows; - getState().rowCount = rows; - } - - private void sendChangedColors() { - if (!changedColors.isEmpty()) { - String[] colors = new String[changedColors.size()]; - String[] XCoords = new String[changedColors.size()]; - String[] YCoords = new String[changedColors.size()]; - int counter = 0; - for (Point p : changedColors.keySet()) { - Color c = changedColors.get(p); - if (c == null) { - continue; - } - - String color = c.getCSS(); - - colors[counter] = color; - XCoords[counter] = String.valueOf((int) p.getX()); - YCoords[counter] = String.valueOf((int) p.getY()); - counter++; - } - getState().changedColor = colors; - getState().changedX = XCoords; - getState().changedY = YCoords; - - changedColors.clear(); - } - } - - /** - * Sets the color grid. - * - * @param colors - * the new color grid - */ - public void setColorGrid(Color[][] colors) { - setRowCount(colors.length); - setColumnCount(colors[0].length); - colorGrid = colors; - - for (int row = 0; row < rows; row++) { - for (int col = 0; col < columns; col++) { - changedColors.put(new Point(row, col), colorGrid[row][col]); - } - } - sendChangedColors(); - - markAsDirty(); - } - - /** - * Adds a color change listener - * - * @param listener - * The color change listener - */ - @Override - public void addColorChangeListener(ColorChangeListener listener) { - addListener(ColorChangeEvent.class, listener, COLOR_CHANGE_METHOD); - } - - @Override - public Color getColor() { - return colorGrid[x][y]; - } - - /** - * Removes a color change listener - * - * @param listener - * The listener - */ - @Override - public void removeColorChangeListener(ColorChangeListener listener) { - removeListener(ColorChangeEvent.class, listener); - } - - @Override - public void setColor(Color color) { - colorGrid[x][y] = color; - changedColors.put(new Point(x, y), color); - sendChangedColors(); - markAsDirty(); - } - - /** - * Sets the position. - * - * @param x - * the x - * @param y - * the y - */ - public void setPosition(int x, int y) { - if (x >= 0 && x < columns && y >= 0 && y < rows) { - this.x = x; - this.y = y; - } - } - - /** - * Gets the position. - * - * @return the position - */ - public int[] getPosition() { - return new int[] { x, y }; - } - - /** - * Notifies the listeners that a color change has occurred - * - * @param color - * The color which it changed to - */ - public void fireColorChanged(Color color) { - fireEvent(new ColorChangeEvent(this, color)); - } - - @Override - protected ColorPickerGridState getState() { - return (ColorPickerGridState) super.getState(); - } -} diff --git a/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerHistory.java b/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerHistory.java deleted file mode 100644 index 1173faf152..0000000000 --- a/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerHistory.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui.components.colorpicker; - -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.concurrent.ArrayBlockingQueue; - -import com.vaadin.shared.ui.colorpicker.Color; -import com.vaadin.ui.CustomComponent; - -/** - * A component that represents color selection history within a color picker. - * - * @since 7.0.0 - */ -public class ColorPickerHistory extends CustomComponent - implements ColorSelector, ColorChangeListener { - - private static final String STYLENAME = "v-colorpicker-history"; - - private static final Method COLOR_CHANGE_METHOD; - static { - try { - COLOR_CHANGE_METHOD = ColorChangeListener.class.getDeclaredMethod( - "colorChanged", new Class[] { ColorChangeEvent.class }); - } catch (final java.lang.NoSuchMethodException e) { - // This should never happen - throw new java.lang.RuntimeException( - "Internal error finding methods in ColorPicker"); - } - } - - /** The rows. */ - private static final int rows = 4; - - /** The columns. */ - private static final int columns = 15; - - /** Temporary color history for when the component is detached. */ - private ArrayBlockingQueue<Color> tempHistory = new ArrayBlockingQueue<Color>( - rows * columns); - - /** The grid. */ - private final ColorPickerGrid grid; - - /** - * Instantiates a new color picker history. - */ - public ColorPickerHistory() { - setPrimaryStyleName(STYLENAME); - - grid = new ColorPickerGrid(rows, columns); - grid.setWidth("100%"); - grid.setPosition(0, 0); - grid.addColorChangeListener(this); - - setCompositionRoot(grid); - } - - @Override - public void attach() { - super.attach(); - createColorHistoryIfNecessary(); - } - - private void createColorHistoryIfNecessary() { - List<Color> tempColors = new ArrayList<Color>(tempHistory); - if (getSession().getAttribute("colorPickerHistory") == null) { - getSession().setAttribute("colorPickerHistory", - new ArrayBlockingQueue<Color>(rows * columns)); - } - for (Color color : tempColors) { - setColor(color); - } - tempHistory.clear(); - } - - @SuppressWarnings("unchecked") - private ArrayBlockingQueue<Color> getColorHistory() { - if (isAttached()) { - Object colorHistory = getSession() - .getAttribute("colorPickerHistory"); - if (colorHistory instanceof ArrayBlockingQueue<?>) { - return (ArrayBlockingQueue<Color>) colorHistory; - } - } - return tempHistory; - } - - @Override - public void setHeight(String height) { - super.setHeight(height); - grid.setHeight(height); - } - - @Override - public void setColor(Color color) { - - ArrayBlockingQueue<Color> colorHistory = getColorHistory(); - - // Check that the color does not already exist - boolean exists = false; - Iterator<Color> iter = colorHistory.iterator(); - while (iter.hasNext()) { - if (color.equals(iter.next())) { - exists = true; - break; - } - } - - // If the color does not exist then add it - if (!exists) { - if (!colorHistory.offer(color)) { - colorHistory.poll(); - colorHistory.offer(color); - } - } - - List<Color> colorList = new ArrayList<Color>(colorHistory); - - // Invert order of colors - Collections.reverse(colorList); - - // Move the selected color to the front of the list - Collections.swap(colorList, colorList.indexOf(color), 0); - - // Create 2d color map - Color[][] colors = new Color[rows][columns]; - iter = colorList.iterator(); - - for (int row = 0; row < rows; row++) { - for (int col = 0; col < columns; col++) { - if (iter.hasNext()) { - colors[row][col] = iter.next(); - } else { - colors[row][col] = Color.WHITE; - } - } - } - - grid.setColorGrid(colors); - grid.markAsDirty(); - } - - @Override - public Color getColor() { - return getColorHistory().peek(); - } - - /** - * Gets the history. - * - * @return the history - */ - public List<Color> getHistory() { - ArrayBlockingQueue<Color> colorHistory = getColorHistory(); - Color[] array = colorHistory.toArray(new Color[colorHistory.size()]); - return Collections.unmodifiableList(Arrays.asList(array)); - } - - /** - * Checks if the history contains given color. - * - * @param c - * the color - * - * @return true, if successful - */ - public boolean hasColor(Color c) { - return getColorHistory().contains(c); - } - - /** - * Adds a color change listener - * - * @param listener - * The listener - */ - @Override - public void addColorChangeListener(ColorChangeListener listener) { - addListener(ColorChangeEvent.class, listener, COLOR_CHANGE_METHOD); - } - - /** - * Removes a color change listener - * - * @param listener - * The listener - */ - @Override - public void removeColorChangeListener(ColorChangeListener listener) { - removeListener(ColorChangeEvent.class, listener); - } - - @Override - public void colorChanged(ColorChangeEvent event) { - fireEvent(new ColorChangeEvent(this, event.getColor())); - } -} diff --git a/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerPopup.java b/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerPopup.java deleted file mode 100644 index dbf3b18bf3..0000000000 --- a/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerPopup.java +++ /dev/null @@ -1,759 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui.components.colorpicker; - -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.vaadin.shared.ui.MarginInfo; -import com.vaadin.shared.ui.colorpicker.Color; -import com.vaadin.ui.AbstractColorPicker.Coordinates2Color; -import com.vaadin.ui.Alignment; -import com.vaadin.ui.Button; -import com.vaadin.ui.Button.ClickEvent; -import com.vaadin.ui.Button.ClickListener; -import com.vaadin.ui.Component; -import com.vaadin.ui.HorizontalLayout; -import com.vaadin.ui.Layout; -import com.vaadin.ui.Slider; -import com.vaadin.ui.Slider.ValueOutOfBoundsException; -import com.vaadin.ui.TabSheet; -import com.vaadin.ui.VerticalLayout; -import com.vaadin.ui.Window; - -/** - * A component that represents color selection popup within a color picker. - * - * @since 7.0.0 - */ -public class ColorPickerPopup extends Window - implements ClickListener, ColorChangeListener, ColorSelector { - - private static final String STYLENAME = "v-colorpicker-popup"; - - private static final Method COLOR_CHANGE_METHOD; - static { - try { - COLOR_CHANGE_METHOD = ColorChangeListener.class.getDeclaredMethod( - "colorChanged", new Class[] { ColorChangeEvent.class }); - } catch (final java.lang.NoSuchMethodException e) { - // This should never happen - throw new java.lang.RuntimeException( - "Internal error finding methods in ColorPicker"); - } - } - - /** The tabs. */ - private final TabSheet tabs = new TabSheet(); - - private Component rgbTab; - - private Component hsvTab; - - private Component swatchesTab; - - /** The layout. */ - private final VerticalLayout layout; - - /** The ok button. */ - private final Button ok = new Button("OK"); - - /** The cancel button. */ - private final Button cancel = new Button("Cancel"); - - /** The resize button. */ - private final Button resize = new Button("show/hide history"); - - /** The selected color. */ - private Color selectedColor = Color.WHITE; - - /** The history. */ - private ColorPickerHistory history; - - /** The history container. */ - private Layout historyContainer; - - /** The rgb gradient. */ - private ColorPickerGradient rgbGradient; - - /** The hsv gradient. */ - private ColorPickerGradient hsvGradient; - - /** The red slider. */ - private Slider redSlider; - - /** The green slider. */ - private Slider greenSlider; - - /** The blue slider. */ - private Slider blueSlider; - - /** The hue slider. */ - private Slider hueSlider; - - /** The saturation slider. */ - private Slider saturationSlider; - - /** The value slider. */ - private Slider valueSlider; - - /** The preview on the rgb tab. */ - private ColorPickerPreview rgbPreview; - - /** The preview on the hsv tab. */ - private ColorPickerPreview hsvPreview; - - /** The preview on the swatches tab. */ - private ColorPickerPreview selPreview; - - /** The color select. */ - private ColorPickerSelect colorSelect; - - /** The selectors. */ - private final Set<ColorSelector> selectors = new HashSet<ColorSelector>(); - - /** - * Set true while the slider values are updated after colorChange. When - * true, valueChange reactions from the sliders are disabled, because - * otherwise the set color may become corrupted as it is repeatedly re-set - * in valueChangeListeners using values from sliders that may not have been - * updated yet. - */ - private boolean updatingColors = false; - - private ColorPickerPopup() { - // Set the layout - layout = new VerticalLayout(); - layout.setSpacing(false); - layout.setMargin(false); - layout.setWidth("100%"); - layout.setHeight(null); - - setContent(layout); - setStyleName(STYLENAME); - setResizable(false); - setImmediate(true); - // Create the history - history = new ColorPickerHistory(); - history.addColorChangeListener(this); - } - - /** - * Instantiates a new color picker popup. - */ - public ColorPickerPopup(Color initialColor) { - this(); - selectedColor = initialColor; - initContents(); - } - - private void initContents() { - // Create the preview on the rgb tab - rgbPreview = new ColorPickerPreview(selectedColor); - rgbPreview.setWidth("240px"); - rgbPreview.setHeight("20px"); - rgbPreview.addColorChangeListener(this); - selectors.add(rgbPreview); - - // Create the preview on the hsv tab - hsvPreview = new ColorPickerPreview(selectedColor); - hsvPreview.setWidth("240px"); - hsvPreview.setHeight("20px"); - hsvPreview.addColorChangeListener(this); - selectors.add(hsvPreview); - - // Create the preview on the swatches tab - selPreview = new ColorPickerPreview(selectedColor); - selPreview.setWidth("100%"); - selPreview.setHeight("20px"); - selPreview.addColorChangeListener(this); - selectors.add(selPreview); - - // Create the tabs - rgbTab = createRGBTab(selectedColor); - tabs.addTab(rgbTab, "RGB", null); - - hsvTab = createHSVTab(selectedColor); - tabs.addTab(hsvTab, "HSV", null); - - swatchesTab = createSelectTab(); - tabs.addTab(swatchesTab, "Swatches", null); - - // Add the tabs - tabs.setWidth("100%"); - - layout.addComponent(tabs); - - // Add the history - history.setWidth("97%"); - history.setHeight("22px"); - - // Create the default colors - List<Color> defaultColors = new ArrayList<Color>(); - defaultColors.add(Color.BLACK); - defaultColors.add(Color.WHITE); - - // Create the history - VerticalLayout innerContainer = new VerticalLayout(); - innerContainer.setWidth("100%"); - innerContainer.setHeight(null); - innerContainer.addComponent(history); - - VerticalLayout outerContainer = new VerticalLayout(); - outerContainer.setWidth("99%"); - outerContainer.setHeight("27px"); - outerContainer.addComponent(innerContainer); - historyContainer = outerContainer; - - layout.addComponent(historyContainer); - - // Add the resize button for the history - resize.addClickListener(this); - resize.setData(new Boolean(false)); - resize.setWidth("100%"); - resize.setHeight("10px"); - resize.setPrimaryStyleName("resize-button"); - layout.addComponent(resize); - - // Add the buttons - ok.setWidth("70px"); - ok.addClickListener(this); - - cancel.setWidth("70px"); - cancel.addClickListener(this); - - HorizontalLayout buttons = new HorizontalLayout(); - buttons.addComponent(ok); - buttons.addComponent(cancel); - buttons.setWidth("100%"); - buttons.setHeight("30px"); - buttons.setComponentAlignment(ok, Alignment.MIDDLE_CENTER); - buttons.setComponentAlignment(cancel, Alignment.MIDDLE_CENTER); - layout.addComponent(buttons); - } - - /** - * Creates the RGB tab. - * - * @return the component - */ - private Component createRGBTab(Color color) { - VerticalLayout rgbLayout = new VerticalLayout(); - rgbLayout.setMargin(new MarginInfo(false, false, true, false)); - rgbLayout.addComponent(rgbPreview); - rgbLayout.setStyleName("rgbtab"); - - // Add the RGB color gradient - rgbGradient = new ColorPickerGradient("rgb-gradient", RGBConverter); - rgbGradient.setColor(color); - rgbGradient.addColorChangeListener(this); - rgbLayout.addComponent(rgbGradient); - selectors.add(rgbGradient); - - // Add the RGB sliders - VerticalLayout sliders = new VerticalLayout(); - sliders.setStyleName("rgb-sliders"); - - redSlider = createRGBSlider("Red", "red"); - greenSlider = createRGBSlider("Green", "green"); - blueSlider = createRGBSlider("Blue", "blue"); - setRgbSliderValues(color); - - redSlider.addValueChangeListener(e -> { - double red = e.getValue(); - if (!updatingColors) { - Color newColor = new Color((int) red, selectedColor.getGreen(), - selectedColor.getBlue()); - setColor(newColor); - } - }); - - sliders.addComponent(redSlider); - - greenSlider.addValueChangeListener(e -> { - double green = e.getValue(); - if (!updatingColors) { - Color newColor = new Color(selectedColor.getRed(), (int) green, - selectedColor.getBlue()); - setColor(newColor); - } - }); - sliders.addComponent(greenSlider); - - blueSlider.addValueChangeListener(e -> { - double blue = e.getValue(); - if (!updatingColors) { - Color newColor = new Color(selectedColor.getRed(), - selectedColor.getGreen(), (int) blue); - setColor(newColor); - } - }); - sliders.addComponent(blueSlider); - - rgbLayout.addComponent(sliders); - - return rgbLayout; - } - - private Slider createRGBSlider(String caption, String styleName) { - Slider redSlider = new Slider(caption, 0, 255); - redSlider.setImmediate(true); - redSlider.setStyleName("rgb-slider"); - redSlider.setWidth("220px"); - redSlider.addStyleName(styleName); - return redSlider; - } - - /** - * Creates the hsv tab. - * - * @return the component - */ - private Component createHSVTab(Color color) { - VerticalLayout hsvLayout = new VerticalLayout(); - hsvLayout.setMargin(new MarginInfo(false, false, true, false)); - hsvLayout.addComponent(hsvPreview); - hsvLayout.setStyleName("hsvtab"); - - // Add the hsv gradient - hsvGradient = new ColorPickerGradient("hsv-gradient", HSVConverter); - hsvGradient.setColor(color); - hsvGradient.addColorChangeListener(this); - hsvLayout.addComponent(hsvGradient); - selectors.add(hsvGradient); - - VerticalLayout sliders = new VerticalLayout(); - sliders.setStyleName("hsv-sliders"); - - hueSlider = new Slider("Hue", 0, 360); - saturationSlider = new Slider("Saturation", 0, 100); - valueSlider = new Slider("Value", 0, 100); - - float[] hsv = color.getHSV(); - setHsvSliderValues(hsv); - - hueSlider.setStyleName("hsv-slider"); - hueSlider.addStyleName("hue-slider"); - hueSlider.setWidth("220px"); - hueSlider.setImmediate(true); - hueSlider.addValueChangeListener(event -> { - if (!updatingColors) { - float hue = (Float.parseFloat(event.getValue().toString())) - / 360f; - float saturation = (Float - .parseFloat(saturationSlider.getValue().toString())) - / 100f; - float value = (Float - .parseFloat(valueSlider.getValue().toString())) / 100f; - - // Set the color - Color newColor = new Color( - Color.HSVtoRGB(hue, saturation, value)); - setColor(newColor); - - /* - * Set the background color of the hue gradient. This has to be - * done here since in the conversion the base color information - * is lost when color is black/white - */ - Color bgColor = new Color(Color.HSVtoRGB(hue, 1f, 1f)); - hsvGradient.setBackgroundColor(bgColor); - } - }); - sliders.addComponent(hueSlider); - - saturationSlider.setStyleName("hsv-slider"); - saturationSlider.setWidth("220px"); - saturationSlider.setImmediate(true); - saturationSlider.addValueChangeListener(event -> { - if (!updatingColors) { - float hue = (Float.parseFloat(hueSlider.getValue().toString())) - / 360f; - float saturation = (Float - .parseFloat(event.getValue().toString())) / 100f; - float value = (Float - .parseFloat(valueSlider.getValue().toString())) / 100f; - Color newColor = new Color( - Color.HSVtoRGB(hue, saturation, value)); - setColor(newColor); - } - }); - sliders.addComponent(saturationSlider); - - valueSlider.setStyleName("hsv-slider"); - valueSlider.setWidth("220px"); - valueSlider.setImmediate(true); - valueSlider.addValueChangeListener(event -> { - if (!updatingColors) { - float hue = (Float.parseFloat(hueSlider.getValue().toString())) - / 360f; - float saturation = (Float - .parseFloat(saturationSlider.getValue().toString())) - / 100f; - float value = (Float.parseFloat(event.getValue().toString())) - / 100f; - - Color newColor = new Color( - Color.HSVtoRGB(hue, saturation, value)); - setColor(newColor); - } - }); - - sliders.addComponent(valueSlider); - hsvLayout.addComponent(sliders); - - return hsvLayout; - } - - /** - * Creates the select tab. - * - * @return the component - */ - private Component createSelectTab() { - VerticalLayout selLayout = new VerticalLayout(); - selLayout.setMargin(new MarginInfo(false, false, true, false)); - selLayout.addComponent(selPreview); - selLayout.addStyleName("seltab"); - - colorSelect = new ColorPickerSelect(); - colorSelect.addColorChangeListener(this); - selLayout.addComponent(colorSelect); - - return selLayout; - } - - @Override - public void buttonClick(ClickEvent event) { - // History resize was clicked - if (event.getButton() == resize) { - boolean state = (Boolean) resize.getData(); - - // minimize - if (state) { - historyContainer.setHeight("27px"); - history.setHeight("22px"); - - // maximize - } else { - historyContainer.setHeight("90px"); - history.setHeight("85px"); - } - - resize.setData(new Boolean(!state)); - } - - // Ok button was clicked - else if (event.getButton() == ok) { - history.setColor(getColor()); - fireColorChanged(); - close(); - } - - // Cancel button was clicked - else if (event.getButton() == cancel) { - close(); - } - - } - - /** - * Notifies the listeners that the color changed - */ - public void fireColorChanged() { - fireEvent(new ColorChangeEvent(this, getColor())); - } - - /** - * Gets the history. - * - * @return the history - */ - public ColorPickerHistory getHistory() { - return history; - } - - @Override - public void setColor(Color color) { - if (color == null) { - return; - } - - selectedColor = color; - - hsvGradient.setColor(selectedColor); - hsvPreview.setColor(selectedColor); - - rgbGradient.setColor(selectedColor); - rgbPreview.setColor(selectedColor); - - selPreview.setColor(selectedColor); - } - - @Override - public Color getColor() { - return selectedColor; - } - - /** - * Gets the color history. - * - * @return the color history - */ - public List<Color> getColorHistory() { - return Collections.unmodifiableList(history.getHistory()); - } - - @Override - public void colorChanged(ColorChangeEvent event) { - setColor(event.getColor()); - - updatingColors = true; - - setRgbSliderValues(selectedColor); - float[] hsv = selectedColor.getHSV(); - setHsvSliderValues(hsv); - - updatingColors = false; - - for (ColorSelector s : selectors) { - if (event.getSource() != s && s != this - && s.getColor() != selectedColor) { - s.setColor(selectedColor); - } - } - } - - private void setRgbSliderValues(Color color) { - try { - redSlider.setValue(((Integer) color.getRed()).doubleValue()); - blueSlider.setValue(((Integer) color.getBlue()).doubleValue()); - greenSlider.setValue(((Integer) color.getGreen()).doubleValue()); - } catch (ValueOutOfBoundsException e) { - getLogger().log(Level.WARNING, - "Unable to set RGB color value to " + color.getRed() + "," - + color.getGreen() + "," + color.getBlue(), - e); - } - } - - private void setHsvSliderValues(float[] hsv) { - try { - hueSlider.setValue(((Float) (hsv[0] * 360f)).doubleValue()); - saturationSlider.setValue(((Float) (hsv[1] * 100f)).doubleValue()); - valueSlider.setValue(((Float) (hsv[2] * 100f)).doubleValue()); - } catch (ValueOutOfBoundsException e) { - getLogger().log(Level.WARNING, "Unable to set HSV color value to " - + hsv[0] + "," + hsv[1] + "," + hsv[2], e); - } - } - - @Override - public void addColorChangeListener(ColorChangeListener listener) { - addListener(ColorChangeEvent.class, listener, COLOR_CHANGE_METHOD); - } - - @Override - public void removeColorChangeListener(ColorChangeListener listener) { - removeListener(ColorChangeEvent.class, listener); - } - - /** - * Checks the visibility of the given tab - * - * @param tab - * The tab to check - * @return true if tab is visible, false otherwise - */ - private boolean tabIsVisible(Component tab) { - Iterator<Component> tabIterator = tabs.getComponentIterator(); - while (tabIterator.hasNext()) { - if (tabIterator.next() == tab) { - return true; - } - } - return false; - } - - /** - * How many tabs are visible - * - * @return The number of tabs visible - */ - private int tabsNumVisible() { - Iterator<Component> tabIterator = tabs.getComponentIterator(); - int tabCounter = 0; - while (tabIterator.hasNext()) { - tabIterator.next(); - tabCounter++; - } - return tabCounter; - } - - /** - * Checks if tabs are needed and hides them if not - */ - private void checkIfTabsNeeded() { - tabs.hideTabs(tabsNumVisible() == 1); - } - - /** - * Set RGB tab visibility - * - * @param visible - * The visibility of the RGB tab - */ - public void setRGBTabVisible(boolean visible) { - if (visible && !tabIsVisible(rgbTab)) { - tabs.addTab(rgbTab, "RGB", null); - checkIfTabsNeeded(); - } else if (!visible && tabIsVisible(rgbTab)) { - tabs.removeComponent(rgbTab); - checkIfTabsNeeded(); - } - } - - /** - * Set HSV tab visibility - * - * @param visible - * The visibility of the HSV tab - */ - public void setHSVTabVisible(boolean visible) { - if (visible && !tabIsVisible(hsvTab)) { - tabs.addTab(hsvTab, "HSV", null); - checkIfTabsNeeded(); - } else if (!visible && tabIsVisible(hsvTab)) { - tabs.removeComponent(hsvTab); - checkIfTabsNeeded(); - } - } - - /** - * Set Swatches tab visibility - * - * @param visible - * The visibility of the Swatches tab - */ - public void setSwatchesTabVisible(boolean visible) { - if (visible && !tabIsVisible(swatchesTab)) { - tabs.addTab(swatchesTab, "Swatches", null); - checkIfTabsNeeded(); - } else if (!visible && tabIsVisible(swatchesTab)) { - tabs.removeComponent(swatchesTab); - checkIfTabsNeeded(); - } - } - - /** - * Set the History visibility - * - * @param visible - */ - public void setHistoryVisible(boolean visible) { - historyContainer.setVisible(visible); - resize.setVisible(visible); - } - - /** - * Set the preview visibility - * - * @param visible - */ - public void setPreviewVisible(boolean visible) { - hsvPreview.setVisible(visible); - rgbPreview.setVisible(visible); - selPreview.setVisible(visible); - } - - /** RGB color converter */ - private Coordinates2Color RGBConverter = new Coordinates2Color() { - - @Override - public Color calculate(int x, int y) { - float h = (x / 220f); - float s = 1f; - float v = 1f; - - if (y < 110) { - s = y / 110f; - } else if (y > 110) { - v = 1f - (y - 110f) / 110f; - } - - return new Color(Color.HSVtoRGB(h, s, v)); - } - - @Override - public int[] calculate(Color color) { - - float[] hsv = color.getHSV(); - - int x = Math.round(hsv[0] * 220f); - int y = 0; - - // lower half - if (hsv[1] == 1f) { - y = Math.round(110f - (hsv[1] + hsv[2]) * 110f); - } else { - y = Math.round(hsv[1] * 110f); - } - - return new int[] { x, y }; - } - }; - - /** HSV color converter */ - Coordinates2Color HSVConverter = new Coordinates2Color() { - @Override - public int[] calculate(Color color) { - - float[] hsv = color.getHSV(); - - // Calculate coordinates - int x = Math.round(hsv[2] * 220.0f); - int y = Math.round(220 - hsv[1] * 220.0f); - - // Create background color of clean color - Color bgColor = new Color(Color.HSVtoRGB(hsv[0], 1f, 1f)); - hsvGradient.setBackgroundColor(bgColor); - - return new int[] { x, y }; - } - - @Override - public Color calculate(int x, int y) { - float saturation = 1f - (y / 220.0f); - float value = (x / 220.0f); - float hue = Float.parseFloat(hueSlider.getValue().toString()) - / 360f; - - Color color = new Color(Color.HSVtoRGB(hue, saturation, value)); - return color; - } - }; - - private static Logger getLogger() { - return Logger.getLogger(ColorPickerPopup.class.getName()); - } -} diff --git a/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerPreview.java b/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerPreview.java deleted file mode 100644 index dc133ce156..0000000000 --- a/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerPreview.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui.components.colorpicker; - -import java.lang.reflect.Method; - -import com.vaadin.data.Property.ValueChangeEvent; -import com.vaadin.data.Property.ValueChangeListener; -import com.vaadin.shared.ui.colorpicker.Color; -import com.vaadin.ui.Component; -import com.vaadin.ui.CssLayout; -import com.vaadin.v7.ui.LegacyTextField; - -/** - * A component that represents color selection preview within a color picker. - * - * @since 7.0.0 - */ -public class ColorPickerPreview extends CssLayout - implements ColorSelector, ValueChangeListener { - - private static final String STYLE_DARK_COLOR = "v-textfield-dark"; - private static final String STYLE_LIGHT_COLOR = "v-textfield-light"; - - private static final Method COLOR_CHANGE_METHOD; - static { - try { - COLOR_CHANGE_METHOD = ColorChangeListener.class.getDeclaredMethod( - "colorChanged", new Class[] { ColorChangeEvent.class }); - } catch (final java.lang.NoSuchMethodException e) { - // This should never happen - throw new java.lang.RuntimeException( - "Internal error finding methods in ColorPicker"); - } - } - - /** The color. */ - private Color color; - - /** The field. */ - private final LegacyTextField field; - - /** The old value. */ - private String oldValue; - - private ColorPickerPreview() { - setStyleName("v-colorpicker-preview"); - setImmediate(true); - field = new LegacyTextField(); - field.setImmediate(true); - field.setSizeFull(); - field.setStyleName("v-colorpicker-preview-textfield"); - field.setData(this); - field.addValueChangeListener(this); - addComponent(field); - } - - /** - * Instantiates a new color picker preview. - */ - public ColorPickerPreview(Color color) { - this(); - setColor(color); - } - - @Override - public void setColor(Color color) { - this.color = color; - - // Unregister listener - field.removeValueChangeListener(this); - - String colorCSS = color.getCSS(); - field.setValue(colorCSS); - - if (field.isValid()) { - oldValue = colorCSS; - } else { - field.setValue(oldValue); - } - - // Re-register listener - field.addValueChangeListener(this); - - // Set the text color - field.removeStyleName(STYLE_DARK_COLOR); - field.removeStyleName(STYLE_LIGHT_COLOR); - if (this.color.getRed() + this.color.getGreen() - + this.color.getBlue() < 3 * 128) { - field.addStyleName(STYLE_DARK_COLOR); - } else { - field.addStyleName(STYLE_LIGHT_COLOR); - } - - markAsDirty(); - } - - @Override - public Color getColor() { - return color; - } - - @Override - public void addColorChangeListener(ColorChangeListener listener) { - addListener(ColorChangeEvent.class, listener, COLOR_CHANGE_METHOD); - } - - @Override - public void removeColorChangeListener(ColorChangeListener listener) { - removeListener(ColorChangeEvent.class, listener); - } - - @Override - public void valueChange(ValueChangeEvent event) { - String value = (String) event.getProperty().getValue(); - try { - if (value != null) { - /* - * Description of supported formats see - * http://www.w3schools.com/cssref/css_colors_legal.asp - */ - if (value.length() == 7 && value.startsWith("#")) { - // CSS color format (e.g. #000000) - int red = Integer.parseInt(value.substring(1, 3), 16); - int green = Integer.parseInt(value.substring(3, 5), 16); - int blue = Integer.parseInt(value.substring(5, 7), 16); - color = new Color(red, green, blue); - - } else if (value.startsWith("rgb")) { - // RGB color format rgb/rgba(255,255,255,0.1) - String[] colors = value.substring(value.indexOf("(") + 1, - value.length() - 1).split(","); - - int red = Integer.parseInt(colors[0]); - int green = Integer.parseInt(colors[1]); - int blue = Integer.parseInt(colors[2]); - if (colors.length > 3) { - int alpha = (int) (Double.parseDouble(colors[3]) - * 255d); - color = new Color(red, green, blue, alpha); - } else { - color = new Color(red, green, blue); - } - - } else if (value.startsWith("hsl")) { - // HSL color format hsl/hsla(100,50%,50%,1.0) - String[] colors = value.substring(value.indexOf("(") + 1, - value.length() - 1).split(","); - - int hue = Integer.parseInt(colors[0]); - int saturation = Integer - .parseInt(colors[1].replace("%", "")); - int lightness = Integer - .parseInt(colors[2].replace("%", "")); - int rgb = Color.HSLtoRGB(hue, saturation, lightness); - - if (colors.length > 3) { - int alpha = (int) (Double.parseDouble(colors[3]) - * 255d); - color = new Color(rgb); - color.setAlpha(alpha); - } else { - color = new Color(rgb); - } - } - - oldValue = value; - fireEvent(new ColorChangeEvent((Component) field.getData(), - color)); - } - - } catch (NumberFormatException nfe) { - // Revert value - field.setValue(oldValue); - } - } - - /** - * Called when the component is refreshing - */ - @Override - protected String getCss(Component c) { - return "background: " + color.getCSS(); - } -} diff --git a/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerSelect.java b/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerSelect.java deleted file mode 100644 index ae3dee4069..0000000000 --- a/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerSelect.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui.components.colorpicker; - -import com.vaadin.data.Property.ValueChangeEvent; -import com.vaadin.data.Property.ValueChangeListener; -import com.vaadin.shared.ui.colorpicker.Color; -import com.vaadin.ui.ComboBox; -import com.vaadin.ui.CustomComponent; -import com.vaadin.ui.VerticalLayout; - -/** - * A component that represents color selection swatches within a color picker. - * - * @since 7.0.0 - */ -public class ColorPickerSelect extends CustomComponent - implements ColorSelector, ValueChangeListener { - - /** The range. */ - private final ComboBox range; - - /** The grid. */ - private final ColorPickerGrid grid; - - /** - * The Enum ColorRangePropertyId. - */ - private enum ColorRangePropertyId { - ALL("All colors"), RED("Red colors"), GREEN("Green colors"), BLUE( - "Blue colors"); - - /** The caption. */ - private String caption; - - /** - * Instantiates a new color range property id. - * - * @param caption - * the caption - */ - ColorRangePropertyId(String caption) { - this.caption = caption; - } - - @Override - public String toString() { - return caption; - } - } - - /** - * Instantiates a new color picker select. - * - * @param rows - * the rows - * @param columns - * the columns - */ - public ColorPickerSelect() { - - VerticalLayout layout = new VerticalLayout(); - setCompositionRoot(layout); - - setStyleName("colorselect"); - setWidth("100%"); - - range = new ComboBox(); - range.setImmediate(true); - range.setImmediate(true); - range.setNullSelectionAllowed(false); - range.setNewItemsAllowed(false); - range.setWidth("100%"); - range.addValueChangeListener(this); - - for (ColorRangePropertyId id : ColorRangePropertyId.values()) { - range.addItem(id); - } - range.select(ColorRangePropertyId.ALL); - - layout.addComponent(range); - - grid = new ColorPickerGrid(createAllColors(14, 10)); - grid.setWidth("100%"); - - layout.addComponent(grid); - } - - /** - * Creates the all colors. - * - * @param rows - * the rows - * @param columns - * the columns - * - * @return the color[][] - */ - private Color[][] createAllColors(int rows, int columns) { - Color[][] colors = new Color[rows][columns]; - - for (int row = 0; row < rows; row++) { - for (int col = 0; col < columns; col++) { - - // Create the color grid by varying the saturation and value - if (row < (rows - 1)) { - // Calculate new hue value - float hue = ((float) col / (float) columns); - float saturation = 1f; - float value = 1f; - - // For the upper half use value=1 and variable - // saturation - if (row < (rows / 2)) { - saturation = ((row + 1f) / (rows / 2f)); - } else { - value = 1f - ((row - (rows / 2f)) / (rows / 2f)); - } - - colors[row][col] = new Color( - Color.HSVtoRGB(hue, saturation, value)); - } - - // The last row should have the black&white gradient - else { - float hue = 0f; - float saturation = 0f; - float value = 1f - ((float) col / (float) columns); - - colors[row][col] = new Color( - Color.HSVtoRGB(hue, saturation, value)); - } - } - } - - return colors; - } - - /** - * Creates the color. - * - * @param color - * the color - * @param rows - * the rows - * @param columns - * the columns - * - * @return the color[][] - */ - private Color[][] createColors(Color color, int rows, int columns) { - Color[][] colors = new Color[rows][columns]; - - float[] hsv = color.getHSV(); - - float hue = hsv[0]; - float saturation = 1f; - float value = 1f; - - for (int row = 0; row < rows; row++) { - for (int col = 0; col < columns; col++) { - - int index = row * columns + col; - saturation = 1f; - value = 1f; - - if (index <= ((rows * columns) / 2)) { - saturation = index - / (((float) rows * (float) columns) / 2f); - } else { - index -= ((rows * columns) / 2); - value = 1f - - index / (((float) rows * (float) columns) / 2f); - } - - colors[row][col] = new Color( - Color.HSVtoRGB(hue, saturation, value)); - } - } - - return colors; - } - - @Override - public Color getColor() { - return grid.getColor(); - } - - @Override - public void setColor(Color color) { - grid.getColor(); - } - - @Override - public void addColorChangeListener(ColorChangeListener listener) { - grid.addColorChangeListener(listener); - } - - @Override - public void removeColorChangeListener(ColorChangeListener listener) { - grid.removeColorChangeListener(listener); - } - - @Override - public void valueChange(ValueChangeEvent event) { - if (grid == null) { - return; - } - - if (event.getProperty().getValue() == ColorRangePropertyId.ALL) { - grid.setColorGrid(createAllColors(14, 10)); - } else if (event.getProperty().getValue() == ColorRangePropertyId.RED) { - grid.setColorGrid(createColors(new Color(0xFF, 0, 0), 14, 10)); - } else if (event.getProperty() - .getValue() == ColorRangePropertyId.GREEN) { - grid.setColorGrid(createColors(new Color(0, 0xFF, 0), 14, 10)); - } else if (event.getProperty() - .getValue() == ColorRangePropertyId.BLUE) { - grid.setColorGrid(createColors(new Color(0, 0, 0xFF), 14, 10)); - } - } -} diff --git a/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorSelector.java b/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorSelector.java deleted file mode 100644 index d9264745a8..0000000000 --- a/server/src/main/java/com/vaadin/ui/components/colorpicker/ColorSelector.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui.components.colorpicker; - -import java.io.Serializable; - -import com.vaadin.shared.ui.colorpicker.Color; - -/** - * An interface for a color selector. - * - * @since 7.0.0 - */ -public interface ColorSelector extends Serializable, HasColorChangeListener { - - /** - * Sets the color. - * - * @param color - * the new color - */ - public void setColor(Color color); - - /** - * Gets the color. - * - * @return the color - */ - public Color getColor(); -} diff --git a/server/src/main/java/com/vaadin/ui/components/colorpicker/HasColorChangeListener.java b/server/src/main/java/com/vaadin/ui/components/colorpicker/HasColorChangeListener.java deleted file mode 100644 index 7980111e2b..0000000000 --- a/server/src/main/java/com/vaadin/ui/components/colorpicker/HasColorChangeListener.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.ui.components.colorpicker; - -import java.io.Serializable; - -public interface HasColorChangeListener extends Serializable { - - /** - * Adds a {@link ColorChangeListener} to the component. - * - * @param listener - */ - void addColorChangeListener(ColorChangeListener listener); - - /** - * Removes a {@link ColorChangeListener} from the component. - * - * @param listener - */ - void removeColorChangeListener(ColorChangeListener listener); - -} diff --git a/server/src/main/java/com/vaadin/ui/declarative/DesignFormatter.java b/server/src/main/java/com/vaadin/ui/declarative/DesignFormatter.java index 272a52c276..4879609e01 100644 --- a/server/src/main/java/com/vaadin/ui/declarative/DesignFormatter.java +++ b/server/src/main/java/com/vaadin/ui/declarative/DesignFormatter.java @@ -32,7 +32,6 @@ import org.jsoup.parser.Parser; import com.vaadin.event.ShortcutAction; import com.vaadin.server.Resource; -import com.vaadin.ui.AbstractSelect; import com.vaadin.ui.declarative.converters.DesignDateConverter; import com.vaadin.ui.declarative.converters.DesignEnumConverter; import com.vaadin.ui.declarative.converters.DesignObjectConverter; @@ -379,7 +378,7 @@ public class DesignFormatter implements Serializable { * </p> * <p> * Typically, this method will be used by components to encode data (like - * option items in {@link AbstractSelect}) when dumping to HTML format + * option items in {@code AbstractSelect}) when dumping to HTML format * </p> * * @since 7.5.7 @@ -403,7 +402,7 @@ public class DesignFormatter implements Serializable { * * <p> * Typically this method will be used by components to read back data (like - * option items in {@link AbstractSelect}) from HTML. Note that this method + * option items in {@code AbstractSelect}) from HTML. Note that this method * unencodes more characters than {@link #encodeForTextNode(String)} encodes * </p> * diff --git a/server/src/test/java/com/vaadin/data/util/filter/AbstractFilterTestBase.java b/server/src/test/java/com/vaadin/data/util/filter/AbstractFilterTestBase.java deleted file mode 100644 index 979f472e20..0000000000 --- a/server/src/test/java/com/vaadin/data/util/filter/AbstractFilterTestBase.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.vaadin.data.util.filter; - -import junit.framework.TestCase; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.Item; -import com.vaadin.data.Property; -import com.vaadin.data.util.ObjectProperty; -import com.vaadin.data.util.PropertysetItem; - -public abstract class AbstractFilterTestBase<FILTERTYPE extends Filter> - extends TestCase { - - protected static final String PROPERTY1 = "property1"; - protected static final String PROPERTY2 = "property2"; - - protected static class TestItem<T1, T2> extends PropertysetItem { - - public TestItem(T1 value1, T2 value2) { - addItemProperty(PROPERTY1, new ObjectProperty<T1>(value1)); - addItemProperty(PROPERTY2, new ObjectProperty<T2>(value2)); - } - } - - protected static class NullProperty implements Property<String> { - - @Override - public String getValue() { - return null; - } - - @Override - public void setValue(String newValue) throws ReadOnlyException { - throw new ReadOnlyException(); - } - - @Override - public Class<String> getType() { - return String.class; - } - - @Override - public boolean isReadOnly() { - return true; - } - - @Override - public void setReadOnly(boolean newStatus) { - // do nothing - } - - } - - public static class SameItemFilter implements Filter { - - private final Item item; - private final Object propertyId; - - public SameItemFilter(Item item) { - this(item, ""); - } - - public SameItemFilter(Item item, Object propertyId) { - this.item = item; - this.propertyId = propertyId; - } - - @Override - public boolean passesFilter(Object itemId, Item item) - throws UnsupportedOperationException { - return this.item == item; - } - - @Override - public boolean appliesToProperty(Object propertyId) { - return this.propertyId != null ? this.propertyId.equals(propertyId) - : true; - } - - @Override - public boolean equals(Object obj) { - if (obj == null || !getClass().equals(obj.getClass())) { - return false; - } - SameItemFilter other = (SameItemFilter) obj; - return item == other.item - && (propertyId == null ? other.propertyId == null - : propertyId.equals(other.propertyId)); - } - - @Override - public int hashCode() { - return item.hashCode(); - } - } - -} diff --git a/server/src/test/java/com/vaadin/data/util/filter/AndOrFilterTest.java b/server/src/test/java/com/vaadin/data/util/filter/AndOrFilterTest.java deleted file mode 100644 index f825ef64c6..0000000000 --- a/server/src/test/java/com/vaadin/data/util/filter/AndOrFilterTest.java +++ /dev/null @@ -1,246 +0,0 @@ -package com.vaadin.data.util.filter; - -import org.junit.Assert; -import org.junit.Test; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.Item; -import com.vaadin.data.util.BeanItem; - -public class AndOrFilterTest - extends AbstractFilterTestBase<AbstractJunctionFilter> { - - protected Item item1 = new BeanItem<Integer>(1); - protected Item item2 = new BeanItem<Integer>(2); - - @Test - public void testNoFilterAnd() { - Filter filter = new And(); - - Assert.assertTrue(filter.passesFilter(null, item1)); - } - - @Test - public void testSingleFilterAnd() { - Filter filter = new And(new SameItemFilter(item1)); - - Assert.assertTrue(filter.passesFilter(null, item1)); - Assert.assertFalse(filter.passesFilter(null, item2)); - } - - @Test - public void testTwoFilterAnd() { - Filter filter1 = new And(new SameItemFilter(item1), - new SameItemFilter(item1)); - Filter filter2 = new And(new SameItemFilter(item1), - new SameItemFilter(item2)); - - Assert.assertTrue(filter1.passesFilter(null, item1)); - Assert.assertFalse(filter1.passesFilter(null, item2)); - - Assert.assertFalse(filter2.passesFilter(null, item1)); - Assert.assertFalse(filter2.passesFilter(null, item2)); - } - - @Test - public void testThreeFilterAnd() { - Filter filter1 = new And(new SameItemFilter(item1), - new SameItemFilter(item1), new SameItemFilter(item1)); - Filter filter2 = new And(new SameItemFilter(item1), - new SameItemFilter(item1), new SameItemFilter(item2)); - - Assert.assertTrue(filter1.passesFilter(null, item1)); - Assert.assertFalse(filter1.passesFilter(null, item2)); - - Assert.assertFalse(filter2.passesFilter(null, item1)); - Assert.assertFalse(filter2.passesFilter(null, item2)); - } - - @Test - public void testNoFilterOr() { - Filter filter = new Or(); - - Assert.assertFalse(filter.passesFilter(null, item1)); - } - - @Test - public void testSingleFilterOr() { - Filter filter = new Or(new SameItemFilter(item1)); - - Assert.assertTrue(filter.passesFilter(null, item1)); - Assert.assertFalse(filter.passesFilter(null, item2)); - } - - @Test - public void testTwoFilterOr() { - Filter filter1 = new Or(new SameItemFilter(item1), - new SameItemFilter(item1)); - Filter filter2 = new Or(new SameItemFilter(item1), - new SameItemFilter(item2)); - - Assert.assertTrue(filter1.passesFilter(null, item1)); - Assert.assertFalse(filter1.passesFilter(null, item2)); - - Assert.assertTrue(filter2.passesFilter(null, item1)); - Assert.assertTrue(filter2.passesFilter(null, item2)); - } - - @Test - public void testThreeFilterOr() { - Filter filter1 = new Or(new SameItemFilter(item1), - new SameItemFilter(item1), new SameItemFilter(item1)); - Filter filter2 = new Or(new SameItemFilter(item1), - new SameItemFilter(item1), new SameItemFilter(item2)); - - Assert.assertTrue(filter1.passesFilter(null, item1)); - Assert.assertFalse(filter1.passesFilter(null, item2)); - - Assert.assertTrue(filter2.passesFilter(null, item1)); - Assert.assertTrue(filter2.passesFilter(null, item2)); - } - - @Test - public void testAndEqualsHashCode() { - Filter filter0 = new And(); - Filter filter0b = new And(); - Filter filter1a = new And(new SameItemFilter(item1)); - Filter filter1a2 = new And(new SameItemFilter(item1)); - Filter filter1b = new And(new SameItemFilter(item2)); - Filter filter2a = new And(new SameItemFilter(item1), - new SameItemFilter(item1)); - Filter filter2b = new And(new SameItemFilter(item1), - new SameItemFilter(item2)); - Filter filter2b2 = new And(new SameItemFilter(item1), - new SameItemFilter(item2)); - Filter other0 = new Or(); - Filter other1 = new Or(new SameItemFilter(item1)); - - Assert.assertEquals(filter0, filter0); - Assert.assertEquals(filter0, filter0b); - Assert.assertFalse(filter0.equals(filter1a)); - Assert.assertFalse(filter0.equals(other0)); - Assert.assertFalse(filter0.equals(other1)); - - Assert.assertFalse(filter1a.equals(filter1b)); - Assert.assertFalse(filter1a.equals(other1)); - - Assert.assertFalse(filter1a.equals(filter2a)); - Assert.assertFalse(filter2a.equals(filter1a)); - - Assert.assertFalse(filter2a.equals(filter2b)); - Assert.assertEquals(filter2b, filter2b2); - - // hashCode() - Assert.assertEquals(filter0.hashCode(), filter0.hashCode()); - Assert.assertEquals(filter0.hashCode(), filter0b.hashCode()); - Assert.assertEquals(filter1a.hashCode(), filter1a.hashCode()); - Assert.assertEquals(filter1a.hashCode(), filter1a2.hashCode()); - Assert.assertEquals(filter2a.hashCode(), filter2a.hashCode()); - Assert.assertEquals(filter2b.hashCode(), filter2b2.hashCode()); - } - - @Test - public void testOrEqualsHashCode() { - Filter filter0 = new Or(); - Filter filter0b = new Or(); - Filter filter1a = new Or(new SameItemFilter(item1)); - Filter filter1a2 = new Or(new SameItemFilter(item1)); - Filter filter1b = new Or(new SameItemFilter(item2)); - Filter filter2a = new Or(new SameItemFilter(item1), - new SameItemFilter(item1)); - Filter filter2b = new Or(new SameItemFilter(item1), - new SameItemFilter(item2)); - Filter filter2b2 = new Or(new SameItemFilter(item1), - new SameItemFilter(item2)); - Filter other0 = new And(); - Filter other1 = new And(new SameItemFilter(item1)); - - Assert.assertEquals(filter0, filter0); - Assert.assertEquals(filter0, filter0b); - Assert.assertFalse(filter0.equals(filter1a)); - Assert.assertFalse(filter0.equals(other0)); - Assert.assertFalse(filter0.equals(other1)); - - Assert.assertFalse(filter1a.equals(filter1b)); - Assert.assertFalse(filter1a.equals(other1)); - - Assert.assertFalse(filter1a.equals(filter2a)); - Assert.assertFalse(filter2a.equals(filter1a)); - - Assert.assertFalse(filter2a.equals(filter2b)); - Assert.assertEquals(filter2b, filter2b2); - - // hashCode() - Assert.assertEquals(filter0.hashCode(), filter0.hashCode()); - Assert.assertEquals(filter0.hashCode(), filter0b.hashCode()); - Assert.assertEquals(filter1a.hashCode(), filter1a.hashCode()); - Assert.assertEquals(filter1a.hashCode(), filter1a2.hashCode()); - Assert.assertEquals(filter2a.hashCode(), filter2a.hashCode()); - Assert.assertEquals(filter2b.hashCode(), filter2b2.hashCode()); - } - - @Test - public void testAndAppliesToProperty() { - Filter filter0 = new And(); - Filter filter1a = new And(new SameItemFilter(item1, "a")); - Filter filter1b = new And(new SameItemFilter(item1, "b")); - Filter filter2aa = new And(new SameItemFilter(item1, "a"), - new SameItemFilter(item1, "a")); - Filter filter2ab = new And(new SameItemFilter(item1, "a"), - new SameItemFilter(item1, "b")); - Filter filter3abc = new And(new SameItemFilter(item1, "a"), - new SameItemFilter(item1, "b"), new SameItemFilter(item1, "c")); - - // empty And does not filter out anything - Assert.assertFalse(filter0.appliesToProperty("a")); - Assert.assertFalse(filter0.appliesToProperty("d")); - - Assert.assertTrue(filter1a.appliesToProperty("a")); - Assert.assertFalse(filter1a.appliesToProperty("b")); - Assert.assertFalse(filter1b.appliesToProperty("a")); - Assert.assertTrue(filter1b.appliesToProperty("b")); - - Assert.assertTrue(filter2aa.appliesToProperty("a")); - Assert.assertFalse(filter2aa.appliesToProperty("b")); - Assert.assertTrue(filter2ab.appliesToProperty("a")); - Assert.assertTrue(filter2ab.appliesToProperty("b")); - - Assert.assertTrue(filter3abc.appliesToProperty("a")); - Assert.assertTrue(filter3abc.appliesToProperty("b")); - Assert.assertTrue(filter3abc.appliesToProperty("c")); - Assert.assertFalse(filter3abc.appliesToProperty("d")); - } - - @Test - public void testOrAppliesToProperty() { - Filter filter0 = new Or(); - Filter filter1a = new Or(new SameItemFilter(item1, "a")); - Filter filter1b = new Or(new SameItemFilter(item1, "b")); - Filter filter2aa = new Or(new SameItemFilter(item1, "a"), - new SameItemFilter(item1, "a")); - Filter filter2ab = new Or(new SameItemFilter(item1, "a"), - new SameItemFilter(item1, "b")); - Filter filter3abc = new Or(new SameItemFilter(item1, "a"), - new SameItemFilter(item1, "b"), new SameItemFilter(item1, "c")); - - // empty Or filters out everything - Assert.assertTrue(filter0.appliesToProperty("a")); - Assert.assertTrue(filter0.appliesToProperty("d")); - - Assert.assertTrue(filter1a.appliesToProperty("a")); - Assert.assertFalse(filter1a.appliesToProperty("b")); - Assert.assertFalse(filter1b.appliesToProperty("a")); - Assert.assertTrue(filter1b.appliesToProperty("b")); - - Assert.assertTrue(filter2aa.appliesToProperty("a")); - Assert.assertFalse(filter2aa.appliesToProperty("b")); - Assert.assertTrue(filter2ab.appliesToProperty("a")); - Assert.assertTrue(filter2ab.appliesToProperty("b")); - - Assert.assertTrue(filter3abc.appliesToProperty("a")); - Assert.assertTrue(filter3abc.appliesToProperty("b")); - Assert.assertTrue(filter3abc.appliesToProperty("c")); - Assert.assertFalse(filter3abc.appliesToProperty("d")); - } - -} diff --git a/server/src/test/java/com/vaadin/data/util/filter/CompareFilterDateTest.java b/server/src/test/java/com/vaadin/data/util/filter/CompareFilterDateTest.java deleted file mode 100644 index 7c3dba9db3..0000000000 --- a/server/src/test/java/com/vaadin/data/util/filter/CompareFilterDateTest.java +++ /dev/null @@ -1,142 +0,0 @@ -package com.vaadin.data.util.filter; - -import java.text.SimpleDateFormat; -import java.util.Date; - -import org.junit.Assert; -import org.junit.Test; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.Item; -import com.vaadin.data.util.ObjectProperty; -import com.vaadin.data.util.PropertysetItem; -import com.vaadin.data.util.filter.Compare.Equal; -import com.vaadin.data.util.filter.Compare.Greater; -import com.vaadin.data.util.filter.Compare.GreaterOrEqual; -import com.vaadin.data.util.filter.Compare.Less; -import com.vaadin.data.util.filter.Compare.LessOrEqual; - -public class CompareFilterDateTest extends AbstractFilterTestBase<Compare> { - - protected Item itemNullUtilDate; - protected Item itemNullSqlDate; - protected Item itemUtilDate; - protected Item itemSqlDate; - - protected SimpleDateFormat formatter = new SimpleDateFormat("ddMMyyyy"); - - protected Filter equalCompUtilDate; - protected Filter greaterCompUtilDate; - protected Filter lessCompUtilDate; - protected Filter greaterEqualCompUtilDate; - protected Filter lessEqualCompUtilDate; - - protected Filter equalCompSqlDate; - protected Filter greaterCompSqlDate; - protected Filter lessCompSqlDate; - protected Filter greaterEqualCompSqlDate; - protected Filter lessEqualCompSqlDate; - - @Override - protected void setUp() throws Exception { - super.setUp(); - - equalCompUtilDate = new Equal(PROPERTY1, formatter.parse("26072016")); - greaterCompUtilDate = new Greater(PROPERTY1, - formatter.parse("26072016")); - lessCompUtilDate = new Less(PROPERTY1, formatter.parse("26072016")); - greaterEqualCompUtilDate = new GreaterOrEqual(PROPERTY1, - formatter.parse("26072016")); - lessEqualCompUtilDate = new LessOrEqual(PROPERTY1, - formatter.parse("26072016")); - - equalCompSqlDate = new Equal(PROPERTY1, - new java.sql.Date(formatter.parse("26072016").getTime())); - greaterCompSqlDate = new Greater(PROPERTY1, - new java.sql.Date(formatter.parse("26072016").getTime())); - lessCompSqlDate = new Less(PROPERTY1, - new java.sql.Date(formatter.parse("26072016").getTime())); - greaterEqualCompSqlDate = new GreaterOrEqual(PROPERTY1, - new java.sql.Date(formatter.parse("26072016").getTime())); - lessEqualCompSqlDate = new LessOrEqual(PROPERTY1, - new java.sql.Date(formatter.parse("26072016").getTime())); - - itemNullUtilDate = new PropertysetItem(); - itemNullUtilDate.addItemProperty(PROPERTY1, - new ObjectProperty<Date>(null, Date.class)); - itemNullSqlDate = new PropertysetItem(); - itemNullSqlDate.addItemProperty(PROPERTY1, - new ObjectProperty<java.sql.Date>(null, java.sql.Date.class)); - itemUtilDate = new PropertysetItem(); - itemUtilDate.addItemProperty(PROPERTY1, new ObjectProperty<Date>( - formatter.parse("25072016"), Date.class)); - itemSqlDate = new PropertysetItem(); - itemSqlDate.addItemProperty(PROPERTY1, - new ObjectProperty<java.sql.Date>( - new java.sql.Date( - formatter.parse("25072016").getTime()), - java.sql.Date.class)); - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - itemNullUtilDate = null; - itemNullSqlDate = null; - itemUtilDate = null; - itemSqlDate = null; - } - - @Test - public void testCompareUtilDatesAndUtilDates() { - Assert.assertFalse( - equalCompUtilDate.passesFilter(null, itemNullUtilDate)); - Assert.assertFalse(equalCompUtilDate.passesFilter(null, itemUtilDate)); - Assert.assertFalse( - greaterCompUtilDate.passesFilter(null, itemUtilDate)); - Assert.assertTrue(lessCompUtilDate.passesFilter(null, itemUtilDate)); - Assert.assertFalse( - greaterEqualCompUtilDate.passesFilter(null, itemUtilDate)); - Assert.assertTrue( - lessEqualCompUtilDate.passesFilter(null, itemUtilDate)); - } - - @Test - public void testCompareUtilDatesAndSqlDates() { - Assert.assertFalse( - equalCompUtilDate.passesFilter(null, itemNullSqlDate)); - Assert.assertFalse(equalCompUtilDate.passesFilter(null, itemSqlDate)); - Assert.assertFalse(greaterCompUtilDate.passesFilter(null, itemSqlDate)); - Assert.assertTrue(lessCompUtilDate.passesFilter(null, itemSqlDate)); - Assert.assertFalse( - greaterEqualCompUtilDate.passesFilter(null, itemSqlDate)); - Assert.assertTrue( - lessEqualCompUtilDate.passesFilter(null, itemSqlDate)); - } - - @Test - public void testCompareSqlDatesAndSqlDates() { - Assert.assertFalse( - equalCompSqlDate.passesFilter(null, itemNullSqlDate)); - Assert.assertFalse(equalCompSqlDate.passesFilter(null, itemSqlDate)); - Assert.assertFalse(greaterCompSqlDate.passesFilter(null, itemSqlDate)); - Assert.assertTrue(lessCompSqlDate.passesFilter(null, itemSqlDate)); - Assert.assertFalse( - greaterEqualCompSqlDate.passesFilter(null, itemSqlDate)); - Assert.assertTrue(lessEqualCompSqlDate.passesFilter(null, itemSqlDate)); - } - - @Test - public void testCompareSqlDatesAndUtilDates() { - Assert.assertFalse( - equalCompSqlDate.passesFilter(null, itemNullUtilDate)); - Assert.assertFalse(equalCompSqlDate.passesFilter(null, itemUtilDate)); - Assert.assertFalse(greaterCompSqlDate.passesFilter(null, itemUtilDate)); - Assert.assertTrue(lessCompSqlDate.passesFilter(null, itemUtilDate)); - Assert.assertFalse( - greaterEqualCompSqlDate.passesFilter(null, itemUtilDate)); - Assert.assertTrue( - lessEqualCompSqlDate.passesFilter(null, itemUtilDate)); - } - -} diff --git a/server/src/test/java/com/vaadin/data/util/filter/CompareFilterTest.java b/server/src/test/java/com/vaadin/data/util/filter/CompareFilterTest.java deleted file mode 100644 index 4bdad3c54d..0000000000 --- a/server/src/test/java/com/vaadin/data/util/filter/CompareFilterTest.java +++ /dev/null @@ -1,322 +0,0 @@ -package com.vaadin.data.util.filter; - -import java.math.BigDecimal; -import java.util.Date; - -import org.junit.Assert; -import org.junit.Test; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.Item; -import com.vaadin.data.util.ObjectProperty; -import com.vaadin.data.util.PropertysetItem; -import com.vaadin.data.util.filter.Compare.Equal; -import com.vaadin.data.util.filter.Compare.Greater; -import com.vaadin.data.util.filter.Compare.GreaterOrEqual; -import com.vaadin.data.util.filter.Compare.Less; -import com.vaadin.data.util.filter.Compare.LessOrEqual; - -public class CompareFilterTest extends AbstractFilterTestBase<Compare> { - - protected Item itemNull; - protected Item itemEmpty; - protected Item itemA; - protected Item itemB; - protected Item itemC; - - protected final Filter equalB = new Equal(PROPERTY1, "b"); - protected final Filter greaterB = new Greater(PROPERTY1, "b"); - protected final Filter lessB = new Less(PROPERTY1, "b"); - protected final Filter greaterEqualB = new GreaterOrEqual(PROPERTY1, "b"); - protected final Filter lessEqualB = new LessOrEqual(PROPERTY1, "b"); - - protected final Filter equalNull = new Equal(PROPERTY1, null); - protected final Filter greaterNull = new Greater(PROPERTY1, null); - protected final Filter lessNull = new Less(PROPERTY1, null); - protected final Filter greaterEqualNull = new GreaterOrEqual(PROPERTY1, - null); - protected final Filter lessEqualNull = new LessOrEqual(PROPERTY1, null); - - @Override - protected void setUp() throws Exception { - super.setUp(); - itemNull = new PropertysetItem(); - itemNull.addItemProperty(PROPERTY1, - new ObjectProperty<String>(null, String.class)); - itemEmpty = new PropertysetItem(); - itemEmpty.addItemProperty(PROPERTY1, - new ObjectProperty<String>("", String.class)); - itemA = new PropertysetItem(); - itemA.addItemProperty(PROPERTY1, - new ObjectProperty<String>("a", String.class)); - itemB = new PropertysetItem(); - itemB.addItemProperty(PROPERTY1, - new ObjectProperty<String>("b", String.class)); - itemC = new PropertysetItem(); - itemC.addItemProperty(PROPERTY1, - new ObjectProperty<String>("c", String.class)); - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - itemNull = null; - itemEmpty = null; - itemA = null; - itemB = null; - } - - @Test - public void testCompareString() { - Assert.assertFalse(equalB.passesFilter(null, itemEmpty)); - Assert.assertFalse(equalB.passesFilter(null, itemA)); - Assert.assertTrue(equalB.passesFilter(null, itemB)); - Assert.assertFalse(equalB.passesFilter(null, itemC)); - - Assert.assertFalse(greaterB.passesFilter(null, itemEmpty)); - Assert.assertFalse(greaterB.passesFilter(null, itemA)); - Assert.assertFalse(greaterB.passesFilter(null, itemB)); - Assert.assertTrue(greaterB.passesFilter(null, itemC)); - - Assert.assertTrue(lessB.passesFilter(null, itemEmpty)); - Assert.assertTrue(lessB.passesFilter(null, itemA)); - Assert.assertFalse(lessB.passesFilter(null, itemB)); - Assert.assertFalse(lessB.passesFilter(null, itemC)); - - Assert.assertFalse(greaterEqualB.passesFilter(null, itemEmpty)); - Assert.assertFalse(greaterEqualB.passesFilter(null, itemA)); - Assert.assertTrue(greaterEqualB.passesFilter(null, itemB)); - Assert.assertTrue(greaterEqualB.passesFilter(null, itemC)); - - Assert.assertTrue(lessEqualB.passesFilter(null, itemEmpty)); - Assert.assertTrue(lessEqualB.passesFilter(null, itemA)); - Assert.assertTrue(lessEqualB.passesFilter(null, itemB)); - Assert.assertFalse(lessEqualB.passesFilter(null, itemC)); - } - - @Test - public void testCompareWithNull() { - // null comparisons: null is less than any other value - Assert.assertFalse(equalB.passesFilter(null, itemNull)); - Assert.assertTrue(greaterB.passesFilter(null, itemNull)); - Assert.assertFalse(lessB.passesFilter(null, itemNull)); - Assert.assertTrue(greaterEqualB.passesFilter(null, itemNull)); - Assert.assertFalse(lessEqualB.passesFilter(null, itemNull)); - - Assert.assertTrue(equalNull.passesFilter(null, itemNull)); - Assert.assertFalse(greaterNull.passesFilter(null, itemNull)); - Assert.assertFalse(lessNull.passesFilter(null, itemNull)); - Assert.assertTrue(greaterEqualNull.passesFilter(null, itemNull)); - Assert.assertTrue(lessEqualNull.passesFilter(null, itemNull)); - - Assert.assertFalse(equalNull.passesFilter(null, itemA)); - Assert.assertFalse(greaterNull.passesFilter(null, itemA)); - Assert.assertTrue(lessNull.passesFilter(null, itemA)); - Assert.assertFalse(greaterEqualNull.passesFilter(null, itemA)); - Assert.assertTrue(lessEqualNull.passesFilter(null, itemA)); - } - - @Test - public void testCompareInteger() { - int negative = -1; - int zero = 0; - int positive = 1; - - Item itemNegative = new PropertysetItem(); - itemNegative.addItemProperty(PROPERTY1, - new ObjectProperty<Integer>(negative, Integer.class)); - Item itemZero = new PropertysetItem(); - itemZero.addItemProperty(PROPERTY1, - new ObjectProperty<Integer>(zero, Integer.class)); - Item itemPositive = new PropertysetItem(); - itemPositive.addItemProperty(PROPERTY1, - new ObjectProperty<Integer>(positive, Integer.class)); - - Filter equalZero = new Equal(PROPERTY1, zero); - Assert.assertFalse(equalZero.passesFilter(null, itemNegative)); - Assert.assertTrue(equalZero.passesFilter(null, itemZero)); - Assert.assertFalse(equalZero.passesFilter(null, itemPositive)); - - Filter isPositive = new Greater(PROPERTY1, zero); - Assert.assertFalse(isPositive.passesFilter(null, itemNegative)); - Assert.assertFalse(isPositive.passesFilter(null, itemZero)); - Assert.assertTrue(isPositive.passesFilter(null, itemPositive)); - - Filter isNegative = new Less(PROPERTY1, zero); - Assert.assertTrue(isNegative.passesFilter(null, itemNegative)); - Assert.assertFalse(isNegative.passesFilter(null, itemZero)); - Assert.assertFalse(isNegative.passesFilter(null, itemPositive)); - - Filter isNonNegative = new GreaterOrEqual(PROPERTY1, zero); - Assert.assertFalse(isNonNegative.passesFilter(null, itemNegative)); - Assert.assertTrue(isNonNegative.passesFilter(null, itemZero)); - Assert.assertTrue(isNonNegative.passesFilter(null, itemPositive)); - - Filter isNonPositive = new LessOrEqual(PROPERTY1, zero); - Assert.assertTrue(isNonPositive.passesFilter(null, itemNegative)); - Assert.assertTrue(isNonPositive.passesFilter(null, itemZero)); - Assert.assertFalse(isNonPositive.passesFilter(null, itemPositive)); - } - - @Test - public void testCompareBigDecimal() { - BigDecimal negative = new BigDecimal(-1); - BigDecimal zero = new BigDecimal(0); - BigDecimal positive = new BigDecimal(1); - positive.setScale(1); - BigDecimal positiveScaleTwo = new BigDecimal(1).setScale(2); - - Item itemNegative = new PropertysetItem(); - itemNegative.addItemProperty(PROPERTY1, - new ObjectProperty<BigDecimal>(negative, BigDecimal.class)); - Item itemZero = new PropertysetItem(); - itemZero.addItemProperty(PROPERTY1, - new ObjectProperty<BigDecimal>(zero, BigDecimal.class)); - Item itemPositive = new PropertysetItem(); - itemPositive.addItemProperty(PROPERTY1, - new ObjectProperty<BigDecimal>(positive, BigDecimal.class)); - Item itemPositiveScaleTwo = new PropertysetItem(); - itemPositiveScaleTwo.addItemProperty(PROPERTY1, - new ObjectProperty<BigDecimal>(positiveScaleTwo, - BigDecimal.class)); - - Filter equalZero = new Equal(PROPERTY1, zero); - Assert.assertFalse(equalZero.passesFilter(null, itemNegative)); - Assert.assertTrue(equalZero.passesFilter(null, itemZero)); - Assert.assertFalse(equalZero.passesFilter(null, itemPositive)); - - Filter isPositive = new Greater(PROPERTY1, zero); - Assert.assertFalse(isPositive.passesFilter(null, itemNegative)); - Assert.assertFalse(isPositive.passesFilter(null, itemZero)); - Assert.assertTrue(isPositive.passesFilter(null, itemPositive)); - - Filter isNegative = new Less(PROPERTY1, zero); - Assert.assertTrue(isNegative.passesFilter(null, itemNegative)); - Assert.assertFalse(isNegative.passesFilter(null, itemZero)); - Assert.assertFalse(isNegative.passesFilter(null, itemPositive)); - - Filter isNonNegative = new GreaterOrEqual(PROPERTY1, zero); - Assert.assertFalse(isNonNegative.passesFilter(null, itemNegative)); - Assert.assertTrue(isNonNegative.passesFilter(null, itemZero)); - Assert.assertTrue(isNonNegative.passesFilter(null, itemPositive)); - - Filter isNonPositive = new LessOrEqual(PROPERTY1, zero); - Assert.assertTrue(isNonPositive.passesFilter(null, itemNegative)); - Assert.assertTrue(isNonPositive.passesFilter(null, itemZero)); - Assert.assertFalse(isNonPositive.passesFilter(null, itemPositive)); - - Filter isPositiveScaleTwo = new Equal(PROPERTY1, positiveScaleTwo); - Assert.assertTrue( - isPositiveScaleTwo.passesFilter(null, itemPositiveScaleTwo)); - Assert.assertTrue(isPositiveScaleTwo.passesFilter(null, itemPositive)); - - } - - @Test - public void testCompareDate() { - Date now = new Date(); - // new Date() is only accurate to the millisecond, so repeating it gives - // the same date - Date earlier = new Date(now.getTime() - 1); - Date later = new Date(now.getTime() + 1); - - Item itemEarlier = new PropertysetItem(); - itemEarlier.addItemProperty(PROPERTY1, - new ObjectProperty<Date>(earlier, Date.class)); - Item itemNow = new PropertysetItem(); - itemNow.addItemProperty(PROPERTY1, - new ObjectProperty<Date>(now, Date.class)); - Item itemLater = new PropertysetItem(); - itemLater.addItemProperty(PROPERTY1, - new ObjectProperty<Date>(later, Date.class)); - - Filter equalNow = new Equal(PROPERTY1, now); - Assert.assertFalse(equalNow.passesFilter(null, itemEarlier)); - Assert.assertTrue(equalNow.passesFilter(null, itemNow)); - Assert.assertFalse(equalNow.passesFilter(null, itemLater)); - - Filter after = new Greater(PROPERTY1, now); - Assert.assertFalse(after.passesFilter(null, itemEarlier)); - Assert.assertFalse(after.passesFilter(null, itemNow)); - Assert.assertTrue(after.passesFilter(null, itemLater)); - - Filter before = new Less(PROPERTY1, now); - Assert.assertTrue(before.passesFilter(null, itemEarlier)); - Assert.assertFalse(before.passesFilter(null, itemNow)); - Assert.assertFalse(before.passesFilter(null, itemLater)); - - Filter afterOrNow = new GreaterOrEqual(PROPERTY1, now); - Assert.assertFalse(afterOrNow.passesFilter(null, itemEarlier)); - Assert.assertTrue(afterOrNow.passesFilter(null, itemNow)); - Assert.assertTrue(afterOrNow.passesFilter(null, itemLater)); - - Filter beforeOrNow = new LessOrEqual(PROPERTY1, now); - Assert.assertTrue(beforeOrNow.passesFilter(null, itemEarlier)); - Assert.assertTrue(beforeOrNow.passesFilter(null, itemNow)); - Assert.assertFalse(beforeOrNow.passesFilter(null, itemLater)); - } - - @Test - public void testCompareAppliesToProperty() { - Filter filterA = new Equal("a", 1); - Filter filterB = new Equal("b", 1); - - Assert.assertTrue(filterA.appliesToProperty("a")); - Assert.assertFalse(filterA.appliesToProperty("b")); - Assert.assertFalse(filterB.appliesToProperty("a")); - Assert.assertTrue(filterB.appliesToProperty("b")); - } - - @Test - public void testCompareEqualsHashCode() { - // most checks with Equal filter, then only some with others - Filter equalNull2 = new Equal(PROPERTY1, null); - Filter equalNullProperty2 = new Equal(PROPERTY2, null); - Filter equalEmpty = new Equal(PROPERTY1, ""); - Filter equalEmpty2 = new Equal(PROPERTY1, ""); - Filter equalEmptyProperty2 = new Equal(PROPERTY2, ""); - Filter equalA = new Equal(PROPERTY1, "a"); - Filter equalB2 = new Equal(PROPERTY1, "b"); - Filter equalBProperty2 = new Equal(PROPERTY2, "b"); - - Filter greaterEmpty = new Greater(PROPERTY1, ""); - - // equals() - Assert.assertEquals(equalNull, equalNull); - Assert.assertEquals(equalNull, equalNull2); - Assert.assertFalse(equalNull.equals(equalNullProperty2)); - Assert.assertFalse(equalNull.equals(equalEmpty)); - Assert.assertFalse(equalNull.equals(equalB)); - - Assert.assertEquals(equalEmpty, equalEmpty); - Assert.assertFalse(equalEmpty.equals(equalNull)); - Assert.assertEquals(equalEmpty, equalEmpty2); - Assert.assertFalse(equalEmpty.equals(equalEmptyProperty2)); - Assert.assertFalse(equalEmpty.equals(equalB)); - - Assert.assertEquals(equalB, equalB); - Assert.assertFalse(equalB.equals(equalNull)); - Assert.assertFalse(equalB.equals(equalEmpty)); - Assert.assertEquals(equalB, equalB2); - Assert.assertFalse(equalB.equals(equalBProperty2)); - Assert.assertFalse(equalB.equals(equalA)); - - Assert.assertEquals(greaterB, greaterB); - Assert.assertFalse(greaterB.equals(lessB)); - Assert.assertFalse(greaterB.equals(greaterEqualB)); - Assert.assertFalse(greaterB.equals(lessEqualB)); - - Assert.assertFalse(greaterNull.equals(greaterEmpty)); - Assert.assertFalse(greaterNull.equals(greaterB)); - Assert.assertFalse(greaterEmpty.equals(greaterNull)); - Assert.assertFalse(greaterEmpty.equals(greaterB)); - Assert.assertFalse(greaterB.equals(greaterNull)); - Assert.assertFalse(greaterB.equals(greaterEmpty)); - - // hashCode() - Assert.assertEquals(equalNull.hashCode(), equalNull2.hashCode()); - Assert.assertEquals(equalEmpty.hashCode(), equalEmpty2.hashCode()); - Assert.assertEquals(equalB.hashCode(), equalB2.hashCode()); - } - -} diff --git a/server/src/test/java/com/vaadin/data/util/filter/IsNullFilterTest.java b/server/src/test/java/com/vaadin/data/util/filter/IsNullFilterTest.java deleted file mode 100644 index 18013cd41c..0000000000 --- a/server/src/test/java/com/vaadin/data/util/filter/IsNullFilterTest.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.vaadin.data.util.filter; - -import org.junit.Assert; -import org.junit.Test; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.Item; -import com.vaadin.data.util.ObjectProperty; -import com.vaadin.data.util.PropertysetItem; - -public class IsNullFilterTest extends AbstractFilterTestBase<IsNull> { - - @Test - public void testIsNull() { - Item item1 = new PropertysetItem(); - item1.addItemProperty("a", - new ObjectProperty<String>(null, String.class)); - item1.addItemProperty("b", - new ObjectProperty<String>("b", String.class)); - Item item2 = new PropertysetItem(); - item2.addItemProperty("a", - new ObjectProperty<String>("a", String.class)); - item2.addItemProperty("b", - new ObjectProperty<String>(null, String.class)); - - Filter filter1 = new IsNull("a"); - Filter filter2 = new IsNull("b"); - - Assert.assertTrue(filter1.passesFilter(null, item1)); - Assert.assertFalse(filter1.passesFilter(null, item2)); - Assert.assertFalse(filter2.passesFilter(null, item1)); - Assert.assertTrue(filter2.passesFilter(null, item2)); - } - - @Test - public void testIsNullAppliesToProperty() { - Filter filterA = new IsNull("a"); - Filter filterB = new IsNull("b"); - - Assert.assertTrue(filterA.appliesToProperty("a")); - Assert.assertFalse(filterA.appliesToProperty("b")); - Assert.assertFalse(filterB.appliesToProperty("a")); - Assert.assertTrue(filterB.appliesToProperty("b")); - } - - @Test - public void testIsNullEqualsHashCode() { - Filter filter1 = new IsNull("a"); - Filter filter1b = new IsNull("a"); - Filter filter2 = new IsNull("b"); - - // equals() - Assert.assertEquals(filter1, filter1b); - Assert.assertFalse(filter1.equals(filter2)); - Assert.assertFalse(filter1.equals(new And())); - - // hashCode() - Assert.assertEquals(filter1.hashCode(), filter1b.hashCode()); - } - -} diff --git a/server/src/test/java/com/vaadin/data/util/filter/LikeFilterTest.java b/server/src/test/java/com/vaadin/data/util/filter/LikeFilterTest.java deleted file mode 100644 index 39054008cd..0000000000 --- a/server/src/test/java/com/vaadin/data/util/filter/LikeFilterTest.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.data.util.filter; - -import org.junit.Assert; -import org.junit.Test; - -import com.vaadin.data.Item; -import com.vaadin.data.util.ObjectProperty; -import com.vaadin.data.util.PropertysetItem; - -public class LikeFilterTest extends AbstractFilterTestBase<Like> { - - protected Item item1 = new PropertysetItem(); - protected Item item2 = new PropertysetItem(); - protected Item item3 = new PropertysetItem(); - - @Test - public void testLikeWithNulls() { - - Like filter = new Like("value", "a"); - - item1.addItemProperty("value", new ObjectProperty<String>("a")); - item2.addItemProperty("value", new ObjectProperty<String>("b")); - item3.addItemProperty("value", - new ObjectProperty<String>(null, String.class)); - - Assert.assertTrue(filter.passesFilter(null, item1)); - Assert.assertFalse(filter.passesFilter(null, item2)); - Assert.assertFalse(filter.passesFilter(null, item3)); - - } - -} diff --git a/server/src/test/java/com/vaadin/data/util/filter/NotFilterTest.java b/server/src/test/java/com/vaadin/data/util/filter/NotFilterTest.java deleted file mode 100644 index e797b484f8..0000000000 --- a/server/src/test/java/com/vaadin/data/util/filter/NotFilterTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.vaadin.data.util.filter; - -import org.junit.Assert; -import org.junit.Test; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.Item; -import com.vaadin.data.util.BeanItem; - -public class NotFilterTest extends AbstractFilterTestBase<Not> { - - protected Item item1 = new BeanItem<Integer>(1); - protected Item item2 = new BeanItem<Integer>(2); - - @Test - public void testNot() { - Filter origFilter = new SameItemFilter(item1); - Filter filter = new Not(origFilter); - - Assert.assertTrue(origFilter.passesFilter(null, item1)); - Assert.assertFalse(origFilter.passesFilter(null, item2)); - Assert.assertFalse(filter.passesFilter(null, item1)); - Assert.assertTrue(filter.passesFilter(null, item2)); - } - - @Test - public void testANotAppliesToProperty() { - Filter filterA = new Not(new SameItemFilter(item1, "a")); - Filter filterB = new Not(new SameItemFilter(item1, "b")); - - Assert.assertTrue(filterA.appliesToProperty("a")); - Assert.assertFalse(filterA.appliesToProperty("b")); - Assert.assertFalse(filterB.appliesToProperty("a")); - Assert.assertTrue(filterB.appliesToProperty("b")); - } - - @Test - public void testNotEqualsHashCode() { - Filter origFilter = new SameItemFilter(item1); - Filter filter1 = new Not(origFilter); - Filter filter1b = new Not(new SameItemFilter(item1)); - Filter filter2 = new Not(new SameItemFilter(item2)); - - // equals() - Assert.assertEquals(filter1, filter1b); - Assert.assertFalse(filter1.equals(filter2)); - Assert.assertFalse(filter1.equals(origFilter)); - Assert.assertFalse(filter1.equals(new And())); - - // hashCode() - Assert.assertEquals(filter1.hashCode(), filter1b.hashCode()); - } - -} diff --git a/server/src/test/java/com/vaadin/data/util/filter/SimpleStringFilterTest.java b/server/src/test/java/com/vaadin/data/util/filter/SimpleStringFilterTest.java deleted file mode 100644 index dd8267107a..0000000000 --- a/server/src/test/java/com/vaadin/data/util/filter/SimpleStringFilterTest.java +++ /dev/null @@ -1,139 +0,0 @@ -package com.vaadin.data.util.filter; - -import org.junit.Assert; -import org.junit.Test; - -public class SimpleStringFilterTest - extends AbstractFilterTestBase<SimpleStringFilter> { - - protected static TestItem<String, String> createTestItem() { - return new TestItem<String, String>("abcde", "TeSt"); - } - - protected TestItem<String, String> getTestItem() { - return createTestItem(); - } - - protected SimpleStringFilter f(Object propertyId, String filterString, - boolean ignoreCase, boolean onlyMatchPrefix) { - return new SimpleStringFilter(propertyId, filterString, ignoreCase, - onlyMatchPrefix); - } - - protected boolean passes(Object propertyId, String filterString, - boolean ignoreCase, boolean onlyMatchPrefix) { - return f(propertyId, filterString, ignoreCase, onlyMatchPrefix) - .passesFilter(null, getTestItem()); - } - - @Test - public void testStartsWithCaseSensitive() { - Assert.assertTrue(passes(PROPERTY1, "ab", false, true)); - Assert.assertTrue(passes(PROPERTY1, "", false, true)); - - Assert.assertFalse(passes(PROPERTY2, "ab", false, true)); - Assert.assertFalse(passes(PROPERTY1, "AB", false, true)); - } - - @Test - public void testStartsWithCaseInsensitive() { - Assert.assertTrue(passes(PROPERTY1, "AB", true, true)); - Assert.assertTrue(passes(PROPERTY2, "te", true, true)); - Assert.assertFalse(passes(PROPERTY2, "AB", true, true)); - } - - @Test - public void testContainsCaseSensitive() { - Assert.assertTrue(passes(PROPERTY1, "ab", false, false)); - Assert.assertTrue(passes(PROPERTY1, "abcde", false, false)); - Assert.assertTrue(passes(PROPERTY1, "cd", false, false)); - Assert.assertTrue(passes(PROPERTY1, "e", false, false)); - Assert.assertTrue(passes(PROPERTY1, "", false, false)); - - Assert.assertFalse(passes(PROPERTY2, "ab", false, false)); - Assert.assertFalse(passes(PROPERTY1, "es", false, false)); - } - - @Test - public void testContainsCaseInsensitive() { - Assert.assertTrue(passes(PROPERTY1, "AB", true, false)); - Assert.assertTrue(passes(PROPERTY1, "aBcDe", true, false)); - Assert.assertTrue(passes(PROPERTY1, "CD", true, false)); - Assert.assertTrue(passes(PROPERTY1, "", true, false)); - - Assert.assertTrue(passes(PROPERTY2, "es", true, false)); - - Assert.assertFalse(passes(PROPERTY2, "ab", true, false)); - } - - @Test - public void testAppliesToProperty() { - SimpleStringFilter filter = f(PROPERTY1, "ab", false, true); - Assert.assertTrue(filter.appliesToProperty(PROPERTY1)); - Assert.assertFalse(filter.appliesToProperty(PROPERTY2)); - Assert.assertFalse(filter.appliesToProperty("other")); - } - - @Test - public void testEqualsHashCode() { - SimpleStringFilter filter = f(PROPERTY1, "ab", false, true); - - SimpleStringFilter f1 = f(PROPERTY2, "ab", false, true); - SimpleStringFilter f1b = f(PROPERTY2, "ab", false, true); - SimpleStringFilter f2 = f(PROPERTY1, "cd", false, true); - SimpleStringFilter f2b = f(PROPERTY1, "cd", false, true); - SimpleStringFilter f3 = f(PROPERTY1, "ab", true, true); - SimpleStringFilter f3b = f(PROPERTY1, "ab", true, true); - SimpleStringFilter f4 = f(PROPERTY1, "ab", false, false); - SimpleStringFilter f4b = f(PROPERTY1, "ab", false, false); - - // equal but not same instance - Assert.assertEquals(f1, f1b); - Assert.assertEquals(f2, f2b); - Assert.assertEquals(f3, f3b); - Assert.assertEquals(f4, f4b); - - // more than one property differ - Assert.assertFalse(f1.equals(f2)); - Assert.assertFalse(f1.equals(f3)); - Assert.assertFalse(f1.equals(f4)); - Assert.assertFalse(f2.equals(f1)); - Assert.assertFalse(f2.equals(f3)); - Assert.assertFalse(f2.equals(f4)); - Assert.assertFalse(f3.equals(f1)); - Assert.assertFalse(f3.equals(f2)); - Assert.assertFalse(f3.equals(f4)); - Assert.assertFalse(f4.equals(f1)); - Assert.assertFalse(f4.equals(f2)); - Assert.assertFalse(f4.equals(f3)); - - // only one property differs - Assert.assertFalse(filter.equals(f1)); - Assert.assertFalse(filter.equals(f2)); - Assert.assertFalse(filter.equals(f3)); - Assert.assertFalse(filter.equals(f4)); - - Assert.assertFalse(f1.equals(null)); - Assert.assertFalse(f1.equals(new Object())); - - Assert.assertEquals(f1.hashCode(), f1b.hashCode()); - Assert.assertEquals(f2.hashCode(), f2b.hashCode()); - Assert.assertEquals(f3.hashCode(), f3b.hashCode()); - Assert.assertEquals(f4.hashCode(), f4b.hashCode()); - } - - @Test - public void testNonExistentProperty() { - Assert.assertFalse(passes("other1", "ab", false, true)); - } - - @Test - public void testNullValueForProperty() { - TestItem<String, String> item = createTestItem(); - item.addItemProperty("other1", new NullProperty()); - - Assert.assertFalse( - f("other1", "ab", false, true).passesFilter(null, item)); - } - -} diff --git a/server/src/test/java/com/vaadin/tests/server/AbstractBeanContainerListenersTest.java b/server/src/test/java/com/vaadin/tests/server/AbstractBeanContainerListenersTest.java deleted file mode 100644 index 98a2513515..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/AbstractBeanContainerListenersTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.vaadin.tests.server; - -import com.vaadin.data.Container.PropertySetChangeEvent; -import com.vaadin.data.Container.PropertySetChangeListener; -import com.vaadin.data.util.BeanItemContainer; -import com.vaadin.tests.server.component.AbstractListenerMethodsTestBase; - -public class AbstractBeanContainerListenersTest - extends AbstractListenerMethodsTestBase { - public void testPropertySetChangeListenerAddGetRemove() throws Exception { - testListenerAddGetRemove(BeanItemContainer.class, - PropertySetChangeEvent.class, PropertySetChangeListener.class, - new BeanItemContainer<PropertySetChangeListener>( - PropertySetChangeListener.class)); - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/AbstractContainerListenersTest.java b/server/src/test/java/com/vaadin/tests/server/AbstractContainerListenersTest.java deleted file mode 100644 index 5e0d464fe8..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/AbstractContainerListenersTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.vaadin.tests.server; - -import org.junit.Test; - -import com.vaadin.data.Container.ItemSetChangeEvent; -import com.vaadin.data.Container.ItemSetChangeListener; -import com.vaadin.data.Container.PropertySetChangeEvent; -import com.vaadin.data.Container.PropertySetChangeListener; -import com.vaadin.data.util.IndexedContainer; -import com.vaadin.tests.server.component.AbstractListenerMethodsTestBase; - -public class AbstractContainerListenersTest - extends AbstractListenerMethodsTestBase { - - @Test - public void testItemSetChangeListenerAddGetRemove() throws Exception { - testListenerAddGetRemove(IndexedContainer.class, - ItemSetChangeEvent.class, ItemSetChangeListener.class); - } - - @Test - public void testPropertySetChangeListenerAddGetRemove() throws Exception { - testListenerAddGetRemove(IndexedContainer.class, - PropertySetChangeEvent.class, PropertySetChangeListener.class); - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/AbstractInMemoryContainerListenersTest.java b/server/src/test/java/com/vaadin/tests/server/AbstractInMemoryContainerListenersTest.java deleted file mode 100644 index d5a7131182..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/AbstractInMemoryContainerListenersTest.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.vaadin.tests.server; - -import com.vaadin.data.Container.ItemSetChangeEvent; -import com.vaadin.data.Container.ItemSetChangeListener; -import com.vaadin.data.util.IndexedContainer; -import com.vaadin.tests.server.component.AbstractListenerMethodsTestBase; - -public class AbstractInMemoryContainerListenersTest - extends AbstractListenerMethodsTestBase { - public void testItemSetChangeListenerAddGetRemove() throws Exception { - testListenerAddGetRemove(IndexedContainer.class, - ItemSetChangeEvent.class, ItemSetChangeListener.class); - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/IndexedContainerListenersTest.java b/server/src/test/java/com/vaadin/tests/server/IndexedContainerListenersTest.java deleted file mode 100644 index d8a1290b68..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/IndexedContainerListenersTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.vaadin.tests.server; - -import org.junit.Test; - -import com.vaadin.data.Container.PropertySetChangeEvent; -import com.vaadin.data.Container.PropertySetChangeListener; -import com.vaadin.data.Property.ValueChangeEvent; -import com.vaadin.data.Property.ValueChangeListener; -import com.vaadin.data.util.IndexedContainer; -import com.vaadin.tests.server.component.AbstractListenerMethodsTestBase; - -public class IndexedContainerListenersTest - extends AbstractListenerMethodsTestBase { - - @Test - public void testValueChangeListenerAddGetRemove() throws Exception { - testListenerAddGetRemove(IndexedContainer.class, ValueChangeEvent.class, - ValueChangeListener.class); - } - - @Test - public void testPropertySetChangeListenerAddGetRemove() throws Exception { - testListenerAddGetRemove(IndexedContainer.class, - PropertySetChangeEvent.class, PropertySetChangeListener.class); - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/SerializationTest.java b/server/src/test/java/com/vaadin/tests/server/SerializationTest.java deleted file mode 100644 index 30b0729ace..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/SerializationTest.java +++ /dev/null @@ -1,135 +0,0 @@ -package com.vaadin.tests.server; - -import static org.junit.Assert.assertNotNull; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; - -import org.junit.Test; - -import com.vaadin.data.Item; -import com.vaadin.data.Property; -import com.vaadin.data.util.IndexedContainer; -import com.vaadin.data.util.MethodProperty; -import com.vaadin.server.VaadinSession; -import com.vaadin.v7.data.validator.LegacyRegexpValidator; - -public class SerializationTest { - - @Test - public void testValidators() throws Exception { - LegacyRegexpValidator validator = new LegacyRegexpValidator(".*", - "Error"); - validator.validate("aaa"); - LegacyRegexpValidator validator2 = serializeAndDeserialize(validator); - validator2.validate("aaa"); - } - - @Test - public void testIndedexContainerItemIds() throws Exception { - IndexedContainer ic = new IndexedContainer(); - ic.addContainerProperty("prop1", String.class, null); - Object id = ic.addItem(); - ic.getItem(id).getItemProperty("prop1").setValue("1"); - - Item item2 = ic.addItem("item2"); - item2.getItemProperty("prop1").setValue("2"); - - serializeAndDeserialize(ic); - } - - @Test - public void testMethodPropertyGetter() throws Exception { - MethodProperty<?> mp = new MethodProperty<Object>(new Data(), - "dummyGetter"); - serializeAndDeserialize(mp); - } - - @Test - public void testMethodPropertyGetterAndSetter() throws Exception { - MethodProperty<?> mp = new MethodProperty<Object>(new Data(), - "dummyGetterAndSetter"); - serializeAndDeserialize(mp); - } - - @Test - public void testMethodPropertyInt() throws Exception { - MethodProperty<?> mp = new MethodProperty<Object>(new Data(), - "dummyInt"); - serializeAndDeserialize(mp); - } - - @Test - public void testVaadinSession() throws Exception { - VaadinSession session = new VaadinSession(null); - - session = serializeAndDeserialize(session); - - assertNotNull( - "Pending access queue was not recreated after deserialization", - session.getPendingAccessQueue()); - } - - private static <S extends Serializable> S serializeAndDeserialize(S s) - throws IOException, ClassNotFoundException { - // Serialize and deserialize - - ByteArrayOutputStream bs = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(bs); - out.writeObject(s); - byte[] data = bs.toByteArray(); - ObjectInputStream in = new ObjectInputStream( - new ByteArrayInputStream(data)); - @SuppressWarnings("unchecked") - S s2 = (S) in.readObject(); - - // using special toString(Object) method to avoid calling - // Property.toString(), which will be temporarily disabled - // TODO This is hilariously broken (#12723) - if (s.equals(s2)) { - System.out.println(toString(s) + " equals " + toString(s2)); - } else { - System.out.println(toString(s) + " does NOT equal " + toString(s2)); - } - - return s2; - } - - private static String toString(Object o) { - if (o instanceof Property) { - return String.valueOf(((Property<?>) o).getValue()); - } else { - return String.valueOf(o); - } - } - - public static class Data implements Serializable { - private String dummyGetter; - private String dummyGetterAndSetter; - private int dummyInt; - - public String getDummyGetterAndSetter() { - return dummyGetterAndSetter; - } - - public void setDummyGetterAndSetter(String dummyGetterAndSetter) { - this.dummyGetterAndSetter = dummyGetterAndSetter; - } - - public int getDummyInt() { - return dummyInt; - } - - public void setDummyInt(int dummyInt) { - this.dummyInt = dummyInt; - } - - public String getDummyGetter() { - return dummyGetter; - } - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/calendar/CalendarBasicsTest.java b/server/src/test/java/com/vaadin/tests/server/component/calendar/CalendarBasicsTest.java deleted file mode 100644 index 7d011afc8b..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/calendar/CalendarBasicsTest.java +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.tests.server.component.calendar; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.Locale; -import java.util.TimeZone; - -import org.junit.Assert; -import org.junit.Test; - -import com.vaadin.ui.Calendar; -import com.vaadin.ui.Calendar.TimeFormat; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.BackwardEvent; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.DateClickEvent; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventResize; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.ForwardEvent; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.MoveEvent; -import com.vaadin.ui.components.calendar.CalendarComponentEvents.WeekClick; -import com.vaadin.ui.components.calendar.event.BasicEventProvider; -import com.vaadin.ui.components.calendar.event.CalendarEventProvider; - -/** - * Basic API tests for the calendar - */ -public class CalendarBasicsTest { - - @Test - public void testEmptyConstructorInitialization() { - - Calendar calendar = new Calendar(); - - // The calendar should have a basic event provider with no events - CalendarEventProvider provider = calendar.getEventProvider(); - assertNotNull("Event provider should not be null", provider); - - // Basic event handlers should be registered - assertNotNull(calendar.getHandler(BackwardEvent.EVENT_ID)); - assertNotNull(calendar.getHandler(ForwardEvent.EVENT_ID)); - assertNotNull(calendar.getHandler(WeekClick.EVENT_ID)); - assertNotNull(calendar.getHandler(DateClickEvent.EVENT_ID)); - assertNotNull(calendar.getHandler(MoveEvent.EVENT_ID)); - assertNotNull(calendar.getHandler(EventResize.EVENT_ID)); - - // Calendar should have undefined size - assertTrue(calendar.getWidth() < 0); - assertTrue(calendar.getHeight() < 0); - } - - @Test - public void testConstructorWithCaption() { - final String caption = "My Calendar Caption"; - Calendar calendar = new Calendar(caption); - assertEquals(caption, calendar.getCaption()); - } - - @Test - public void testConstructorWithCustomEventProvider() { - BasicEventProvider myProvider = new BasicEventProvider(); - Calendar calendar = new Calendar(myProvider); - assertEquals(myProvider, calendar.getEventProvider()); - } - - @Test - public void testConstructorWithCustomEventProviderAndCaption() { - BasicEventProvider myProvider = new BasicEventProvider(); - final String caption = "My Calendar Caption"; - Calendar calendar = new Calendar(caption, myProvider); - assertEquals(caption, calendar.getCaption()); - assertEquals(myProvider, calendar.getEventProvider()); - } - - @Test - public void testDefaultStartAndEndDates() { - Calendar calendar = new Calendar(); - - // If no start and end date is set the calendar will display the current - // week - java.util.Calendar c = new GregorianCalendar(); - java.util.Calendar c2 = new GregorianCalendar(); - - c2.setTime(calendar.getStartDate()); - assertEquals(c.getFirstDayOfWeek(), - c2.get(java.util.Calendar.DAY_OF_WEEK)); - c2.setTime(calendar.getEndDate()); - - c.set(java.util.Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek() + 6); - assertEquals(c.get(java.util.Calendar.DAY_OF_WEEK), - c2.get(java.util.Calendar.DAY_OF_WEEK)); - } - - @Test - public void testCustomStartAndEndDates() { - Calendar calendar = new Calendar(); - java.util.Calendar c = new GregorianCalendar(); - - Date start = c.getTime(); - c.add(java.util.Calendar.DATE, 3); - Date end = c.getTime(); - - calendar.setStartDate(start); - calendar.setEndDate(end); - - assertEquals(start.getTime(), calendar.getStartDate().getTime()); - assertEquals(end.getTime(), calendar.getEndDate().getTime()); - } - - @Test - public void testCustomLocale() { - Calendar calendar = new Calendar(); - calendar.setLocale(Locale.CANADA_FRENCH); - - // Setting the locale should set the internal calendars locale - assertEquals(Locale.CANADA_FRENCH, calendar.getLocale()); - java.util.Calendar c = new GregorianCalendar(Locale.CANADA_FRENCH); - assertEquals(c.getTimeZone().getRawOffset(), - calendar.getInternalCalendar().getTimeZone().getRawOffset()); - } - - @Test - public void testTimeFormat() { - Calendar calendar = new Calendar(); - - // The default timeformat depends on the current locale - calendar.setLocale(Locale.ENGLISH); - assertEquals(TimeFormat.Format12H, calendar.getTimeFormat()); - - calendar.setLocale(Locale.ITALIAN); - assertEquals(TimeFormat.Format24H, calendar.getTimeFormat()); - - // Setting a specific time format overrides the locale - calendar.setTimeFormat(TimeFormat.Format12H); - assertEquals(TimeFormat.Format12H, calendar.getTimeFormat()); - } - - @Test - public void testTimeZone() { - Calendar calendar = new Calendar(); - calendar.setLocale(Locale.CANADA_FRENCH); - - // By default the calendars timezone is returned - assertEquals(calendar.getInternalCalendar().getTimeZone(), - calendar.getTimeZone()); - - // One can override the default behaviour by specifying a timezone - TimeZone customTimeZone = TimeZone.getTimeZone("Europe/Helsinki"); - calendar.setTimeZone(customTimeZone); - assertEquals(customTimeZone, calendar.getTimeZone()); - } - - @Test - public void testVisibleDaysOfWeek() { - Calendar calendar = new Calendar(); - - // The defaults are the whole week - assertEquals(1, calendar.getFirstVisibleDayOfWeek()); - assertEquals(7, calendar.getLastVisibleDayOfWeek()); - - calendar.setFirstVisibleDayOfWeek(0); // Invalid input - assertEquals(1, calendar.getFirstVisibleDayOfWeek()); - - calendar.setLastVisibleDayOfWeek(0); // Invalid input - assertEquals(7, calendar.getLastVisibleDayOfWeek()); - - calendar.setFirstVisibleDayOfWeek(8); // Invalid input - assertEquals(1, calendar.getFirstVisibleDayOfWeek()); - - calendar.setLastVisibleDayOfWeek(8); // Invalid input - assertEquals(7, calendar.getLastVisibleDayOfWeek()); - - calendar.setFirstVisibleDayOfWeek(4); - assertEquals(4, calendar.getFirstVisibleDayOfWeek()); - - calendar.setLastVisibleDayOfWeek(6); - assertEquals(6, calendar.getLastVisibleDayOfWeek()); - - calendar.setFirstVisibleDayOfWeek(7); // Invalid since last day is 6 - assertEquals(4, calendar.getFirstVisibleDayOfWeek()); - - calendar.setLastVisibleDayOfWeek(2); // Invalid since first day is 4 - assertEquals(6, calendar.getLastVisibleDayOfWeek()); - } - - @Test - public void testVisibleHoursInDay() { - Calendar calendar = new Calendar(); - - // Defaults are the whole day - assertEquals(0, calendar.getFirstVisibleHourOfDay()); - assertEquals(23, calendar.getLastVisibleHourOfDay()); - } - - @Test - public void isClientChangeAllowed_connectorEnabled() { - TestCalendar calendar = new TestCalendar(true); - Assert.assertTrue( - "Calendar with enabled connector doesn't allow client change", - calendar.isClientChangeAllowed()); - } - - // regression test to ensure old functionality is not broken - @Test - public void defaultFirstDayOfWeek() { - Calendar calendar = new Calendar(); - calendar.setLocale(Locale.GERMAN); - // simulating consequences of markAsDirty - calendar.beforeClientResponse(true); - assertEquals(java.util.Calendar.MONDAY, - calendar.getInternalCalendar().getFirstDayOfWeek()); - } - - @Test - public void customFirstDayOfWeek() { - Calendar calendar = new Calendar(); - calendar.setLocale(Locale.GERMAN); - calendar.setFirstDayOfWeek(java.util.Calendar.SUNDAY); - - // simulating consequences of markAsDirty - calendar.beforeClientResponse(true); - assertEquals(java.util.Calendar.SUNDAY, - calendar.getInternalCalendar().getFirstDayOfWeek()); - } - - @Test - public void customFirstDayOfWeekCanSetEvenBeforeLocale() { - Calendar calendar = new Calendar(); - calendar.setFirstDayOfWeek(java.util.Calendar.SUNDAY); - - calendar.setLocale(Locale.GERMAN); - // simulating consequences of markAsDirty - calendar.beforeClientResponse(true); - assertEquals(java.util.Calendar.SUNDAY, - calendar.getInternalCalendar().getFirstDayOfWeek()); - } - - @Test - public void customFirstDayOfWeekSetNullRestoresDefault() { - Calendar calendar = new Calendar(); - calendar.setLocale(Locale.GERMAN); - calendar.setFirstDayOfWeek(java.util.Calendar.SUNDAY); - calendar.setFirstDayOfWeek(null); - // simulating consequences of markAsDirty - calendar.beforeClientResponse(true); - assertEquals(java.util.Calendar.MONDAY, - calendar.getInternalCalendar().getFirstDayOfWeek()); - } - - @Test(expected = IllegalArgumentException.class) - public void customFirstDayOfWeekValidation() { - Calendar calendar = new Calendar(); - int someWrongDayOfWeek = 10; - calendar.setFirstDayOfWeek(someWrongDayOfWeek); - } - - private static class TestCalendar extends Calendar { - TestCalendar(boolean connectorEnabled) { - isConnectorEnabled = connectorEnabled; - } - - @Override - public boolean isConnectorEnabled() { - return isConnectorEnabled; - } - - @Override - public boolean isClientChangeAllowed() { - return super.isClientChangeAllowed(); - } - - private final boolean isConnectorEnabled; - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/calendar/CalendarDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/calendar/CalendarDeclarativeTest.java deleted file mode 100644 index f6896ff15d..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/calendar/CalendarDeclarativeTest.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.tests.server.component.calendar; - -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.TimeZone; - -import org.junit.Test; - -import com.vaadin.tests.design.DeclarativeTestBase; -import com.vaadin.ui.Calendar; -import com.vaadin.ui.Calendar.TimeFormat; - -public class CalendarDeclarativeTest extends DeclarativeTestBase<Calendar> { - - @Test - public void testEmpty() { - verifyDeclarativeDesign("<vaadin-calendar></vaadin-calendar>", - new Calendar()); - } - - @Test - public void testCalendarAllFeatures() throws ParseException { - String design = "<vaadin-calendar start-date='2014-11-17' end-date='2014-11-23' " - + "first-visible-day-of-week=2 last-visible-day-of-week=5 " - + "time-zone='EST' time-format='12h' first-visible-hour-of-day=8 " - + "last-visible-hour-of-day=18 weekly-caption-format='mmm MM/dd' />"; - - DateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - Calendar calendar = new Calendar(); - calendar.setStartDate(format.parse("2014-11-17")); - calendar.setEndDate(format.parse("2014-11-23")); - calendar.setFirstVisibleDayOfWeek(2); - calendar.setLastVisibleDayOfWeek(5); - calendar.setTimeZone(TimeZone.getTimeZone("EST")); - calendar.setTimeFormat(TimeFormat.Format12H); - calendar.setFirstVisibleHourOfDay(8); - calendar.setLastVisibleHourOfDay(18); - calendar.setWeeklyCaptionFormat("mmm MM/dd"); - verifyDeclarativeDesign(design, calendar); - } - - protected void verifyDeclarativeDesign(String design, Calendar expected) { - testRead(design, expected); - testWrite(design, expected); - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/calendar/ContainerDataSourceTest.java b/server/src/test/java/com/vaadin/tests/server/component/calendar/ContainerDataSourceTest.java deleted file mode 100644 index 9cc78269f8..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/calendar/ContainerDataSourceTest.java +++ /dev/null @@ -1,396 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.tests.server.component.calendar; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.util.Date; -import java.util.List; - -import org.junit.Before; -import org.junit.Test; - -import com.vaadin.data.Container.Indexed; -import com.vaadin.data.Container.Sortable; -import com.vaadin.data.Item; -import com.vaadin.data.Property; -import com.vaadin.data.util.BeanItemContainer; -import com.vaadin.data.util.IndexedContainer; -import com.vaadin.ui.Calendar; -import com.vaadin.ui.components.calendar.ContainerEventProvider; -import com.vaadin.ui.components.calendar.event.BasicEvent; -import com.vaadin.ui.components.calendar.event.CalendarEvent; - -public class ContainerDataSourceTest { - - private Calendar calendar; - - @Before - public void setUp() { - calendar = new Calendar(); - } - - /** - * Tests adding a bean item container to the Calendar - */ - @Test - public void testWithBeanItemContainer() { - - // Create a container to use as a datasource - Indexed container = createTestBeanItemContainer(); - - // Set datasource - calendar.setContainerDataSource(container); - - // Start and end dates to query for - java.util.Calendar cal = java.util.Calendar.getInstance(); - cal.setTime(((CalendarEvent) container.getIdByIndex(0)).getStart()); - Date start = cal.getTime(); - cal.add(java.util.Calendar.MONTH, 1); - Date end = cal.getTime(); - - // Test the all events are returned - List<CalendarEvent> events = calendar.getEventProvider() - .getEvents(start, end); - assertEquals(container.size(), events.size()); - - // Test that a certain range is returned - cal.setTime(((CalendarEvent) container.getIdByIndex(6)).getStart()); - end = cal.getTime(); - events = calendar.getEventProvider().getEvents(start, end); - assertEquals(6, events.size()); - } - - /** - * This tests tests that if you give the Calendar an unsorted (== not sorted - * by starting date) container then the calendar should gracefully handle - * it. In this case the size of the container will be wrong. The test is - * exactly the same as {@link #testWithBeanItemContainer()} except that the - * beans has been intentionally sorted by caption instead of date. - */ - @Test - public void testWithUnsortedBeanItemContainer() { - // Create a container to use as a datasource - Indexed container = createTestBeanItemContainer(); - - // Make the container sorted by caption - ((Sortable) container).sort(new Object[] { "caption" }, - new boolean[] { true }); - - // Set data source - calendar.setContainerDataSource(container); - - // Start and end dates to query for - java.util.Calendar cal = java.util.Calendar.getInstance(); - cal.setTime(((CalendarEvent) container.getIdByIndex(0)).getStart()); - Date start = cal.getTime(); - cal.add(java.util.Calendar.MONTH, 1); - Date end = cal.getTime(); - - // Test the all events are returned - List<CalendarEvent> events = calendar.getEventProvider() - .getEvents(start, end); - assertEquals(container.size(), events.size()); - - // Test that a certain range is returned - cal.setTime(((CalendarEvent) container.getIdByIndex(6)).getStart()); - end = cal.getTime(); - events = calendar.getEventProvider().getEvents(start, end); - - // The events size is 1 since the getEvents returns the wrong range - assertEquals(1, events.size()); - } - - /** - * Tests adding a Indexed container to the Calendar - */ - @Test - public void testWithIndexedContainer() { - - // Create a container to use as a datasource - Indexed container = createTestIndexedContainer(); - - // Set datasource - calendar.setContainerDataSource(container, "testCaption", - "testDescription", "testStartDate", "testEndDate", null); - - // Start and end dates to query for - java.util.Calendar cal = java.util.Calendar.getInstance(); - cal.setTime((Date) container.getItem(container.getIdByIndex(0)) - .getItemProperty("testStartDate").getValue()); - Date start = cal.getTime(); - cal.add(java.util.Calendar.MONTH, 1); - Date end = cal.getTime(); - - // Test the all events are returned - List<CalendarEvent> events = calendar.getEventProvider() - .getEvents(start, end); - assertEquals(container.size(), events.size()); - - // Check that event values are present - CalendarEvent e = events.get(0); - assertEquals("Test 1", e.getCaption()); - assertEquals("Description 1", e.getDescription()); - assertTrue(e.getStart().compareTo(start) == 0); - - // Test that a certain range is returned - cal.setTime((Date) container.getItem(container.getIdByIndex(6)) - .getItemProperty("testStartDate").getValue()); - end = cal.getTime(); - events = calendar.getEventProvider().getEvents(start, end); - assertEquals(6, events.size()); - } - - @Test - public void testNullLimitsBeanItemContainer() { - // Create a container to use as a datasource - Indexed container = createTestBeanItemContainer(); - - // Start and end dates to query for - java.util.Calendar cal = java.util.Calendar.getInstance(); - cal.setTime(((CalendarEvent) container.getIdByIndex(0)).getStart()); - Date start = cal.getTime(); - cal.add(java.util.Calendar.MONTH, 1); - Date end = cal.getTime(); - - // Set datasource - calendar.setContainerDataSource(container); - - // Test null start time - List<CalendarEvent> events = calendar.getEventProvider().getEvents(null, - end); - assertEquals(container.size(), events.size()); - - // Test null end time - events = calendar.getEventProvider().getEvents(start, null); - assertEquals(container.size(), events.size()); - - // Test both null times - events = calendar.getEventProvider().getEvents(null, null); - assertEquals(container.size(), events.size()); - } - - @Test - public void testNullLimitsIndexedContainer() { - // Create a container to use as a datasource - Indexed container = createTestIndexedContainer(); - - // Start and end dates to query for - java.util.Calendar cal = java.util.Calendar.getInstance(); - cal.setTime((Date) container.getItem(container.getIdByIndex(0)) - .getItemProperty("testStartDate").getValue()); - Date start = cal.getTime(); - cal.add(java.util.Calendar.MONTH, 1); - Date end = cal.getTime(); - - // Set datasource - calendar.setContainerDataSource(container, "testCaption", - "testDescription", "testStartDate", "testEndDate", null); - - // Test null start time - List<CalendarEvent> events = calendar.getEventProvider().getEvents(null, - end); - assertEquals(container.size(), events.size()); - - // Test null end time - events = calendar.getEventProvider().getEvents(start, null); - assertEquals(container.size(), events.size()); - - // Test both null times - events = calendar.getEventProvider().getEvents(null, null); - assertEquals(container.size(), events.size()); - } - - /** - * Tests the addEvent convenience method with the default event provider - */ - @Test - public void testAddEventConvinienceMethod() { - - // Start and end dates to query for - java.util.Calendar cal = java.util.Calendar.getInstance(); - Date start = cal.getTime(); - cal.add(java.util.Calendar.MONTH, 1); - Date end = cal.getTime(); - - // Ensure no events - assertEquals(0, calendar.getEvents(start, end).size()); - - // Add an event - BasicEvent event = new BasicEvent("Test", "Test", start); - calendar.addEvent(event); - - // Ensure event exists - List<CalendarEvent> events = calendar.getEvents(start, end); - assertEquals(1, events.size()); - assertEquals(events.get(0).getCaption(), event.getCaption()); - assertEquals(events.get(0).getDescription(), event.getDescription()); - assertEquals(events.get(0).getStart(), event.getStart()); - } - - /** - * Test the removeEvent convenience method with the default event provider - */ - @Test - public void testRemoveEventConvinienceMethod() { - - // Start and end dates to query for - java.util.Calendar cal = java.util.Calendar.getInstance(); - Date start = cal.getTime(); - cal.add(java.util.Calendar.MONTH, 1); - Date end = cal.getTime(); - - // Ensure no events - assertEquals(0, calendar.getEvents(start, end).size()); - - // Add an event - CalendarEvent event = new BasicEvent("Test", "Test", start); - calendar.addEvent(event); - - // Ensure event exists - assertEquals(1, calendar.getEvents(start, end).size()); - - // Remove event - calendar.removeEvent(event); - - // Ensure no events - assertEquals(0, calendar.getEvents(start, end).size()); - } - - @Test - public void testAddEventConvinienceMethodWithCustomEventProvider() { - - // Use a container data source - calendar.setEventProvider(new ContainerEventProvider( - new BeanItemContainer<BasicEvent>(BasicEvent.class))); - - // Start and end dates to query for - java.util.Calendar cal = java.util.Calendar.getInstance(); - Date start = cal.getTime(); - cal.add(java.util.Calendar.MONTH, 1); - Date end = cal.getTime(); - - // Ensure no events - assertEquals(0, calendar.getEvents(start, end).size()); - - // Add an event - BasicEvent event = new BasicEvent("Test", "Test", start); - calendar.addEvent(event); - - // Ensure event exists - List<CalendarEvent> events = calendar.getEvents(start, end); - assertEquals(1, events.size()); - assertEquals(events.get(0).getCaption(), event.getCaption()); - assertEquals(events.get(0).getDescription(), event.getDescription()); - assertEquals(events.get(0).getStart(), event.getStart()); - } - - @Test - public void testRemoveEventConvinienceMethodWithCustomEventProvider() { - - // Use a container data source - calendar.setEventProvider(new ContainerEventProvider( - new BeanItemContainer<BasicEvent>(BasicEvent.class))); - - // Start and end dates to query for - java.util.Calendar cal = java.util.Calendar.getInstance(); - Date start = cal.getTime(); - cal.add(java.util.Calendar.MONTH, 1); - Date end = cal.getTime(); - - // Ensure no events - assertEquals(0, calendar.getEvents(start, end).size()); - - // Add an event - BasicEvent event = new BasicEvent("Test", "Test", start); - calendar.addEvent(event); - - // Ensure event exists - List<CalendarEvent> events = calendar.getEvents(start, end); - assertEquals(1, events.size()); - - // Remove event - calendar.removeEvent(event); - - // Ensure no events - assertEquals(0, calendar.getEvents(start, end).size()); - } - - @Test - public void testStyleNamePropertyRetrieved() { - IndexedContainer ic = (IndexedContainer) createTestIndexedContainer(); - ic.addContainerProperty("testStyleName", String.class, ""); - for (int i = 0; i < 10; i++) { - Item item = ic.getItem(ic.getIdByIndex(i)); - @SuppressWarnings("unchecked") - Property<String> itemProperty = item - .getItemProperty("testStyleName"); - itemProperty.setValue("testStyle"); - } - - ContainerEventProvider provider = new ContainerEventProvider(ic); - provider.setCaptionProperty("testCaption"); - provider.setDescriptionProperty("testDescription"); - provider.setStartDateProperty("testStartDate"); - provider.setEndDateProperty("testEndDate"); - provider.setStyleNameProperty("testStyleName"); - - calendar.setEventProvider(provider); - java.util.Calendar cal = java.util.Calendar.getInstance(); - Date now = cal.getTime(); - cal.add(java.util.Calendar.DAY_OF_MONTH, 20); - Date then = cal.getTime(); - List<CalendarEvent> events = calendar.getEventProvider().getEvents(now, - then); - for (CalendarEvent ce : events) { - assertEquals("testStyle", ce.getStyleName()); - } - } - - private static Indexed createTestBeanItemContainer() { - BeanItemContainer<CalendarEvent> eventContainer = new BeanItemContainer<CalendarEvent>( - CalendarEvent.class); - java.util.Calendar cal = java.util.Calendar.getInstance(); - for (int i = 1; i <= 10; i++) { - eventContainer.addBean(new BasicEvent("Test " + i, - "Description " + i, cal.getTime())); - cal.add(java.util.Calendar.DAY_OF_MONTH, 2); - } - return eventContainer; - } - - private static Indexed createTestIndexedContainer() { - IndexedContainer container = new IndexedContainer(); - container.addContainerProperty("testCaption", String.class, ""); - container.addContainerProperty("testDescription", String.class, ""); - container.addContainerProperty("testStartDate", Date.class, null); - container.addContainerProperty("testEndDate", Date.class, null); - - java.util.Calendar cal = java.util.Calendar.getInstance(); - for (int i = 1; i <= 10; i++) { - Item item = container.getItem(container.addItem()); - item.getItemProperty("testCaption").setValue("Test " + i); - item.getItemProperty("testDescription") - .setValue("Description " + i); - item.getItemProperty("testStartDate").setValue(cal.getTime()); - item.getItemProperty("testEndDate").setValue(cal.getTime()); - cal.add(java.util.Calendar.DAY_OF_MONTH, 2); - } - return container; - } - -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/calendar/ContainerEventProviderTest.java b/server/src/test/java/com/vaadin/tests/server/component/calendar/ContainerEventProviderTest.java deleted file mode 100644 index 401b5861ce..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/calendar/ContainerEventProviderTest.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.tests.server.component.calendar; - -import java.util.Calendar; -import java.util.Date; -import java.util.List; - -import org.junit.Assert; -import org.junit.Test; - -import com.vaadin.data.util.BeanItemContainer; -import com.vaadin.ui.components.calendar.ContainerEventProvider; -import com.vaadin.ui.components.calendar.event.CalendarEvent; - -/** - * - * @author Vaadin Ltd - */ -public class ContainerEventProviderTest { - - @Test - public void testDefaultAllDayProperty() { - ContainerEventProvider provider = new ContainerEventProvider(null); - Assert.assertEquals(ContainerEventProvider.ALL_DAY_PROPERTY, - provider.getAllDayProperty()); - - } - - @Test - public void testSetAllDayProperty() { - ContainerEventProvider provider = new ContainerEventProvider(null); - Object prop = new Object(); - provider.setAllDayProperty(prop); - Assert.assertEquals(prop, provider.getAllDayProperty()); - } - - @Test - public void testGetEvents() { - BeanItemContainer<EventBean> container = new BeanItemContainer<EventBean>( - EventBean.class); - EventBean bean = new EventBean(); - container.addBean(bean); - ContainerEventProvider provider = new ContainerEventProvider(container); - List<CalendarEvent> events = provider.getEvents(bean.getStart(), - bean.getEnd()); - Assert.assertTrue(events.get(0).isAllDay()); - } - - public static class EventBean { - - public boolean isAllDay() { - return true; - } - - public void setAllDay(boolean allDay) { - } - - public Date getStart() { - return Calendar.getInstance().getTime(); - } - - public Date getEnd() { - Calendar calendar = Calendar.getInstance(); - calendar.add(Calendar.MINUTE, 10); - return calendar.getTime(); - } - - public void setStart(Date date) { - } - - public void setEnd(Date date) { - } - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/colorpicker/AbstractColorPickerDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/colorpicker/AbstractColorPickerDeclarativeTest.java deleted file mode 100644 index 2e3b8e412e..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/colorpicker/AbstractColorPickerDeclarativeTest.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.tests.server.component.colorpicker; - -import org.junit.Test; - -import com.vaadin.shared.ui.colorpicker.Color; -import com.vaadin.tests.design.DeclarativeTestBase; -import com.vaadin.ui.AbstractColorPicker; -import com.vaadin.ui.AbstractColorPicker.PopupStyle; -import com.vaadin.ui.ColorPicker; -import com.vaadin.ui.ColorPickerArea; - -public class AbstractColorPickerDeclarativeTest - extends DeclarativeTestBase<AbstractColorPicker> { - - @Test - public void testAllAbstractColorPickerFeatures() { - String design = "<vaadin-color-picker color='#fafafa' default-caption-enabled position='100,100'" - + " popup-style='simple' rgb-visibility='false' hsv-visibility='false'" - + " history-visibility=false textfield-visibility=false />"; - ColorPicker colorPicker = new ColorPicker(); - int colorInt = Integer.parseInt("fafafa", 16); - colorPicker.setColor(new Color(colorInt)); - colorPicker.setDefaultCaptionEnabled(true); - colorPicker.setPosition(100, 100); - colorPicker.setPopupStyle(PopupStyle.POPUP_SIMPLE); - colorPicker.setRGBVisibility(false); - colorPicker.setHSVVisibility(false); - colorPicker.setSwatchesVisibility(true); - colorPicker.setHistoryVisibility(false); - colorPicker.setTextfieldVisibility(false); - - testWrite(design, colorPicker); - testRead(design, colorPicker); - } - - @Test - public void testEmptyColorPicker() { - String design = "<vaadin-color-picker />"; - ColorPicker colorPicker = new ColorPicker(); - testRead(design, colorPicker); - testWrite(design, colorPicker); - } - - @Test - public void testAllAbstractColorPickerAreaFeatures() { - String design = "<vaadin-color-picker-area color='#fafafa' default-caption-enabled position='100,100'" - + " popup-style='simple' rgb-visibility='false' hsv-visibility='false'" - + " history-visibility=false textfield-visibility=false />"; - AbstractColorPicker colorPicker = new ColorPickerArea(); - int colorInt = Integer.parseInt("fafafa", 16); - colorPicker.setColor(new Color(colorInt)); - colorPicker.setDefaultCaptionEnabled(true); - colorPicker.setPosition(100, 100); - colorPicker.setPopupStyle(PopupStyle.POPUP_SIMPLE); - colorPicker.setRGBVisibility(false); - colorPicker.setHSVVisibility(false); - colorPicker.setSwatchesVisibility(true); - colorPicker.setHistoryVisibility(false); - colorPicker.setTextfieldVisibility(false); - - testWrite(design, colorPicker); - testRead(design, colorPicker); - } - - @Test - public void testEmptyColorPickerArea() { - String design = "<vaadin-color-picker-area />"; - AbstractColorPicker colorPicker = new ColorPickerArea(); - testRead(design, colorPicker); - testWrite(design, colorPicker); - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/colorpicker/ColorConversionsTest.java b/server/src/test/java/com/vaadin/tests/server/component/colorpicker/ColorConversionsTest.java deleted file mode 100644 index a55ed89691..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/colorpicker/ColorConversionsTest.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.tests.server.component.colorpicker; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.vaadin.shared.ui.colorpicker.Color; - -public class ColorConversionsTest { - - @Test - public void convertHSL2RGB() { - - int rgb = Color.HSLtoRGB(100, 50, 50); - Color c = new Color(rgb); - assertEquals(106, c.getRed()); - assertEquals(191, c.getGreen()); - assertEquals(64, c.getBlue()); - assertEquals("#6abf40", c.getCSS()); - - rgb = Color.HSLtoRGB(0, 50, 50); - c = new Color(rgb); - assertEquals(191, c.getRed()); - assertEquals(64, c.getGreen()); - assertEquals(64, c.getBlue()); - assertEquals("#bf4040", c.getCSS()); - - rgb = Color.HSLtoRGB(50, 0, 50); - c = new Color(rgb); - assertEquals(128, c.getRed()); - assertEquals(128, c.getGreen()); - assertEquals(128, c.getBlue()); - assertEquals("#808080", c.getCSS()); - - rgb = Color.HSLtoRGB(50, 100, 0); - c = new Color(rgb); - assertEquals(0, c.getRed(), 0); - assertEquals(0, c.getGreen(), 0); - assertEquals(0, c.getBlue(), 0); - assertEquals("#000000", c.getCSS()); - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/combobox/ComboBoxDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/combobox/ComboBoxDeclarativeTest.java deleted file mode 100644 index 482267f63d..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/combobox/ComboBoxDeclarativeTest.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.tests.server.component.combobox; - -import org.junit.Test; - -import com.vaadin.shared.ui.combobox.FilteringMode; -import com.vaadin.tests.design.DeclarativeTestBase; -import com.vaadin.ui.ComboBox; - -public class ComboBoxDeclarativeTest extends DeclarativeTestBase<ComboBox> { - - @Test - public void testReadOnlyWithOptionsRead() { - testRead(getReadOnlyWithOptionsDesign(), - getReadOnlyWithOptionsExpected()); - } - - private ComboBox getReadOnlyWithOptionsExpected() { - ComboBox cb = new ComboBox(); - cb.setTextInputAllowed(false); - cb.addItem("Hello"); - cb.addItem("World"); - return cb; - } - - private String getReadOnlyWithOptionsDesign() { - return "<vaadin-combo-box text-input-allowed='false'><option>Hello</option><option>World</option></vaadin-combo-box>"; - } - - @Test - public void testReadOnlyWithOptionsWrite() { - testWrite(stripOptionTags(getReadOnlyWithOptionsDesign()), - getReadOnlyWithOptionsExpected()); - } - - @Test - public void testBasicRead() { - testRead(getBasicDesign(), getBasicExpected()); - } - - @Test - public void testBasicWrite() { - testWrite(getBasicDesign(), getBasicExpected()); - } - - @Test - public void testReadOnlyValue() { - String design = "<vaadin-combo-box readonly value='foo'><option selected>foo</option></vaadin-combo-box>"; - - ComboBox comboBox = new ComboBox(); - comboBox.addItems("foo", "bar"); - comboBox.setValue("foo"); - comboBox.setReadOnly(true); - - testRead(design, comboBox); - - // Selects items are not written out by default - String design2 = "<vaadin-combo-box readonly></vaadin-combo-box>"; - testWrite(design2, comboBox); - } - - private String getBasicDesign() { - return "<vaadin-combo-box input-prompt=\"Select something\" filtering-mode=\"off\" scroll-to-selected-item='false'>"; - } - - private ComboBox getBasicExpected() { - ComboBox cb = new ComboBox(); - cb.setInputPrompt("Select something"); - cb.setTextInputAllowed(true); - cb.setFilteringMode(FilteringMode.OFF); - cb.setScrollToSelectedItem(false); - return cb; - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/combobox/ComboBoxStateTest.java b/server/src/test/java/com/vaadin/tests/server/component/combobox/ComboBoxStateTest.java deleted file mode 100644 index e8ca64895a..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/combobox/ComboBoxStateTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.tests.server.component.combobox; - -import org.junit.Assert; -import org.junit.Test; - -import com.vaadin.shared.ui.combobox.ComboBoxState; -import com.vaadin.ui.ComboBox; - -/** - * Tests for ComboBox state. - * - */ -public class ComboBoxStateTest { - @Test - public void getState_comboboxHasCustomState() { - TestComboBox combobox = new TestComboBox(); - ComboBoxState state = combobox.getState(); - Assert.assertEquals("Unexpected state class", ComboBoxState.class, - state.getClass()); - } - - @Test - public void getPrimaryStyleName_comboboxHasCustomPrimaryStyleName() { - ComboBox combobox = new ComboBox(); - ComboBoxState state = new ComboBoxState(); - Assert.assertEquals("Unexpected primary style name", - state.primaryStyleName, combobox.getPrimaryStyleName()); - } - - @Test - public void comboboxStateHasCustomPrimaryStyleName() { - ComboBoxState state = new ComboBoxState(); - Assert.assertEquals("Unexpected primary style name", "v-filterselect", - state.primaryStyleName); - } - - private static class TestComboBox extends ComboBox { - - @Override - public ComboBoxState getState() { - return super.getState(); - } - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/tree/ListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/tree/ListenersTest.java deleted file mode 100644 index ade24a0df6..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/tree/ListenersTest.java +++ /dev/null @@ -1,143 +0,0 @@ -package com.vaadin.tests.server.component.tree; - -import static org.junit.Assert.assertEquals; - -import java.util.ArrayList; -import java.util.List; - -import org.junit.Before; -import org.junit.Test; - -import com.vaadin.ui.Tree; -import com.vaadin.ui.Tree.CollapseEvent; -import com.vaadin.ui.Tree.CollapseListener; -import com.vaadin.ui.Tree.ExpandEvent; -import com.vaadin.ui.Tree.ExpandListener; - -public class ListenersTest implements ExpandListener, CollapseListener { - private int expandCalled; - private int collapseCalled; - private Object lastExpanded; - private Object lastCollapsed; - - @Before - public void setUp() { - expandCalled = 0; - } - - @Test - public void testExpandListener() { - Tree tree = createTree(10, 20, false); - tree.addListener((ExpandListener) this); - List<Object> rootIds = new ArrayList<Object>(tree.rootItemIds()); - - assertEquals(10, rootIds.size()); - assertEquals(10 + 10 * 20 + 10, tree.size()); - - // Expanding should send one expand event for the root item id - tree.expandItem(rootIds.get(0)); - assertEquals(1, expandCalled); - assertEquals(rootIds.get(0), lastExpanded); - - // Expand should send one event for each expanded item id. - // In this case root + child 4 - expandCalled = 0; - tree.expandItemsRecursively(rootIds.get(1)); - assertEquals(2, expandCalled); - List<Object> c = new ArrayList<Object>( - tree.getChildren(rootIds.get(1))); - - assertEquals(c.get(4), lastExpanded); - - // Expanding an already expanded item should send no expand event - expandCalled = 0; - tree.expandItem(rootIds.get(0)); - assertEquals(0, expandCalled); - } - - /** - * Creates a tree with "rootItems" roots, each with "children" children, - * each with 1 child. - * - * @param rootItems - * @param children - * @param expand - * @return - */ - private Tree createTree(int rootItems, int children, boolean expand) { - Tree tree = new Tree(); - for (int i = 0; i < rootItems; i++) { - String rootId = "root " + i; - tree.addItem(rootId); - if (expand) { - tree.expandItemsRecursively(rootId); - } else { - tree.collapseItemsRecursively(rootId); - - } - for (int j = 0; j < children; j++) { - String childId = "child " + i + "/" + j; - tree.addItem(childId); - tree.setParent(childId, rootId); - tree.setChildrenAllowed(childId, false); - if (j == 4) { - tree.setChildrenAllowed(childId, true); - Object grandChildId = tree.addItem(); - tree.setParent(grandChildId, childId); - tree.setChildrenAllowed(grandChildId, false); - if (expand) { - tree.expandItemsRecursively(childId); - } else { - tree.collapseItemsRecursively(childId); - } - } - } - } - - return tree; - } - - @Test - public void testCollapseListener() { - Tree tree = createTree(7, 15, true); - tree.addListener((CollapseListener) this); - - List<Object> rootIds = new ArrayList<Object>(tree.rootItemIds()); - - assertEquals(7, rootIds.size()); - assertEquals(7 + 7 * 15 + 7, tree.size()); - - // Expanding should send one expand event for the root item id - tree.collapseItem(rootIds.get(0)); - assertEquals(1, collapseCalled); - assertEquals(rootIds.get(0), lastCollapsed); - - // Collapse sends one event for each collapsed node. - // In this case root + child 4 - collapseCalled = 0; - tree.collapseItemsRecursively(rootIds.get(1)); - assertEquals(2, collapseCalled); - List<Object> c = new ArrayList<Object>( - tree.getChildren(rootIds.get(1))); - assertEquals(c.get(4), lastCollapsed); - - // Collapsing an already expanded item should send no expand event - collapseCalled = 0; - tree.collapseItem(rootIds.get(0)); - assertEquals(0, collapseCalled); - } - - @Override - public void nodeExpand(ExpandEvent event) { - lastExpanded = event.getItemId(); - expandCalled++; - - } - - @Override - public void nodeCollapse(CollapseEvent event) { - lastCollapsed = event.getItemId(); - collapseCalled++; - - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/tree/TreeDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/tree/TreeDeclarativeTest.java deleted file mode 100644 index 1e73f953b2..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/tree/TreeDeclarativeTest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.tests.server.component.tree; - -import org.junit.Test; - -import com.vaadin.server.ExternalResource; -import com.vaadin.tests.design.DeclarativeTestBase; -import com.vaadin.ui.Tree; -import com.vaadin.ui.Tree.TreeDragMode; - -/** - * Tests the declarative support for implementations of {@link Tree}. - * - * @since 7.4 - * @author Vaadin Ltd - */ -public class TreeDeclarativeTest extends DeclarativeTestBase<Tree> { - - @Test - public void testDragMode() { - String design = "<vaadin-tree drag-mode='node' />"; - - Tree tree = new Tree(); - tree.setDragMode(TreeDragMode.NODE); - - testRead(design, tree); - testWrite(design, tree); - } - - @Test - public void testEmpty() { - testRead("<vaadin-tree />", new Tree()); - testWrite("<vaadin-tree />", new Tree()); - } - - @Test - public void testNodes() { - String design = "<vaadin-tree>" // - + " <node text='Node'/>" // - + " <node text='Parent'>" // - + " <node text='Child'>" // - + " <node text='Grandchild'/>" // - + " </node>" // - + " </node>" // - + " <node text='With icon' icon='http://example.com/icon.png'/>" // - + "</vaadin-tree>"; - - Tree tree = new Tree(); - - tree.addItem("Node"); - - tree.addItem("Parent"); - - tree.addItem("Child"); - tree.setParent("Child", "Parent"); - - tree.addItem("Grandchild"); - tree.setParent("Grandchild", "Child"); - - tree.addItem("With icon"); - tree.setItemIcon("With icon", - new ExternalResource("http://example.com/icon.png")); - - testRead(design, tree); - testWrite(design, tree, true); - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/tree/TreeListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/tree/TreeListenersTest.java deleted file mode 100644 index ec10c4fe39..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/tree/TreeListenersTest.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.vaadin.tests.server.component.tree; - -import org.junit.Test; - -import com.vaadin.event.ItemClickEvent; -import com.vaadin.event.ItemClickEvent.ItemClickListener; -import com.vaadin.tests.server.component.AbstractListenerMethodsTestBase; -import com.vaadin.ui.Tree; -import com.vaadin.ui.Tree.CollapseEvent; -import com.vaadin.ui.Tree.CollapseListener; -import com.vaadin.ui.Tree.ExpandEvent; -import com.vaadin.ui.Tree.ExpandListener; - -public class TreeListenersTest extends AbstractListenerMethodsTestBase { - - @Test - public void testExpandListenerAddGetRemove() throws Exception { - testListenerAddGetRemove(Tree.class, ExpandEvent.class, - ExpandListener.class); - } - - @Test - public void testItemClickListenerAddGetRemove() throws Exception { - testListenerAddGetRemove(Tree.class, ItemClickEvent.class, - ItemClickListener.class); - } - - @Test - public void testCollapseListenerAddGetRemove() throws Exception { - testListenerAddGetRemove(Tree.class, CollapseEvent.class, - CollapseListener.class); - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/tree/TreeTest.java b/server/src/test/java/com/vaadin/tests/server/component/tree/TreeTest.java deleted file mode 100644 index ed455415ea..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/tree/TreeTest.java +++ /dev/null @@ -1,178 +0,0 @@ -package com.vaadin.tests.server.component.tree; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.lang.reflect.Field; -import java.util.HashSet; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import com.vaadin.data.Container; -import com.vaadin.data.util.HierarchicalContainer; -import com.vaadin.data.util.IndexedContainer; -import com.vaadin.shared.ui.tree.TreeState; -import com.vaadin.ui.Tree; - -public class TreeTest { - - private Tree tree; - private Tree tree2; - private Tree tree3; - private Tree tree4; - - @Before - public void setUp() { - tree = new Tree(); - tree.addItem("parent"); - tree.addItem("child"); - tree.setChildrenAllowed("parent", true); - tree.setParent("child", "parent"); - - tree2 = new Tree("Caption"); - tree2.addItem("parent"); - tree2.addItem("child"); - tree2.setChildrenAllowed("parent", true); - tree2.setParent("child", "parent"); - - tree3 = new Tree("Caption", null); - tree3.addItem("parent"); - tree3.addItem("child"); - tree3.setChildrenAllowed("parent", true); - tree3.setParent("child", "parent"); - - tree4 = new Tree("Caption", new IndexedContainer()); - tree4.addItem("parent"); - tree4.addItem("child"); - tree4.setChildrenAllowed("parent", true); - tree4.setParent("child", "parent"); - } - - @Test - public void testRemoveChildren() { - assertTrue(tree.hasChildren("parent")); - tree.removeItem("child"); - assertFalse(tree.hasChildren("parent")); - - assertTrue(tree2.hasChildren("parent")); - tree2.removeItem("child"); - assertFalse(tree2.hasChildren("parent")); - - assertTrue(tree3.hasChildren("parent")); - tree3.removeItem("child"); - assertFalse(tree3.hasChildren("parent")); - - assertTrue(tree4.hasChildren("parent")); - tree4.removeItem("child"); - assertFalse(tree4.hasChildren("parent")); - } - - @Test - public void testContainerTypeIsHierarchical() { - assertTrue(HierarchicalContainer.class - .isAssignableFrom(tree.getContainerDataSource().getClass())); - assertTrue(HierarchicalContainer.class - .isAssignableFrom(tree2.getContainerDataSource().getClass())); - assertTrue(HierarchicalContainer.class - .isAssignableFrom(tree3.getContainerDataSource().getClass())); - assertFalse(HierarchicalContainer.class - .isAssignableFrom(tree4.getContainerDataSource().getClass())); - assertTrue(Container.Hierarchical.class - .isAssignableFrom(tree4.getContainerDataSource().getClass())); - } - - @Test - public void testRemoveExpandedItems() throws Exception { - tree.expandItem("parent"); - tree.expandItem("child"); - - Field expandedField = tree.getClass().getDeclaredField("expanded"); - Field expandedItemIdField = tree.getClass() - .getDeclaredField("expandedItemId"); - - expandedField.setAccessible(true); - expandedItemIdField.setAccessible(true); - - HashSet<Object> expanded = (HashSet<Object>) expandedField.get(tree); - Object expandedItemId = expandedItemIdField.get(tree); - - assertEquals(2, expanded.size()); - assertTrue("Contains parent", expanded.contains("parent")); - assertTrue("Contains child", expanded.contains("child")); - assertEquals("child", expandedItemId); - - tree.removeItem("parent"); - - expanded = (HashSet<Object>) expandedField.get(tree); - expandedItemId = expandedItemIdField.get(tree); - - assertEquals(1, expanded.size()); - assertTrue("Contains child", expanded.contains("child")); - assertEquals("child", expandedItemId); - - tree.removeItem("child"); - - expanded = (HashSet<Object>) expandedField.get(tree); - expandedItemId = expandedItemIdField.get(tree); - - assertEquals(0, expanded.size()); - assertNull(expandedItemId); - } - - @Test - public void testRemoveExpandedItemsOnContainerChange() throws Exception { - tree.expandItem("parent"); - tree.expandItem("child"); - - tree.setContainerDataSource(new HierarchicalContainer()); - - Field expandedField = tree.getClass().getDeclaredField("expanded"); - Field expandedItemIdField = tree.getClass() - .getDeclaredField("expandedItemId"); - - expandedField.setAccessible(true); - expandedItemIdField.setAccessible(true); - - HashSet<Object> expanded = (HashSet<Object>) expandedField.get(tree); - assertEquals(0, expanded.size()); - - Object expandedItemId = expandedItemIdField.get(tree); - assertNull(expandedItemId); - } - - @Test - public void getState_treeHasCustomState() { - TestTree table = new TestTree(); - TreeState state = table.getState(); - Assert.assertEquals("Unexpected state class", TreeState.class, - state.getClass()); - } - - @Test - public void getPrimaryStyleName_treeHasCustomPrimaryStyleName() { - Tree table = new Tree(); - TreeState state = new TreeState(); - Assert.assertEquals("Unexpected primary style name", - state.primaryStyleName, table.getPrimaryStyleName()); - } - - @Test - public void treeStateHasCustomPrimaryStyleName() { - TreeState state = new TreeState(); - Assert.assertEquals("Unexpected primary style name", "v-tree", - state.primaryStyleName); - } - - private static class TestTree extends Tree { - - @Override - public TreeState getState() { - return super.getState(); - } - } - -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/twincolselect/TwinColSelectDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/twincolselect/TwinColSelectDeclarativeTest.java deleted file mode 100644 index 02a2ebfd77..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/twincolselect/TwinColSelectDeclarativeTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.tests.server.component.twincolselect; - -import java.util.Arrays; - -import org.junit.Test; - -import com.vaadin.tests.design.DeclarativeTestBase; -import com.vaadin.ui.TwinColSelect; - -/** - * Test cases for reading the properties of selection components. - * - * @author Vaadin Ltd - */ -public class TwinColSelectDeclarativeTest - extends DeclarativeTestBase<TwinColSelect> { - - public String getBasicDesign() { - return "<vaadin-twin-col-select rows=5 right-column-caption='Selected values' left-column-caption='Unselected values'>\n" - + " <option>First item</option>\n" - + " <option selected>Second item</option>\n" - + " <option selected>Third item</option>\n" - + "</vaadin-twin-col-select>"; - - } - - public TwinColSelect getBasicExpected() { - TwinColSelect s = new TwinColSelect(); - s.setRightColumnCaption("Selected values"); - s.setLeftColumnCaption("Unselected values"); - s.addItem("First item"); - s.addItem("Second item"); - s.addItem("Third item"); - s.setValue(Arrays.asList(new Object[] { "Second item", "Third item" })); - s.setRows(5); - return s; - } - - @Test - public void testReadBasic() { - testRead(getBasicDesign(), getBasicExpected()); - } - - @Test - public void testWriteBasic() { - testWrite(stripOptionTags(getBasicDesign()), getBasicExpected()); - } - - @Test - public void testReadEmpty() { - testRead("<vaadin-twin-col-select />", new TwinColSelect()); - } - - @Test - public void testWriteEmpty() { - testWrite("<vaadin-twin-col-select />", new TwinColSelect()); - } - -}
\ No newline at end of file diff --git a/server/src/test/java/com/vaadin/tests/server/component/twincolselect/TwinColSelectStateTest.java b/server/src/test/java/com/vaadin/tests/server/component/twincolselect/TwinColSelectStateTest.java deleted file mode 100644 index 9348de63c2..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/twincolselect/TwinColSelectStateTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * 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.vaadin.tests.server.component.twincolselect; - -import org.junit.Assert; -import org.junit.Test; - -import com.vaadin.shared.ui.twincolselect.TwinColSelectState; -import com.vaadin.ui.TwinColSelect; - -/** - * Tests for TwinColSelectState. - * - */ -public class TwinColSelectStateTest { - - @Test - public void getState_selectHasCustomState() { - TestTwinColSelect select = new TestTwinColSelect(); - TwinColSelectState state = select.getState(); - Assert.assertEquals("Unexpected state class", TwinColSelectState.class, - state.getClass()); - } - - @Test - public void getPrimaryStyleName_selectHasCustomPrimaryStyleName() { - TwinColSelect table = new TwinColSelect(); - TwinColSelectState state = new TwinColSelectState(); - Assert.assertEquals("Unexpected primary style name", - state.primaryStyleName, table.getPrimaryStyleName()); - } - - @Test - public void selectStateHasCustomPrimaryStyleName() { - TwinColSelectState state = new TwinColSelectState(); - Assert.assertEquals("Unexpected primary style name", "v-select-twincol", - state.primaryStyleName); - } - - private static class TestTwinColSelect extends TwinColSelect { - - @Override - public TwinColSelectState getState() { - return super.getState(); - } - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/componentcontainer/AddRemoveComponentTest.java b/server/src/test/java/com/vaadin/tests/server/componentcontainer/AddRemoveComponentTest.java index f1a83adadc..4662f6f84b 100644 --- a/server/src/test/java/com/vaadin/tests/server/componentcontainer/AddRemoveComponentTest.java +++ b/server/src/test/java/com/vaadin/tests/server/componentcontainer/AddRemoveComponentTest.java @@ -10,7 +10,6 @@ import com.vaadin.ui.ComponentContainer; import com.vaadin.ui.CustomLayout; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; -import com.vaadin.ui.components.colorpicker.ColorPickerPreview; public class AddRemoveComponentTest { @@ -22,7 +21,6 @@ public class AddRemoveComponentTest { // No default constructor, special case containerClasses.remove(CustomLayout.class); - containerClasses.remove(ColorPickerPreview.class); testRemoveComponentFromWrongContainer(new CustomLayout("dummy")); for (Class<? extends ComponentContainer> c : containerClasses) { diff --git a/server/src/test/java/com/vaadin/tests/server/components/ComboBoxValueChangeTest.java b/server/src/test/java/com/vaadin/tests/server/components/ComboBoxValueChangeTest.java deleted file mode 100644 index 66a4ec2370..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/components/ComboBoxValueChangeTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.vaadin.tests.server.components; - -import org.junit.Before; - -import com.vaadin.server.ServerRpcManager; -import com.vaadin.server.ServerRpcMethodInvocation; -import com.vaadin.shared.ui.combobox.ComboBoxServerRpc; -import com.vaadin.ui.ComboBox; -import com.vaadin.v7.ui.LegacyAbstractField; - -/** - * Check that the value change listener for a combo box is triggered exactly - * once when setting the value, at the correct time. - * - * See <a href="http://dev.vaadin.com/ticket/4394">Ticket 4394</a>. - */ -public class ComboBoxValueChangeTest - extends AbstractFieldValueChangeTestBase<Object> { - - @Before - public void setUp() { - ComboBox combo = new ComboBox() { - @Override - public String getConnectorId() { - return "id"; - } - }; - combo.addItem("myvalue"); - super.setUp(combo); - } - - @Override - protected void setValue(LegacyAbstractField<Object> field) { - ComboBox combo = (ComboBox) field; - ServerRpcMethodInvocation invocation = new ServerRpcMethodInvocation( - combo.getConnectorId(), ComboBoxServerRpc.class, - "setSelectedItem", 1); - invocation.setParameters(new Object[] { "myvalue" }); - try { - ServerRpcManager.applyInvocation(combo, invocation); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - -} |