Browse Source

Correct all tests that introspect classpath for Vaadin classes.

Fixes vaadin/framework8-issues#399
RemoveListenersDeprecatedTest test is fixed.
Corrections are made to make the test above passes.

Change-Id: I209a4693d241a1488b69b4742f48549dbf4bf0ac
tags/8.0.0.alpha8
Denis Anisimov 7 years ago
parent
commit
b8e84da2e2
27 changed files with 431 additions and 278 deletions
  1. 5
    2
      compatibility-server/src/main/java/com/vaadin/v7/ui/Grid.java
  2. 2
    0
      compatibility-server/src/test/java/com/vaadin/tests/server/ComponentDesignWriterUtility.java
  3. 3
    2
      compatibility-server/src/test/java/com/vaadin/tests/server/DeprecatedTest.java
  4. 47
    13
      compatibility-server/src/test/java/com/vaadin/v7/tests/VaadinClasses.java
  5. 5
    2
      compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/FieldDefaultValuesTest.java
  6. 6
    0
      server/src/main/java/com/vaadin/event/MethodEventSource.java
  7. 6
    1
      server/src/main/java/com/vaadin/event/SortEvent.java
  8. 8
    2
      server/src/main/java/com/vaadin/navigator/Navigator.java
  9. 6
    0
      server/src/main/java/com/vaadin/server/AbstractClientConnector.java
  10. 11
    9
      server/src/main/java/com/vaadin/server/VaadinPortletSession.java
  11. 3
    9
      server/src/main/java/com/vaadin/server/VaadinService.java
  12. 13
    1
      server/src/main/java/com/vaadin/server/VaadinSession.java
  13. 3
    3
      server/src/main/java/com/vaadin/ui/LoginForm.java
  14. 1
    1
      server/src/main/java/com/vaadin/ui/Slider.java
  15. 2
    2
      server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerHistory.java
  16. 36
    4
      server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerPopup.java
  17. 26
    4
      server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerPreview.java
  18. 13
    0
      server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerSelect.java
  19. 8
    1
      server/src/main/java/com/vaadin/ui/declarative/DesignContext.java
  20. 73
    5
      server/src/test/java/com/vaadin/server/RemoveListenersDeprecatedTest.java
  21. 32
    161
      server/src/test/java/com/vaadin/tests/VaadinClasses.java
  22. 23
    8
      server/src/test/java/com/vaadin/tests/server/ClasspathHelper.java
  23. 13
    8
      server/src/test/java/com/vaadin/tests/server/component/FinalMethodTest.java
  24. 57
    20
      server/src/test/java/com/vaadin/tests/server/component/StateGetDoesNotMarkDirtyTest.java
  25. 20
    3
      server/src/test/java/com/vaadin/tests/server/componentcontainer/AddRemoveComponentTest.java
  26. 9
    2
      shared/src/main/java/com/vaadin/shared/ui/ComponentStateUtil.java
  27. 0
    15
      uitest/src/main/java/com/vaadin/tests/VaadinClasses.java

+ 5
- 2
compatibility-server/src/main/java/com/vaadin/v7/ui/Grid.java View File

import com.vaadin.server.KeyMapper; import com.vaadin.server.KeyMapper;
import com.vaadin.server.VaadinSession; import com.vaadin.server.VaadinSession;
import com.vaadin.shared.MouseEventDetails; import com.vaadin.shared.MouseEventDetails;
import com.vaadin.shared.Registration;
import com.vaadin.shared.data.sort.SortDirection; import com.vaadin.shared.data.sort.SortDirection;
import com.vaadin.shared.util.SharedUtil; import com.vaadin.shared.util.SharedUtil;
import com.vaadin.ui.AbstractFocusable; import com.vaadin.ui.AbstractFocusable;
import com.vaadin.v7.data.util.converter.Converter; import com.vaadin.v7.data.util.converter.Converter;
import com.vaadin.v7.data.util.converter.ConverterUtil; import com.vaadin.v7.data.util.converter.ConverterUtil;
import com.vaadin.v7.event.ItemClickEvent; import com.vaadin.v7.event.ItemClickEvent;
import com.vaadin.v7.event.SelectionEvent;
import com.vaadin.v7.event.ItemClickEvent.ItemClickListener; import com.vaadin.v7.event.ItemClickEvent.ItemClickListener;
import com.vaadin.v7.event.ItemClickEvent.ItemClickNotifier; import com.vaadin.v7.event.ItemClickEvent.ItemClickNotifier;
import com.vaadin.v7.event.SelectionEvent;
import com.vaadin.v7.event.SelectionEvent.SelectionListener; import com.vaadin.v7.event.SelectionEvent.SelectionListener;
import com.vaadin.v7.event.SelectionEvent.SelectionNotifier; import com.vaadin.v7.event.SelectionEvent.SelectionNotifier;
import com.vaadin.v7.server.communication.data.DataGenerator; import com.vaadin.v7.server.communication.data.DataGenerator;
* the sort order change listener to add * the sort order change listener to add
*/ */
@Override @Override
public void addSortListener(SortListener listener) {
public Registration addSortListener(SortListener listener) {
addListener(SortEvent.class, listener, SORT_ORDER_CHANGE_METHOD); addListener(SortEvent.class, listener, SORT_ORDER_CHANGE_METHOD);
return () -> removeListener(SortEvent.class, listener,
SORT_ORDER_CHANGE_METHOD);
} }


/** /**

+ 2
- 0
compatibility-server/src/test/java/com/vaadin/tests/server/ComponentDesignWriterUtility.java View File

"com.vaadin.server.communication.PushAtmosphereHandler$AtmosphereResourceListener"); "com.vaadin.server.communication.PushAtmosphereHandler$AtmosphereResourceListener");
WHITE_LIST_FQNS WHITE_LIST_FQNS
.add("com.vaadin.server.communication.PushAtmosphereHandler"); .add("com.vaadin.server.communication.PushAtmosphereHandler");
WHITE_LIST_FQNS
.add("com.vaadin.server.communication.PushRequestHandler$1");
WHITE_LIST_FQNS WHITE_LIST_FQNS
.add("com.vaadin.server.communication.PushRequestHandler$2"); .add("com.vaadin.server.communication.PushRequestHandler$2");
WHITE_LIST_FQNS.add("com.vaadin.server.LegacyVaadinPortlet"); WHITE_LIST_FQNS.add("com.vaadin.server.LegacyVaadinPortlet");

+ 3
- 2
compatibility-server/src/test/java/com/vaadin/tests/server/DeprecatedTest.java View File



File testRoot = new File(DeprecatedTest.class.getResource("/").toURI()); File testRoot = new File(DeprecatedTest.class.getResource("/").toURI());


new ClasspathHelper(fqn -> false)
new ClasspathHelper()
.getVaadinClassesFromClasspath( .getVaadinClassesFromClasspath(
entry -> entry.contains("compatibility-server") entry -> entry.contains("compatibility-server")
&& !testRoot.equals(new File(entry))) && !testRoot.equals(new File(entry)))
+ " is in compatability package and it's not deprecated", + " is in compatability package and it's not deprecated",
cls.getAnnotation(Deprecated.class)); cls.getAnnotation(Deprecated.class));
}); });
Assert.assertNotEquals("Total number of checked classes", 0, count.get());
Assert.assertNotEquals("Total number of checked classes", 0,
count.get());
} }


} }

+ 47
- 13
compatibility-server/src/test/java/com/vaadin/v7/tests/VaadinClasses.java View File

package com.vaadin.v7.tests; package com.vaadin.v7.tests;


import java.io.IOException;
import java.io.File;
import java.lang.reflect.Modifier;
import java.net.URISyntaxException;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;


import com.vaadin.tests.server.ClasspathHelper;
import com.vaadin.ui.Component; import com.vaadin.ui.Component;
import com.vaadin.v7.ui.Field; import com.vaadin.v7.ui.Field;


@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public class VaadinClasses { public class VaadinClasses {


private static final Set<String> WHITE_LIST_FQNS = new HashSet<>();

public static List<Class<? extends Field>> getFields() { public static List<Class<? extends Field>> getFields() {
return getServerClasses(Field.class::isAssignableFrom)
.map(VaadinClasses::castFieldClass)
.collect(Collectors.toList());
}

public static Stream<Class<?>> getServerClasses(
Predicate<? super Class<?>> predicate) {
try { try {
return com.vaadin.tests.VaadinClasses.findClasses(Field.class,
"com.vaadin.v7.ui");
} catch (IOException e) {
e.printStackTrace();
return null;
File testRoot = new File(com.vaadin.tests.VaadinClasses.class
.getResource("/").toURI());
File compatibilityTestRoot = new File(
VaadinClasses.class.getResource("/").toURI());
ClasspathHelper helper = new ClasspathHelper(
fqn -> !fqn.startsWith("com.vaadin.v7.ui"));
return helper.getVaadinClassesFromClasspath(
entry -> !compatibilityTestRoot.equals(new File(entry))
&& !testRoot.equals(new File(entry)),
cls -> predicate.test(cls) && !cls.isInterface()
&& !Modifier.isAbstract(cls.getModifiers()));
} catch (URISyntaxException e) {
throw new RuntimeException(e);
} }
} }


public static List<Class<? extends Component>> getComponents() { public static List<Class<? extends Component>> getComponents() {
try {
return com.vaadin.tests.VaadinClasses.findClasses(Component.class,
"com.vaadin.v7.ui");
} catch (IOException e) {
throw new RuntimeException(
"Could not find all Vaadin component classes", e);
}
return getServerClasses(Component.class::isAssignableFrom)
.map(VaadinClasses::castComponentClass)
.collect(Collectors.toList());
}

private static Class<? extends Field> castFieldClass(Class<?> clazz) {
return (Class<? extends Field>) clazz;
}

private static Class<? extends Component> castComponentClass(
Class<?> clazz) {
return (Class<? extends Component>) clazz;
}

protected static Set<String> getWhiteListFqns() {
return WHITE_LIST_FQNS;
} }
} }

+ 5
- 2
compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/FieldDefaultValuesTest.java View File

import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;


import com.vaadin.ui.Slider;
import com.vaadin.v7.tests.VaadinClasses; import com.vaadin.v7.tests.VaadinClasses;
import com.vaadin.v7.ui.Field; import com.vaadin.v7.ui.Field;
import com.vaadin.v7.ui.Slider;


public class FieldDefaultValuesTest { public class FieldDefaultValuesTest {




@Test @Test
public void testFieldsAreEmptyAfterClear() throws Exception { public void testFieldsAreEmptyAfterClear() throws Exception {
int count = 0;
for (Field<?> field : createFields()) { for (Field<?> field : createFields()) {
count++;
field.clear(); field.clear();


if (field instanceof Slider) { if (field instanceof Slider) {
field.isEmpty()); field.isEmpty());
} }
} }
Assert.assertTrue(count > 0);
} }


@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
private static List<Field<?>> createFields() private static List<Field<?>> createFields()
throws InstantiationException, IllegalAccessException { throws InstantiationException, IllegalAccessException {
List<Field<?>> fieldInstances = new ArrayList<Field<?>>();
List<Field<?>> fieldInstances = new ArrayList<>();


for (Class<? extends Field> fieldType : VaadinClasses.getFields()) { for (Class<? extends Field> fieldType : VaadinClasses.getFields()) {
fieldInstances.add(fieldType.newInstance()); fieldInstances.add(fieldType.newInstance());

+ 6
- 0
server/src/main/java/com/vaadin/event/MethodEventSource.java View File

* @param method * @param method
* the method owned by the target that's registered to listen to * the method owned by the target that's registered to listen to
* events of type eventType. * events of type eventType.
* @deprecated use a {@link Registration} returned by
* {@link #addListener(Class, Object, Method)}
*/ */
@Deprecated
public void removeListener(Class<?> eventType, Object target, public void removeListener(Class<?> eventType, Object target,
Method method); Method method);


* @param methodName * @param methodName
* the name of the method owned by <code>target</code> that's * the name of the method owned by <code>target</code> that's
* registered to listen to events of type <code>eventType</code>. * registered to listen to events of type <code>eventType</code>.
* @deprecated use a {@link Registration} returned by
* {@link #addListener(Class, Object, String)}
*/ */
@Deprecated
public void removeListener(Class<?> eventType, Object target, public void removeListener(Class<?> eventType, Object target,
String methodName); String methodName);
} }

+ 6
- 1
server/src/main/java/com/vaadin/event/SortEvent.java View File

import java.util.List; import java.util.List;


import com.vaadin.data.sort.SortOrder; import com.vaadin.data.sort.SortOrder;
import com.vaadin.shared.Registration;
import com.vaadin.ui.Component; import com.vaadin.ui.Component;


/** /**
* *
* @param listener * @param listener
* the sort order change listener to add * the sort order change listener to add
* @return a registration object for removing the listener
*/ */
public void addSortListener(SortListener listener);
public Registration addSortListener(SortListener listener);


/** /**
* Removes a sort order change listener previously added using * Removes a sort order change listener previously added using
* *
* @param listener * @param listener
* the sort order change listener to remove * the sort order change listener to remove
* @deprecated use a {@link Registration} returned by
* {@link #addSortListener(SortListener)}
*/ */
@Deprecated
public void removeSortListener(SortListener listener); public void removeSortListener(SortListener listener);
} }
} }

+ 8
- 2
server/src/main/java/com/vaadin/navigator/Navigator.java View File

import com.vaadin.server.Page; import com.vaadin.server.Page;
import com.vaadin.server.Page.UriFragmentChangedEvent; import com.vaadin.server.Page.UriFragmentChangedEvent;
import com.vaadin.server.Page.UriFragmentChangedListener; import com.vaadin.server.Page.UriFragmentChangedListener;
import com.vaadin.shared.Registration;
import com.vaadin.shared.util.SharedUtil; import com.vaadin.shared.util.SharedUtil;
import com.vaadin.ui.Component; import com.vaadin.ui.Component;
import com.vaadin.ui.ComponentContainer; import com.vaadin.ui.ComponentContainer;
throw new RuntimeException(e); throw new RuntimeException(e);
} }
// TODO error handling // TODO error handling
} }
return null; return null;
} }
* @param listener * @param listener
* Listener to invoke during a view change. * Listener to invoke during a view change.
*/ */
public void addViewChangeListener(ViewChangeListener listener) {
public Registration addViewChangeListener(ViewChangeListener listener) {
listeners.add(listener); listeners.add(listener);
return () -> listeners.remove(listener);
} }


/** /**
* *
* @param listener * @param listener
* Listener to remove. * Listener to remove.
* @deprecated use a {@link Registration} object returned by
* {@link #addViewChangeListener(ViewChangeListener)} to remove
* a listener
*/ */
@Deprecated
public void removeViewChangeListener(ViewChangeListener listener) { public void removeViewChangeListener(ViewChangeListener listener) {
listeners.remove(listener); listeners.remove(listener);
} }

+ 6
- 0
server/src/main/java/com/vaadin/server/AbstractClientConnector.java View File

} }


@Override @Override
@Deprecated
public void removeAttachListener(AttachListener listener) { public void removeAttachListener(AttachListener listener) {
removeListener(AttachEvent.ATTACH_EVENT_IDENTIFIER, AttachEvent.class, removeListener(AttachEvent.ATTACH_EVENT_IDENTIFIER, AttachEvent.class,
listener); listener);
} }


@Override @Override
@Deprecated
public void removeDetachListener(DetachListener listener) { public void removeDetachListener(DetachListener listener) {
removeListener(DetachEvent.DETACH_EVENT_IDENTIFIER, DetachEvent.class, removeListener(DetachEvent.DETACH_EVENT_IDENTIFIER, DetachEvent.class,
listener); listener);
* @param method * @param method
* the method owned by <code>target</code> that's registered to * the method owned by <code>target</code> that's registered to
* listen to events of type <code>eventType</code>. * listen to events of type <code>eventType</code>.
* @deprecated use a {@link Registration} from
* {@link #addListener(Class, Object, Method)} to remove a
* listener
*/ */
@Override @Override
@Deprecated
public void removeListener(Class<?> eventType, Object target, public void removeListener(Class<?> eventType, Object target,
Method method) { Method method) {
if (eventRouter != null) { if (eventRouter != null) {

+ 11
- 9
server/src/main/java/com/vaadin/server/VaadinPortletSession.java View File

import javax.xml.namespace.QName; import javax.xml.namespace.QName;


import com.vaadin.server.communication.PortletListenerNotifier; import com.vaadin.server.communication.PortletListenerNotifier;
import com.vaadin.shared.Registration;
import com.vaadin.ui.UI; import com.vaadin.ui.UI;
import com.vaadin.util.CurrentInstance; import com.vaadin.util.CurrentInstance;


* @param listener * @param listener
* to add * to add
*/ */
public void addPortletListener(PortletListener listener) {
public Registration addPortletListener(PortletListener listener) {
portletListeners.add(listener); portletListeners.add(listener);
return () -> portletListeners.remove(listener);
} }


/** /**
* *
* @param listener * @param listener
* to remove * to remove
* @deprecated Use a {@link Registration} object returned by
* {@link #addPortletListener(PortletListener)} to remove a
* listener
*/ */
@Deprecated
public void removePortletListener(PortletListener listener) { public void removePortletListener(PortletListener listener) {
portletListeners.remove(listener); portletListeners.remove(listener);
} }
*/ */
public void firePortletRenderRequest(UI uI, RenderRequest request, public void firePortletRenderRequest(UI uI, RenderRequest request,
RenderResponse response) { RenderResponse response) {
for (PortletListener l : new ArrayList<>(
portletListeners)) {
for (PortletListener l : new ArrayList<>(portletListeners)) {
l.handleRenderRequest(request, l.handleRenderRequest(request,
new RestrictedRenderResponse(response), uI); new RestrictedRenderResponse(response), uI);
} }
sharedParameterActionValueMap.remove(key); sharedParameterActionValueMap.remove(key);
} else { } else {
// normal action request, notify listeners // normal action request, notify listeners
for (PortletListener l : new ArrayList<>(
portletListeners)) {
for (PortletListener l : new ArrayList<>(portletListeners)) {
l.handleActionRequest(request, response, uI); l.handleActionRequest(request, response, uI);
} }
} }
*/ */
public void firePortletEventRequest(UI uI, EventRequest request, public void firePortletEventRequest(UI uI, EventRequest request,
EventResponse response) { EventResponse response) {
for (PortletListener l : new ArrayList<>(
portletListeners)) {
for (PortletListener l : new ArrayList<>(portletListeners)) {
l.handleEventRequest(request, response, uI); l.handleEventRequest(request, response, uI);
} }
} }
*/ */
public void firePortletResourceRequest(UI uI, ResourceRequest request, public void firePortletResourceRequest(UI uI, ResourceRequest request,
ResourceResponse response) { ResourceResponse response) {
for (PortletListener l : new ArrayList<>(
portletListeners)) {
for (PortletListener l : new ArrayList<>(portletListeners)) {
l.handleResourceRequest(request, response, uI); l.handleResourceRequest(request, response, uI);
} }
} }

+ 3
- 9
server/src/main/java/com/vaadin/server/VaadinService.java View File

* @return a registration object for removing the listener * @return a registration object for removing the listener
*/ */
public Registration addSessionInitListener(SessionInitListener listener) { public Registration addSessionInitListener(SessionInitListener listener) {
eventRouter.addListener(SessionInitEvent.class, listener,
return eventRouter.addListener(SessionInitEvent.class, listener,
SESSION_INIT_METHOD); SESSION_INIT_METHOD);
return () -> eventRouter.removeListener(SessionInitEvent.class,
listener, SESSION_INIT_METHOD);
} }


/** /**
*/ */
public Registration addSessionDestroyListener( public Registration addSessionDestroyListener(
SessionDestroyListener listener) { SessionDestroyListener listener) {
eventRouter.addListener(SessionDestroyEvent.class, listener,
return eventRouter.addListener(SessionDestroyEvent.class, listener,
SESSION_DESTROY_METHOD); SESSION_DESTROY_METHOD);
return () -> eventRouter.removeListener(SessionInitEvent.class,
listener, SESSION_DESTROY_METHOD);
} }


/** /**
*/ */
public Registration addServiceDestroyListener( public Registration addServiceDestroyListener(
ServiceDestroyListener listener) { ServiceDestroyListener listener) {
eventRouter.addListener(ServiceDestroyEvent.class, listener,
return eventRouter.addListener(ServiceDestroyEvent.class, listener,
SERVICE_DESTROY_METHOD); SERVICE_DESTROY_METHOD);
return () -> eventRouter.removeListener(ServiceDestroyEvent.class,
listener, SERVICE_DESTROY_METHOD);
} }


/** /**

+ 13
- 1
server/src/main/java/com/vaadin/server/VaadinSession.java View File

import javax.servlet.http.HttpSessionBindingListener; import javax.servlet.http.HttpSessionBindingListener;


import com.vaadin.event.EventRouter; import com.vaadin.event.EventRouter;
import com.vaadin.shared.Registration;
import com.vaadin.shared.communication.PushMode; import com.vaadin.shared.communication.PushMode;
import com.vaadin.ui.UI; import com.vaadin.ui.UI;
import com.vaadin.util.CurrentInstance; import com.vaadin.util.CurrentInstance;
* *
* @param listener * @param listener
* the bootstrap listener to add * the bootstrap listener to add
* @return a registration object for removing the listener
*/ */
public void addBootstrapListener(BootstrapListener listener) {
public Registration addBootstrapListener(BootstrapListener listener) {
assert hasLock(); assert hasLock();
eventRouter.addListener(BootstrapFragmentResponse.class, listener, eventRouter.addListener(BootstrapFragmentResponse.class, listener,
BOOTSTRAP_FRAGMENT_METHOD); BOOTSTRAP_FRAGMENT_METHOD);
eventRouter.addListener(BootstrapPageResponse.class, listener, eventRouter.addListener(BootstrapPageResponse.class, listener,
BOOTSTRAP_PAGE_METHOD); BOOTSTRAP_PAGE_METHOD);
return () -> {
eventRouter.removeListener(BootstrapFragmentResponse.class,
listener, BOOTSTRAP_FRAGMENT_METHOD);
eventRouter.removeListener(BootstrapPageResponse.class, listener,
BOOTSTRAP_PAGE_METHOD);
};
} }


/** /**
* *
* @param listener * @param listener
* the bootstrap listener to remove * the bootstrap listener to remove
* @deprecated Use a {@link Registration} object returned by
* {@link #addBootstrapListener(BootstrapListener)} to remove a
* listener
*/ */
@Deprecated
public void removeBootstrapListener(BootstrapListener listener) { public void removeBootstrapListener(BootstrapListener listener) {
assert hasLock(); assert hasLock();
eventRouter.removeListener(BootstrapFragmentResponse.class, listener, eventRouter.removeListener(BootstrapFragmentResponse.class, listener,

+ 3
- 3
server/src/main/java/com/vaadin/ui/LoginForm.java View File



private TextField getUsernameField() { private TextField getUsernameField() {
assert initialized; assert initialized;
return (TextField) getState().userNameFieldConnector;
return (TextField) getState(false).userNameFieldConnector;
} }


private PasswordField getPasswordField() { private PasswordField getPasswordField() {
assert initialized; assert initialized;
return (PasswordField) getState().passwordFieldConnector;
return (PasswordField) getState(false).passwordFieldConnector;
} }


private Button getLoginButton() { private Button getLoginButton() {
assert initialized; assert initialized;
return (Button) getState().loginButtonConnector;
return (Button) getState(false).loginButtonConnector;
} }


/** /**

+ 1
- 1
server/src/main/java/com/vaadin/ui/Slider.java View File



@Override @Override
public Double getValue() { public Double getValue() {
return getState().value;
return getState(false).value;
} }


@Override @Override

+ 2
- 2
server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerHistory.java View File

ColorPickerGrid grid = new ColorPickerGrid(ROWS, COLUMNS); ColorPickerGrid grid = new ColorPickerGrid(ROWS, COLUMNS);
grid.setWidth("100%"); grid.setWidth("100%");
grid.setPosition(0, 0); grid.setPosition(0, 0);
grid.addValueChangeListener(event -> fireEvent(new ValueChangeEvent<>(this,
event.isUserOriginated())));
grid.addValueChangeListener(event -> fireEvent(
new ValueChangeEvent<>(this, event.isUserOriginated())));


return grid; return grid;
} }

+ 36
- 4
server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerPopup.java View File

import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import com.vaadin.ui.Button; import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Component; import com.vaadin.ui.Component;
import com.vaadin.ui.HasComponents;
import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Layout; import com.vaadin.ui.Layout;
import com.vaadin.ui.Slider; import com.vaadin.ui.Slider;
/** The selectors. */ /** The selectors. */
private final Set<HasValue<Color>> selectors = new HashSet<>(); private final Set<HasValue<Color>> selectors = new HashSet<>();


private boolean readOnly;

private boolean required;

/** /**
* Set true while the slider values are updated after colorChange. When * Set true while the slider values are updated after colorChange. When
* true, valueChange reactions from the sliders are disabled, because * true, valueChange reactions from the sliders are disabled, because
selPreview = new ColorPickerPreview(selectedColor); selPreview = new ColorPickerPreview(selectedColor);
selPreview.setWidth("100%"); selPreview.setWidth("100%");
selPreview.setHeight("20px"); selPreview.setHeight("20px");
selPreview.setRequiredIndicatorVisible(required);
selPreview.addValueChangeListener(this::colorChanged); selPreview.addValueChangeListener(this::colorChanged);
selectors.add(selPreview); selectors.add(selPreview);




@Override @Override
public void setRequiredIndicatorVisible(boolean visible) { public void setRequiredIndicatorVisible(boolean visible) {
super.setRequiredIndicatorVisible(visible);
required = visible;
if (selPreview != null) {
selPreview.setRequiredIndicatorVisible(required);
}
} }


@Override @Override
public boolean isRequiredIndicatorVisible() { public boolean isRequiredIndicatorVisible() {
return super.isRequiredIndicatorVisible();
return required;
} }


private static Logger getLogger() { private static Logger getLogger() {


@Override @Override
public void setReadOnly(boolean readOnly) { public void setReadOnly(boolean readOnly) {
super.setReadOnly(readOnly);
this.readOnly = readOnly;
updateColorComponents();
} }


@Override @Override
public boolean isReadOnly() { public boolean isReadOnly() {
return super.isReadOnly();
return readOnly;
}

private void updateColorComponents() {
if (getContent() != null) {
updateColorComponents(getContent());
}
}

private void updateColorComponents(Component component) {
if (component instanceof HasValue<?>) {
((HasValue<?>) component).setReadOnly(isReadOnly());
((HasValue<?>) component)
.setRequiredIndicatorVisible(isRequiredIndicatorVisible());
}
if (component instanceof HasComponents) {
Iterator<Component> iterator = ((HasComponents) component)
.iterator();
while (iterator.hasNext()) {
updateColorComponents(iterator.next());
}
}
} }
} }

+ 26
- 4
server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerPreview.java View File

*/ */
package com.vaadin.ui.components.colorpicker; package com.vaadin.ui.components.colorpicker;


import java.util.Iterator;
import java.util.Objects; import java.util.Objects;


import com.vaadin.data.HasValue; import com.vaadin.data.HasValue;
import com.vaadin.shared.ui.colorpicker.Color; import com.vaadin.shared.ui.colorpicker.Color;
import com.vaadin.ui.Component; import com.vaadin.ui.Component;
import com.vaadin.ui.CssLayout; import com.vaadin.ui.CssLayout;
import com.vaadin.ui.HasComponents;
import com.vaadin.ui.TextField; import com.vaadin.ui.TextField;


/** /**
private String oldValue; private String oldValue;
private Registration valueChangeListenerRegistration = null; private Registration valueChangeListenerRegistration = null;


private boolean readOnly;

private ColorPickerPreview() { private ColorPickerPreview() {
setStyleName("v-colorpicker-preview"); setStyleName("v-colorpicker-preview");
field = new TextField(); field = new TextField();


@Override @Override
public void setRequiredIndicatorVisible(boolean visible) { public void setRequiredIndicatorVisible(boolean visible) {
super.setRequiredIndicatorVisible(visible);
field.setRequiredIndicatorVisible(visible);
} }


@Override @Override
public boolean isRequiredIndicatorVisible() { public boolean isRequiredIndicatorVisible() {
return super.isRequiredIndicatorVisible();
return field.isRequiredIndicatorVisible();
} }


@Override @Override
public void setReadOnly(boolean readOnly) { public void setReadOnly(boolean readOnly) {
super.setReadOnly(readOnly);
this.readOnly = readOnly;
updateColorComponents();
} }


@Override @Override
public boolean isReadOnly() { public boolean isReadOnly() {
return super.isReadOnly();
return readOnly;
}

private void updateColorComponents() {
iterator().forEachRemaining(this::updateColorComponents);
}

private void updateColorComponents(Component component) {
if (component instanceof HasValue<?>) {
((HasValue<?>) component).setReadOnly(isReadOnly());
}
if (component instanceof HasComponents) {
Iterator<Component> iterator = ((HasComponents) component)
.iterator();
while (iterator.hasNext()) {
updateColorComponents(iterator.next());
}
}
} }
} }

+ 13
- 0
server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerSelect.java View File

} }
} }


/**
* Returns the selected value.
* <p>
* Value can be {@code null} if component is not yet initialized via
* {@link #initContent()}
*
* @see ColorPickerSelect#initContent()
*
* @return the selected color, may be {@code null}
*/
@Override @Override
public Color getValue() { public Color getValue() {
if (grid == null) {
return null;
}
return grid.getValue(); return grid.getValue();
} }



+ 8
- 1
server/src/main/java/com/vaadin/ui/declarative/DesignContext.java View File

import com.vaadin.server.Constants; import com.vaadin.server.Constants;
import com.vaadin.server.DeploymentConfiguration; import com.vaadin.server.DeploymentConfiguration;
import com.vaadin.server.VaadinService; import com.vaadin.server.VaadinService;
import com.vaadin.shared.Registration;
import com.vaadin.ui.Component; import com.vaadin.ui.Component;
import com.vaadin.ui.HasComponents; import com.vaadin.ui.HasComponents;
import com.vaadin.ui.declarative.Design.ComponentFactory; import com.vaadin.ui.declarative.Design.ComponentFactory;
* *
* @param listener * @param listener
* the component creation listener to be added * the component creation listener to be added
* @return a registration object for removing the listener
*/ */
public void addComponentCreationListener(
public Registration addComponentCreationListener(
ComponentCreationListener listener) { ComponentCreationListener listener) {
listeners.add(listener); listeners.add(listener);
return () -> listeners.remove(listener);
} }


/** /**
* *
* @param listener * @param listener
* the component creation listener to be removed * the component creation listener to be removed
* @deprecated Use a {@link Registration} object returned by
* {@link #addComponentCreationListener(ComponentCreationListener)}
* a listener
*/ */
@Deprecated
public void removeComponentCreationListener( public void removeComponentCreationListener(
ComponentCreationListener listener) { ComponentCreationListener listener) {
listeners.remove(listener); listeners.remove(listener);

+ 73
- 5
server/src/test/java/com/vaadin/server/RemoveListenersDeprecatedTest.java View File

package com.vaadin.server; package com.vaadin.server;


import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.regex.Pattern; import java.util.regex.Pattern;


import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;


import com.vaadin.event.EventRouter;
import com.vaadin.event.MethodEventSource;
import com.vaadin.server.data.AbstractDataProvider;
import com.vaadin.shared.Registration;
import com.vaadin.tests.VaadinClasses; import com.vaadin.tests.VaadinClasses;


public class RemoveListenersDeprecatedTest { public class RemoveListenersDeprecatedTest {


private static final List<Predicate<Method>> ALLOW_REMOVE_LISTENER = new ArrayList<>();

static {
ALLOW_REMOVE_LISTENER.add(
RemoveListenersDeprecatedTest::acceptAbstarctClientConnectorRemoveMethods);
ALLOW_REMOVE_LISTENER
.add(RemoveListenersDeprecatedTest::acceptAbstractDataProvider);
ALLOW_REMOVE_LISTENER
.add(RemoveListenersDeprecatedTest::acceptMethodEventSource);
}

@Test @Test
public void allRemoveListenerMethodsMarkedAsDeprecated() { public void allRemoveListenerMethodsMarkedAsDeprecated() {
Pattern methodPattern = Pattern.compile("remove.*Listener");
Pattern removePattern = Pattern.compile("remove.*Listener");
Pattern addPattern = Pattern.compile("add.*Listener");
int count = 0;
for (Class<? extends Object> serverClass : VaadinClasses for (Class<? extends Object> serverClass : VaadinClasses
.getComponents()) {
for (Method method : serverClass.getMethods()) {
if (methodPattern.matcher(method.getName()).matches()) {
.getAllServerSideClasses()) {
count++;
if (serverClass.equals(EventRouter.class)) {
continue;
}
for (Method method : serverClass.getDeclaredMethods()) {
if (Modifier.isPrivate(method.getModifiers())) {
continue;
}
if (addPattern.matcher(method.getName()).matches()
&& method.getAnnotation(Deprecated.class) == null) {
Class<?> returnType = method.getReturnType();
Assert.assertEquals(
"Method " + method.getName()
+ " is not deprectated in class "
+ serverClass.getName()
+ " and doesn't return a Registration object",
Registration.class, returnType);
}
if (ALLOW_REMOVE_LISTENER.stream()
.anyMatch(predicate -> predicate.test(method))) {
continue;
}

if (removePattern.matcher(method.getName()).matches()) {
Assert.assertNotNull( Assert.assertNotNull(
"Method " + method.getName() + " in class " "Method " + method.getName() + " in class "
+ serverClass.getSimpleName()
+ serverClass.getName()
+ " has not been marked as deprecated.", + " has not been marked as deprecated.",
method.getAnnotation(Deprecated.class)); method.getAnnotation(Deprecated.class));
} }
} }
} }
Assert.assertTrue(count > 0);
}

private static boolean acceptMethodEventSource(Method method) {
return method.getDeclaringClass().equals(MethodEventSource.class)
&& method.getParameterCount() == 2;
}

private static boolean acceptAbstarctClientConnectorRemoveMethods(
Method method) {
if (method.getDeclaringClass().equals(AbstractClientConnector.class)) {
if (method.getParameterCount() == 2) {
return true;
} else if (method.getParameterCount() == 0) {
return false;
} else {
return method.getParameterTypes()[0].equals(String.class);
}
}
return false;
}

private static boolean acceptAbstractDataProvider(Method method) {
return method.getDeclaringClass().equals(AbstractDataProvider.class)
&& method.getParameterCount() == 2;
} }
} }

+ 32
- 161
server/src/test/java/com/vaadin/tests/VaadinClasses.java View File

package com.vaadin.tests; package com.vaadin.tests;


import java.io.File; import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.JarURLConnection;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.List; import java.util.List;
import java.util.jar.JarEntry;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;


import org.junit.Test;

import com.vaadin.server.VaadinSession;
import com.vaadin.tests.server.ClasspathHelper;
import com.vaadin.ui.Component; import com.vaadin.ui.Component;
import com.vaadin.ui.ComponentContainer; import com.vaadin.ui.ComponentContainer;
import com.vaadin.ui.CustomComponent; import com.vaadin.ui.CustomComponent;
} }


public static List<Class<? extends Component>> getComponents() { public static List<Class<? extends Component>> getComponents() {
try {
return findClasses(Component.class, "com.vaadin.ui");
} catch (IOException e) {
e.printStackTrace();
return null;
}
return getServerClasses(Component.class::isAssignableFrom)
.map(VaadinClasses::castComponentClass)
.collect(Collectors.toList());
} }


public static List<Class<? extends Object>> getThemeClasses() { public static List<Class<? extends Object>> getThemeClasses() {
try {
return findClasses(Object.class, "com.vaadin.ui.themes");
} catch (IOException e) {
e.printStackTrace();
return null;
}
return getServerClasses(clazz -> clazz.getPackage().getName()
.equals("com.vaadin.ui.themes")).collect(Collectors.toList());
} }


public static List<Class<? extends Object>> getAllServerSideClasses() { public static List<Class<? extends Object>> getAllServerSideClasses() {
try {
return findClassesNoTests(Object.class, "com.vaadin",
new String[] { "com.vaadin.tests", "com.vaadin.client" });
} catch (IOException e) {
e.printStackTrace();
return null;
}
return getServerClasses(clazz -> true).collect(Collectors.toList());
} }


public static List<Class<? extends ComponentContainer>> getComponentContainers() { public static List<Class<? extends ComponentContainer>> getComponentContainers() {
try {
return findClasses(ComponentContainer.class, "com.vaadin.ui");
} catch (IOException e) {
e.printStackTrace();
return null;
}
return getServerClasses(ComponentContainer.class::isAssignableFrom)
.filter(clazz -> clazz.getPackage().getName()
.startsWith("com.vaadin.ui"))
.map(VaadinClasses::castContainerClass)
.collect(Collectors.toList());
} }


public static List<Class<? extends ComponentContainer>> getComponentContainersSupportingAddRemoveComponent() { public static List<Class<? extends ComponentContainer>> getComponentContainersSupportingAddRemoveComponent() {
return classes; return classes;
} }


@SuppressWarnings({ "unchecked", "rawtypes" })
public static List<Class<?>> getBasicComponentTests() {
public static Stream<Class<?>> getServerClasses(
Predicate<? super Class<?>> predicate) {
try { try {
// Given as name to avoid dependencies on testbench source folder
return (List) findClasses(
Class.forName(
"com.vaadin.tests.components.AbstractComponentTest"),
"com.vaadin.tests.components");
} catch (Exception e) {
e.printStackTrace();
return null;
File testRoot = new File(
VaadinClasses.class.getResource("/").toURI());
ClasspathHelper helper = new ClasspathHelper();
return helper
.getVaadinClassesFromClasspath(
entry -> !testRoot.equals(new File(entry)))
.filter(predicate);
} catch (URISyntaxException e) {
throw new RuntimeException(e);
} }

}

public static <T> List<Class<? extends T>> findClasses(Class<T> baseClass,
String basePackage) throws IOException {
return findClasses(baseClass, basePackage, new String[] {});
} }


private static <T> List<Class<? extends T>> findClasses(Class<T> baseClass,
String basePackage, String[] ignoredPackages) throws IOException {
List<Class<? extends T>> classes = new ArrayList<>();
String basePackageDirName = "/" + basePackage.replace('.', '/');
URL location = VaadinSession.class.getResource(basePackageDirName);
if (location.getProtocol().equals("file")) {
try {
File f = new File(location.toURI());
if (!f.exists()) {
throw new IOException(
"Directory " + f.toString() + " does not exist");
}
findPackages(f, basePackage, baseClass, classes,
ignoredPackages);
} catch (URISyntaxException e) {
throw new IOException(e.getMessage());
}
} else if (location.getProtocol().equals("jar")) {
JarURLConnection juc = (JarURLConnection) location.openConnection();
findPackages(juc, basePackage, baseClass, classes);
}

Collections.sort(classes, (Class<? extends T> o1, Class<? extends T> o2) -> o1.getName().compareTo(o2.getName()));
return classes;
private static Class<? extends Component> castComponentClass(
Class<?> clazz) {
return (Class<? extends Component>) clazz;
} }


private static <T> List<Class<? extends T>> findClassesNoTests(
Class<T> baseClass, String basePackage, String[] ignoredPackages)
throws IOException {
List<Class<? extends T>> classes = findClasses(baseClass, basePackage,
ignoredPackages);
List<Class<? extends T>> classesNoTests = new ArrayList<>();
for (Class<? extends T> clazz : classes) {
if (!clazz.getName().contains("Test")) {
boolean testPresent = false;
for (Method method : clazz.getMethods()) {
if (method.isAnnotationPresent(Test.class)) {
testPresent = true;
break;
}
}
if (!testPresent) {
classesNoTests.add(clazz);
}
}
}
return classesNoTests;
}

private static <T> void findPackages(JarURLConnection juc,
String javaPackage, Class<T> baseClass,
Collection<Class<? extends T>> result) throws IOException {
String prefix = "com/vaadin/ui";
Enumeration<JarEntry> ent = juc.getJarFile().entries();
while (ent.hasMoreElements()) {
JarEntry e = ent.nextElement();
if (e.getName().endsWith(".class")
&& e.getName().startsWith(prefix)) {
String fullyQualifiedClassName = e.getName().replace('/', '.')
.replace(".class", "");
addClassIfMatches(result, fullyQualifiedClassName, baseClass);
}
}
}

private static <T> void findPackages(File parent, String javaPackage,
Class<T> baseClass, Collection<Class<? extends T>> result,
String[] ignoredPackages) {
for (String ignoredPackage : ignoredPackages) {
if (javaPackage.equals(ignoredPackage)) {
return;
}
}

for (File file : parent.listFiles()) {
if (file.isDirectory()) {
findPackages(file, javaPackage + "." + file.getName(),
baseClass, result, ignoredPackages);
} else if (file.getName().endsWith(".class")) {
String fullyQualifiedClassName = javaPackage + "."
+ file.getName().replace(".class", "");
addClassIfMatches(result, fullyQualifiedClassName, baseClass);
}
}

}

@SuppressWarnings("unchecked")
private static <T> void addClassIfMatches(
Collection<Class<? extends T>> result,
String fullyQualifiedClassName, Class<T> baseClass) {
try {
// Try to load the class

Class<?> c = Class.forName(fullyQualifiedClassName);
if (baseClass.isAssignableFrom(c)
&& !Modifier.isAbstract(c.getModifiers())
&& !c.isAnonymousClass() && !c.isMemberClass()
&& !c.isLocalClass()) {
result.add((Class<? extends T>) c);
}
} catch (Exception e) {
// Could ignore that class cannot be loaded
e.printStackTrace();
} catch (LinkageError e) {
// Ignore. Client side classes will at least throw LinkageErrors
}

private static Class<? extends ComponentContainer> castContainerClass(
Class<?> clazz) {
return (Class<? extends ComponentContainer>) clazz;
} }
} }

compatibility-server/src/test/java/com/vaadin/tests/server/ClasspathHelper.java → server/src/test/java/com/vaadin/tests/server/ClasspathHelper.java View File

import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.net.URI; import java.net.URI;
import java.nio.file.FileSystem;
import java.nio.file.FileSystemNotFoundException;
import java.nio.file.FileSystems; import java.nio.file.FileSystems;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
* @author Vaadin Ltd * @author Vaadin Ltd
* *
*/ */
class ClasspathHelper {
public class ClasspathHelper {


public static final String COM_VAADIN_FILE_PREFIX = "com" + File.separatorChar + "vaadin" + File.separatorChar;
public static final String COM_VAADIN_FILE_PREFIX = "com"
+ File.separatorChar + "vaadin" + File.separatorChar;
private final Predicate<String> skipClassesFilter; private final Predicate<String> skipClassesFilter;


ClasspathHelper(Predicate<String> skipClassesFilter) {
public ClasspathHelper(Predicate<String> skipClassesFilter) {
this.skipClassesFilter = skipClassesFilter; this.skipClassesFilter = skipClassesFilter;
} }


Stream<Class<?>> getVaadinClassesFromClasspath(
public ClasspathHelper() {
this(fqn -> false);
}

public Stream<Class<?>> getVaadinClassesFromClasspath(
Predicate<String> classpathFilter, Predicate<String> classpathFilter,
Predicate<Class<?>> classFilter) { Predicate<Class<?>> classFilter) {
return getRawClasspathEntries().stream().filter(classpathFilter) return getRawClasspathEntries().stream().filter(classpathFilter)


} }


Stream<Class<?>> getVaadinClassesFromClasspath(
public Stream<Class<?>> getVaadinClassesFromClasspath(
Predicate<String> classpathFilter) { Predicate<String> classpathFilter) {
return getVaadinClassesFromClasspath(classpathFilter, cls -> true); return getVaadinClassesFromClasspath(classpathFilter, cls -> true);
} }
} else if (classesRoot.getName().toLowerCase(Locale.ENGLISH) } else if (classesRoot.getName().toLowerCase(Locale.ENGLISH)
.endsWith(".jar")) { .endsWith(".jar")) {
URI uri = URI.create("jar:file:" + classesRoot.getPath()); URI uri = URI.create("jar:file:" + classesRoot.getPath());
Path root = FileSystems
.newFileSystem(uri, Collections.emptyMap())
.getPath(File.separator);
FileSystem fileSystem;
try {
fileSystem = FileSystems.getFileSystem(uri);
} catch (FileSystemNotFoundException e) {
fileSystem = null;
}
if (fileSystem == null) {
fileSystem = FileSystems.newFileSystem(uri,
Collections.emptyMap());
}
Path root = fileSystem.getPath(File.separator);
return Files.walk(root).filter(Files::isRegularFile) return Files.walk(root).filter(Files::isRegularFile)
.filter(path -> path.toUri().getSchemeSpecificPart() .filter(path -> path.toUri().getSchemeSpecificPart()
.endsWith(".class")) .endsWith(".class"))

+ 13
- 8
server/src/test/java/com/vaadin/tests/server/component/FinalMethodTest.java View File

import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.HashSet; import java.util.HashSet;


import org.junit.Assert;
import org.junit.Test; import org.junit.Test;


import com.vaadin.tests.VaadinClasses; import com.vaadin.tests.VaadinClasses;
@Test @Test
public void testThatComponentsHaveNoFinalMethods() { public void testThatComponentsHaveNoFinalMethods() {
HashSet<Class<?>> tested = new HashSet<>(); HashSet<Class<?>> tested = new HashSet<>();
int count = 0;
for (Class<? extends Component> c : VaadinClasses.getComponents()) { for (Class<? extends Component> c : VaadinClasses.getComponents()) {
ensureNoFinalMethods(c, tested); ensureNoFinalMethods(c, tested);
count++;
} }
Assert.assertTrue(count > 0);
} }


private void ensureNoFinalMethods(Class<?> c, HashSet<Class<?>> tested) {
if (tested.contains(c)) {
private void ensureNoFinalMethods(Class<?> clazz,
HashSet<Class<?>> tested) {
if (tested.contains(clazz)) {
return; return;
} }


tested.add(c);
tested.add(clazz);


if (c == Object.class) {
if (clazz == null || clazz.equals(Object.class)) {
return; return;
} }
System.out.println("Checking " + c.getName());
for (Method m : c.getDeclaredMethods()) {
System.out.println("Checking " + clazz.getName());
for (Method m : clazz.getDeclaredMethods()) {
if (isPrivate(m)) { if (isPrivate(m)) {
continue; continue;
} }
if (isFinal(m)) { if (isFinal(m)) {
String error = "Class " + c.getName() + " contains a "
String error = "Class " + clazz.getName() + " contains a "
+ (isPublic(m) ? "public" : "non-public") + (isPublic(m) ? "public" : "non-public")
+ " final method: " + m.getName(); + " final method: " + m.getName();
// System.err.println(error); // System.err.println(error);
throw new RuntimeException(error); throw new RuntimeException(error);
} }
} }
ensureNoFinalMethods(c.getSuperclass(), tested);
ensureNoFinalMethods(clazz.getSuperclass(), tested);


} }



+ 57
- 20
server/src/test/java/com/vaadin/tests/server/component/StateGetDoesNotMarkDirtyTest.java View File

package com.vaadin.tests.server.component; package com.vaadin.tests.server.component;


import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Locale; import java.util.Locale;
import java.util.Set; import java.util.Set;


import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;


import com.vaadin.server.VaadinSession;
import com.vaadin.tests.VaadinClasses; import com.vaadin.tests.VaadinClasses;
import com.vaadin.ui.Component; import com.vaadin.ui.Component;
import com.vaadin.ui.ConnectorTracker; import com.vaadin.ui.ConnectorTracker;
public void setUp() { public void setUp() {
excludedMethods.add(Label.class.getName() + "getDataProviderValue"); excludedMethods.add(Label.class.getName() + "getDataProviderValue");
excludedMethods.add("getConnectorId"); excludedMethods.add("getConnectorId");
excludedMethods.add("getContent");
} }


@Test @Test
public void testGetDoesntMarkStateDirty() throws Exception { public void testGetDoesntMarkStateDirty() throws Exception {
for (Class<? extends Component> c : VaadinClasses.getComponents()) {
Component newInstance = construct(c);
int count = 0;
for (Class<? extends Component> clazz : VaadinClasses.getComponents()) {
if (clazz.isInterface()
|| Modifier.isAbstract(clazz.getModifiers())) {
continue;
}
Component newInstance = construct(clazz);
if (newInstance == null) {
continue;
}
count++;
prepareMockUI(newInstance); prepareMockUI(newInstance);


Set<Method> methods = new HashSet<>(); Set<Method> methods = new HashSet<>();
methods.addAll(Arrays.asList(c.getMethods()));
methods.addAll(Arrays.asList(c.getDeclaredMethods()));
methods.addAll(Arrays.asList(clazz.getMethods()));
methods.addAll(Arrays.asList(clazz.getDeclaredMethods()));
for (Method method : methods) { for (Method method : methods) {
try { try {
if (method.getName().startsWith("is") if (method.getName().startsWith("is")
continue; continue;
} }
if (excludedMethods if (excludedMethods
.contains(c.getName() + method.getName())) {
.contains(clazz.getName() + method.getName())) {
// blacklisted method for specific classes // blacklisted method for specific classes
continue; continue;
} }
method.invoke(newInstance); method.invoke(newInstance);
} }
} catch (Exception e) { } catch (Exception e) {
System.err.println("problem with method " + c.getName()
System.err.println("problem with method " + clazz.getName()
+ "# " + method.getName()); + "# " + method.getName());
e.printStackTrace(); e.printStackTrace();
throw e; throw e;
} }
} }
} }
Assert.assertTrue(count > 0);
} }


private void prepareMockUI(Component newInstance) { private void prepareMockUI(Component newInstance) {
UI ui = mockUI();
ConnectorTracker connectorTracker = ui.getConnectorTracker();
Mockito.doThrow(new RuntimeException("getState(true) called in getter"))
.when(connectorTracker).markDirty(newInstance);
newInstance.setParent(null);
newInstance.setParent(ui);
}

private UI mockUI() {
UI ui = Mockito.mock(UI.class); UI ui = Mockito.mock(UI.class);
Mockito.when(ui.getLocale()).thenReturn(Locale.ENGLISH); Mockito.when(ui.getLocale()).thenReturn(Locale.ENGLISH);
ConnectorTracker connectorTracker = Mockito ConnectorTracker connectorTracker = Mockito
.mock(ConnectorTracker.class); .mock(ConnectorTracker.class);
Mockito.when(ui.getConnectorTracker()).thenReturn(connectorTracker); Mockito.when(ui.getConnectorTracker()).thenReturn(connectorTracker);
Mockito.doThrow(new RuntimeException("getState(true) called in getter"))
.when(connectorTracker).markDirty(newInstance);

newInstance.setParent(ui);
return ui;
} }


private Component construct(Class<? extends Component> c) {
private Component construct(Class<? extends Component> clazz) {
try { try {
try {
Constructor<? extends Component> declaredConstructor = c
.getDeclaredConstructor();
declaredConstructor.setAccessible(true);
return declaredConstructor.newInstance();
} catch (NoSuchMethodException e) {
return c.newInstance();
Constructor<? extends Component> declaredConstructor = clazz
.getDeclaredConstructor();
declaredConstructor.setAccessible(true);
Component component = declaredConstructor.newInstance();
if (component instanceof UI) {
return component;
} }
} catch (Exception e) {
emulateAttach(component);
return component;
} catch (NoSuchMethodException e) {
// no default CTOR, skip
return null;
} catch (InstantiationException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }

private void emulateAttach(Component component) {
UI ui = mockUI();
VaadinSession session = Mockito.mock(VaadinSession.class);
Mockito.when(session.hasLock()).thenReturn(true);
Mockito.when(ui.getSession()).thenReturn(session);
component.setParent(ui);

component.attach();
}

} }

+ 20
- 3
server/src/test/java/com/vaadin/tests/server/componentcontainer/AddRemoveComponentTest.java View File

package com.vaadin.tests.server.componentcontainer; package com.vaadin.tests.server.componentcontainer;


import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.util.List; import java.util.List;


import org.junit.Assert; import org.junit.Assert;


@Test @Test
public void testRemoveComponentFromWrongContainer() public void testRemoveComponentFromWrongContainer()
throws InstantiationException, IllegalAccessException {
throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
List<Class<? extends ComponentContainer>> containerClasses = VaadinClasses List<Class<? extends ComponentContainer>> containerClasses = VaadinClasses
.getComponentContainersSupportingAddRemoveComponent(); .getComponentContainersSupportingAddRemoveComponent();


Assert.assertTrue(containerClasses.size() > 0);

// No default constructor, special case // No default constructor, special case
containerClasses.remove(CustomLayout.class); containerClasses.remove(CustomLayout.class);
testRemoveComponentFromWrongContainer(new CustomLayout("dummy")); testRemoveComponentFromWrongContainer(new CustomLayout("dummy"));


for (Class<? extends ComponentContainer> c : containerClasses) {
testRemoveComponentFromWrongContainer(c.newInstance());
for (Class<? extends ComponentContainer> clazz : containerClasses) {
if (Modifier.isAbstract(clazz.getModifiers())) {
continue;
}
try {
Constructor<? extends ComponentContainer> constructor = clazz
.getConstructor();
constructor.setAccessible(true);
testRemoveComponentFromWrongContainer(
constructor.newInstance());
} catch (NoSuchMethodException ignore) {
// if there is no default CTOR, just ignore
}
} }
} }



+ 9
- 2
shared/src/main/java/com/vaadin/shared/ui/ComponentStateUtil.java View File

import java.util.HashSet; import java.util.HashSet;


import com.vaadin.shared.AbstractComponentState; import com.vaadin.shared.AbstractComponentState;
import com.vaadin.shared.Registration;
import com.vaadin.shared.communication.SharedState; import com.vaadin.shared.communication.SharedState;


public final class ComponentStateUtil implements Serializable { public final class ComponentStateUtil implements Serializable {
* *
* @param eventListenerId * @param eventListenerId
* The event identifier to remove * The event identifier to remove
* @deprecated Use a {@link Registration} object returned by
* {@link #addRegisteredEventListener(SharedState, String)} to
* remove a listener
*/ */
@Deprecated
public static final void removeRegisteredEventListener(SharedState state, public static final void removeRegisteredEventListener(SharedState state,
String eventIdentifier) { String eventIdentifier) {
if (state.registeredEventListeners == null) { if (state.registeredEventListeners == null) {
* *
* @param eventListenerId * @param eventListenerId
* The event identifier to add * The event identifier to add
* @return a registration object for removing the listener
*/ */
public static final void addRegisteredEventListener(SharedState state,
String eventListenerId) {
public static final Registration addRegisteredEventListener(
SharedState state, String eventListenerId) {
if (state.registeredEventListeners == null) { if (state.registeredEventListeners == null) {
state.registeredEventListeners = new HashSet<>(); state.registeredEventListeners = new HashSet<>();
} }
state.registeredEventListeners.add(eventListenerId); state.registeredEventListeners.add(eventListenerId);
return () -> removeRegisteredEventListener(state, eventListenerId);
} }
} }

+ 0
- 15
uitest/src/main/java/com/vaadin/tests/VaadinClasses.java View File

return classes; return classes;
} }


@SuppressWarnings({ "unchecked", "rawtypes" })
public static List<Class<?>> getBasicComponentTests() {
try {
// Given as name to avoid dependencies on testbench source folder
return (List) findClasses(
Class.forName(
"com.vaadin.tests.components.AbstractComponentTest"),
"com.vaadin.tests.components");
} catch (Exception e) {
e.printStackTrace();
return null;
}

}

private static <T> List<Class<? extends T>> findClasses(Class<T> baseClass, private static <T> List<Class<? extends T>> findClasses(Class<T> baseClass,
String basePackage) throws IOException { String basePackage) throws IOException {
return findClasses(baseClass, basePackage, new String[] {}); return findClasses(baseClass, basePackage, new String[] {});

Loading…
Cancel
Save