Fixes vaadin/framework8-issues#399 RemoveListenersDeprecatedTest test is fixed. Corrections are made to make the test above passes. Change-Id: I209a4693d241a1488b69b4742f48549dbf4bf0actags/8.0.0.alpha8
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); | |||||
} | } | ||||
/** | /** |
"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"); |
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()); | |||||
} | } | ||||
} | } |
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; | |||||
} | } | ||||
} | } |
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()); |
* @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); | ||||
} | } |
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); | ||||
} | } | ||||
} | } |
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); | ||||
} | } |
} | } | ||||
@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) { |
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); | ||||
} | } | ||||
} | } |
* @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); | |||||
} | } | ||||
/** | /** |
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, |
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; | |||||
} | } | ||||
/** | /** |
@Override | @Override | ||||
public Double getValue() { | public Double getValue() { | ||||
return getState().value; | |||||
return getState(false).value; | |||||
} | } | ||||
@Override | @Override |
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; | ||||
} | } |
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()); | |||||
} | |||||
} | |||||
} | } | ||||
} | } |
*/ | */ | ||||
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()); | |||||
} | |||||
} | |||||
} | } | ||||
} | } |
} | } | ||||
} | } | ||||
/** | |||||
* 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(); | ||||
} | } | ||||
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); |
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; | |||||
} | } | ||||
} | } |
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; | |||||
} | } | ||||
} | } |
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")) |
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); | |||||
} | } | ||||
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(); | |||||
} | |||||
} | } |
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 | |||||
} | |||||
} | } | ||||
} | } | ||||
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); | |||||
} | } | ||||
} | } |
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[] {}); |