diff options
author | Leif Åstrand <leif@vaadin.com> | 2013-07-15 09:15:13 +0300 |
---|---|---|
committer | Leif Åstrand <leif@vaadin.com> | 2013-07-15 09:15:13 +0300 |
commit | f0d8ccd131a5a63a2f5624dd8ef1643d4268f62d (patch) | |
tree | cb80d9096aeb554d545f932d0e51b013c4d0e830 /server | |
parent | c44ca1270523c544b9aedabe7f9780a5e6862859 (diff) | |
parent | a93426164d5766fd7e0a687c1a7c98ce53aaa1c7 (diff) | |
download | vaadin-framework-f0d8ccd131a5a63a2f5624dd8ef1643d4268f62d.tar.gz vaadin-framework-f0d8ccd131a5a63a2f5624dd8ef1643d4268f62d.zip |
Merge changes from origin/7.1
419c6c7 Implemented Focusable in MenuBar (#7674)
a4f1277 Fixed NPE in ApplicationRunnerServlet (#12145)
08d365a Fixed slider value initialization on HSV and RGB tabs of ColorPicker. (#7863)
da480bd Fix VaadinService.findUI to throw Error if UIConstants.UI_ID_PARAMETER is not set (#11943)
6291a50 Ensure that Slider diffstate always contains "value" (#12133)
7e7e698 32x32 favicons added, replacing the old favicons (#12143)
1702059 Replace printStackTrace with getLogger().log() (#12147)
b421d6e Updated Javadoc for Table.getColumnAlignment fixing #6810
414e3bf Fixed an error in CustomComponent JavaDoc (#10038), and some improvements.
4583d07 Fix NPE in Like.java (#10167)
6c4da29 Ensure table's cells aren't refreshed if table is detached. (#9138)
e37464c #11638: Ending an imported SCSS file with a comment causes an error in the Sass
478eeb5 Test using Jetty 9 (#12124)
f7cc72d Close only combobox on escape, not the window (#12163)
9a9b0a5 Automatic test for escape closing window from combobox (#12163)
ae565a2 Fix bug in PopupDateField where locale was retained incorrectly if changed while popup was open (#12153)
d7a64fd Enable native scrolling in home screen apps on iOS 6+ (#12149)
4a04f00 Add test case for testing ClickEvent after dragging button (#7690)
775c969 Make UploadInterruptedException visible (#12070)
6a4bbe5 Set heartbeat response Content-Type to text/plain (#12182)
e4011c6 When InputStream cannot be opened while writing static resource response, display 404 instead of 500 (#10920)
20162db Set current instances when calling UI.push from VaadinSession.unlock (#12168)
94c0f86 Ensure VaadinSession.service is set up by storeInSession (#12204)
23ed487 Attempt to get GAE lock for UIDL requests (#12211)
7f52b2e Improved AbstractClientConnector performance (#12219)
a934261 Improving performance of ConnectorTracker (#12218)
Change-Id: I810124d60c22d4d0ab837a19eb9c2689951864b5
Diffstat (limited to 'server')
17 files changed, 275 insertions, 126 deletions
diff --git a/server/src/com/vaadin/data/util/filter/Like.java b/server/src/com/vaadin/data/util/filter/Like.java index 91230bb1f1..4c15564105 100644 --- a/server/src/com/vaadin/data/util/filter/Like.java +++ b/server/src/com/vaadin/data/util/filter/Like.java @@ -60,6 +60,11 @@ public class Like implements Filter { String colValue = (String) item.getItemProperty(getPropertyId()) .getValue(); + // Fix issue #10167 - avoid NPE and drop null property values + if (colValue == null) { + return false; + } + String pattern = getValue().replace("%", ".*"); if (isCaseSensitive()) { return colValue.matches(pattern); diff --git a/server/src/com/vaadin/server/AbstractClientConnector.java b/server/src/com/vaadin/server/AbstractClientConnector.java index c3101924dd..91a9e41522 100644 --- a/server/src/com/vaadin/server/AbstractClientConnector.java +++ b/server/src/com/vaadin/server/AbstractClientConnector.java @@ -224,9 +224,9 @@ public abstract class AbstractClientConnector implements ClientConnector, } if (markAsDirty) { UI ui = getUI(); - if (ui != null && !ui.getConnectorTracker().isWritingResponse() - && !ui.getConnectorTracker().isDirty(this)) { - markAsDirty(); + if (ui != null && !ui.getConnectorTracker().isDirty(this) + && !ui.getConnectorTracker().isWritingResponse()) { + ui.getConnectorTracker().markDirty(this); } } return sharedState; diff --git a/server/src/com/vaadin/server/GAEVaadinServlet.java b/server/src/com/vaadin/server/GAEVaadinServlet.java index b4a83603b0..5a12295d9d 100644 --- a/server/src/com/vaadin/server/GAEVaadinServlet.java +++ b/server/src/com/vaadin/server/GAEVaadinServlet.java @@ -218,23 +218,24 @@ public class GAEVaadinServlet extends VaadinServlet { memcache = MemcacheServiceFactory.getMemcacheService(); try { // try to get lock - long started = new Date().getTime(); - // non-UIDL requests will try indefinitely - if (!ServletPortletHelper.isUIDLRequest(request)) { - while (new Date().getTime() - started < MAX_UIDL_WAIT_MILLISECONDS) { - locked = memcache.put(mutex, 1, - Expiration.byDeltaSeconds(40), - MemcacheService.SetPolicy.ADD_ONLY_IF_NOT_PRESENT); - if (locked) { - break; - } - try { - Thread.sleep(RETRY_AFTER_MILLISECONDS); - } catch (InterruptedException e) { - getLogger().finer( - "Thread.sleep() interrupted while waiting for lock. Trying again. " - + e); - } + long started = System.currentTimeMillis(); + while (System.currentTimeMillis() - started < MAX_UIDL_WAIT_MILLISECONDS) { + locked = memcache.put(mutex, 1, Expiration.byDeltaSeconds(40), + MemcacheService.SetPolicy.ADD_ONLY_IF_NOT_PRESENT); + if (locked || ServletPortletHelper.isUIDLRequest(request)) { + /* + * Done if we got a lock. Will also avoid retrying if + * there's a UIDL request because those are retried from the + * client without keeping the server thread stalled. + */ + break; + } + try { + Thread.sleep(RETRY_AFTER_MILLISECONDS); + } catch (InterruptedException e) { + getLogger().finer( + "Thread.sleep() interrupted while waiting for lock. Trying again. " + + e); } } diff --git a/server/src/com/vaadin/server/VaadinService.java b/server/src/com/vaadin/server/VaadinService.java index 18dc468cb0..cfbf2606ae 100644 --- a/server/src/com/vaadin/server/VaadinService.java +++ b/server/src/com/vaadin/server/VaadinService.java @@ -905,7 +905,7 @@ public abstract class VaadinService implements Serializable { * * @param request * the request for which a UI is desired - * @return the UI belonging to the request + * @return the UI belonging to the request or null if no UI is found * */ public UI findUI(VaadinRequest request) { @@ -915,9 +915,11 @@ public abstract class VaadinService implements Serializable { // Get UI id from the request String uiIdString = request.getParameter(UIConstants.UI_ID_PARAMETER); - int uiId = Integer.parseInt(uiIdString); - - UI ui = session.getUIById(uiId); + UI ui = null; + if (uiIdString != null) { + int uiId = Integer.parseInt(uiIdString); + ui = session.getUIById(uiId); + } UI.setCurrent(ui); return ui; diff --git a/server/src/com/vaadin/server/VaadinServlet.java b/server/src/com/vaadin/server/VaadinServlet.java index 6f45ee4930..b820b53953 100644 --- a/server/src/com/vaadin/server/VaadinServlet.java +++ b/server/src/com/vaadin/server/VaadinServlet.java @@ -16,6 +16,7 @@ package com.vaadin.server; import java.io.BufferedWriter; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -645,19 +646,19 @@ public class VaadinServlet extends HttpServlet implements Constants { "Failed to find out last modified timestamp. Continuing without it.", e); } finally { - if (connection instanceof URLConnection) { - try { - // Explicitly close the input stream to prevent it - // from remaining hanging - // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4257700 - InputStream is = connection.getInputStream(); - if (is != null) { - is.close(); - } - } catch (IOException e) { - getLogger().log(Level.INFO, - "Error closing URLConnection input stream", e); + try { + // Explicitly close the input stream to prevent it + // from remaining hanging + // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4257700 + InputStream is = connection.getInputStream(); + if (is != null) { + is.close(); } + } catch (FileNotFoundException e) { + // Not logging when the file does not exist. + } catch (IOException e) { + getLogger().log(Level.INFO, + "Error closing URLConnection input stream", e); } } @@ -747,14 +748,17 @@ public class VaadinServlet extends HttpServlet implements Constants { // prevent it from hanging, but that is done below. } - InputStream is = connection.getInputStream(); + InputStream is = null; try { + is = connection.getInputStream(); final OutputStream os = response.getOutputStream(); final byte buffer[] = new byte[DEFAULT_BUFFER_SIZE]; int bytes; while ((bytes = is.read(buffer)) >= 0) { os.write(buffer, 0, bytes); } + } catch (FileNotFoundException e) { + response.setStatus(HttpServletResponse.SC_NOT_FOUND); } finally { if (is != null) { is.close(); @@ -841,7 +845,7 @@ public class VaadinServlet extends HttpServlet implements Constants { new Object[] { realFilename, filename }); scss.compile(); } catch (Exception e) { - e.printStackTrace(); + getLogger().log(Level.WARNING, "Scss compilation failed", e); return false; } diff --git a/server/src/com/vaadin/server/VaadinSession.java b/server/src/com/vaadin/server/VaadinSession.java index 504788d479..890b2eba29 100644 --- a/server/src/com/vaadin/server/VaadinSession.java +++ b/server/src/com/vaadin/server/VaadinSession.java @@ -426,6 +426,13 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { public void storeInSession(VaadinService service, WrappedSession session) { assert hasLock(service, session); session.setAttribute(getSessionAttributeName(service), this); + + /* + * GAEVaadinServlet passes newly deserialized sessions here, which means + * that these transient fields need to be populated to avoid NPE from + * refreshLock(). + */ + this.service = service; this.session = session; refreshLock(); } @@ -885,9 +892,9 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * Unlocks this session. This method should always be used in a finally * block after {@link #lock()} to ensure that the lock is always released. * <p> - * If {@link #getPushMode() the push mode} is {@link PushMode#AUTOMATIC - * automatic}, pushes the changes in all UIs in this session to their - * respective clients. + * For UIs in this session that have its push mode set to + * {@link PushMode#AUTOMATIC automatic}, pending changes will be pushed to + * their respective clients. * * @see #lock() * @see UI#push() @@ -904,7 +911,13 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { for (UI ui : getUIs()) { if (ui.getPushConfiguration().getPushMode() == PushMode.AUTOMATIC) { - ui.push(); + Map<Class<?>, CurrentInstance> oldCurrent = CurrentInstance + .setCurrent(ui); + try { + ui.push(); + } finally { + CurrentInstance.restoreInstances(oldCurrent); + } } } } diff --git a/server/src/com/vaadin/server/communication/FileUploadHandler.java b/server/src/com/vaadin/server/communication/FileUploadHandler.java index 8014dba12d..41a16601fe 100644 --- a/server/src/com/vaadin/server/communication/FileUploadHandler.java +++ b/server/src/com/vaadin/server/communication/FileUploadHandler.java @@ -38,6 +38,7 @@ import com.vaadin.server.VaadinResponse; import com.vaadin.server.VaadinSession; import com.vaadin.ui.Component; import com.vaadin.ui.UI; +import com.vaadin.ui.Upload.FailedEvent; /** * Handles a file upload request submitted via an Upload component. @@ -197,7 +198,19 @@ public class FileUploadHandler implements RequestHandler { } } - private static class UploadInterruptedException extends Exception { + /** + * An UploadInterruptedException will be thrown by an ongoing upload if + * {@link StreamVariable#isInterrupted()} returns <code>true</code>. + * + * By checking the exception of an {@link StreamingErrorEvent} or + * {@link FailedEvent} against this class, it is possible to determine if an + * upload was interrupted by code or aborted due to any other exception. + */ + public static class UploadInterruptedException extends Exception { + + /** + * Constructs an instance of <code>UploadInterruptedException</code>. + */ public UploadInterruptedException() { super("Upload interrupted by other thread"); } diff --git a/server/src/com/vaadin/server/communication/HeartbeatHandler.java b/server/src/com/vaadin/server/communication/HeartbeatHandler.java index 16c21224ab..4c95859203 100644 --- a/server/src/com/vaadin/server/communication/HeartbeatHandler.java +++ b/server/src/com/vaadin/server/communication/HeartbeatHandler.java @@ -63,6 +63,9 @@ public class HeartbeatHandler extends SynchronizedRequestHandler implements // Ensure that the browser does not cache heartbeat responses. // iOS 6 Safari requires this (#10370) response.setHeader("Cache-Control", "no-cache"); + // If Content-Type is not set, browsers assume text/html and may + // complain about the empty response body (#12182) + response.setHeader("Content-Type", "text/plain"); } else { response.sendError(HttpServletResponse.SC_NOT_FOUND, "UI not found"); } diff --git a/server/src/com/vaadin/server/themeutils/SASSAddonImportFileCreator.java b/server/src/com/vaadin/server/themeutils/SASSAddonImportFileCreator.java index f199c347eb..94ca9e7d5b 100644 --- a/server/src/com/vaadin/server/themeutils/SASSAddonImportFileCreator.java +++ b/server/src/com/vaadin/server/themeutils/SASSAddonImportFileCreator.java @@ -26,6 +26,8 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; import com.vaadin.server.widgetsetutils.ClassPathExplorer; import com.vaadin.server.widgetsetutils.ClassPathExplorer.LocationInfo; @@ -126,10 +128,14 @@ public class SASSAddonImportFileCreator { } catch (FileNotFoundException e) { // Should not happen since file is checked before this - e.printStackTrace(); + getLogger().log(Level.WARNING, "Error updating addons.scss", e); } } + private static Logger getLogger() { + return Logger.getLogger(SASSAddonImportFileCreator.class.getName()); + } + private static List<String> addImport(PrintStream stream, String file, URL location) { diff --git a/server/src/com/vaadin/ui/ConnectorTracker.java b/server/src/com/vaadin/ui/ConnectorTracker.java index 85cdcdf65c..c2aeebcd44 100644 --- a/server/src/com/vaadin/ui/ConnectorTracker.java +++ b/server/src/com/vaadin/ui/ConnectorTracker.java @@ -296,9 +296,9 @@ public class ConnectorTracker implements Serializable { uninitializedConnectors.remove(connector); diffStates.remove(connector); iterator.remove(); - } else if (!LegacyCommunicationManager - .isConnectorVisibleToClient(connector) - && !uninitializedConnectors.contains(connector)) { + } else if (!uninitializedConnectors.contains(connector) + && !LegacyCommunicationManager + .isConnectorVisibleToClient(connector)) { uninitializedConnectors.add(connector); diffStates.remove(connector); if (getLogger().isLoggable(Level.FINE)) { diff --git a/server/src/com/vaadin/ui/CustomComponent.java b/server/src/com/vaadin/ui/CustomComponent.java index ae92a514a8..9e004f7a17 100644 --- a/server/src/com/vaadin/ui/CustomComponent.java +++ b/server/src/com/vaadin/ui/CustomComponent.java @@ -20,12 +20,33 @@ import java.util.Collections; import java.util.Iterator; /** - * Custom component provides simple implementation of Component interface for - * creation of new UI components by composition of existing components. + * Custom component provides a simple implementation of the {@link Component} + * interface to allow creating new UI components by composition of existing + * server-side components. + * + * <p> + * The component is used by inheriting the CustomComponent class and setting the + * composition root component. The composition root must be set with + * {@link #setCompositionRoot(Component)} before the CustomComponent is used, + * such as by adding it to a layout, so it is preferable to set it in the + * constructor. + * </p> + * * <p> - * The component is used by inheriting the CustomComponent class and setting - * composite root inside the Custom component. The composite root itself can - * contain more components, but their interfaces are hidden from the users. + * The composition root itself can contain more components. The advantage of + * wrapping it in a CustomComponent is that its details, such as interfaces, are + * hidden from the users of the component, thereby contributing to information + * hiding. + * </p> + * + * <p> + * The CustomComponent does not display the caption of the composition root, so + * if you want to have it shown in the layout where the custom component is + * contained, you need to set it as caption of the CustomComponent. + * </p> + * + * <p> + * The component expands horizontally and has undefined height by default. * </p> * * @author Vaadin Ltd. @@ -43,27 +64,21 @@ public class CustomComponent extends AbstractComponent implements HasComponents * Constructs a new custom component. * * <p> - * The component is implemented by wrapping the methods of the composition - * root component given as parameter. The composition root must be set - * before the component can be used. + * Note that you must set the composition root before the component can be + * used, preferably in the constructor. * </p> */ public CustomComponent() { - // expand horizontally by default - setWidth(100, UNITS_PERCENTAGE); + // Expand horizontally by default + setWidth(100, Unit.PERCENTAGE); } /** * Constructs a new custom component. * - * <p> - * The component is implemented by wrapping the methods of the composition - * root component given as parameter. The composition root must not be null - * and can not be changed after the composition. - * </p> - * * @param compositionRoot - * the root of the composition component tree. + * the root of the composition component tree. It must not be + * null. */ public CustomComponent(Component compositionRoot) { this(); @@ -80,10 +95,11 @@ public class CustomComponent extends AbstractComponent implements HasComponents } /** - * Sets the compositions root. + * Sets the composition root for the component. + * * <p> - * The composition root must be set to non-null value before the component - * can be used. The composition root can only be set once. + * You must set the composition root must to a non-null value before the + * component can be used. You can change it later. * </p> * * @param compositionRoot diff --git a/server/src/com/vaadin/ui/MenuBar.java b/server/src/com/vaadin/ui/MenuBar.java index 2bf5234f24..545a1e9e3e 100644 --- a/server/src/com/vaadin/ui/MenuBar.java +++ b/server/src/com/vaadin/ui/MenuBar.java @@ -26,6 +26,8 @@ import com.vaadin.server.PaintException; import com.vaadin.server.PaintTarget; import com.vaadin.server.Resource; import com.vaadin.shared.ui.menubar.MenuBarConstants; +import com.vaadin.shared.ui.menubar.MenuBarState; +import com.vaadin.ui.Component.Focusable; /** * <p> @@ -35,7 +37,8 @@ import com.vaadin.shared.ui.menubar.MenuBarConstants; * </p> */ @SuppressWarnings("serial") -public class MenuBar extends AbstractComponent implements LegacyComponent { +public class MenuBar extends AbstractComponent implements LegacyComponent, + Focusable { // Items of the top-level menu private final List<MenuItem> menuItems; @@ -49,6 +52,11 @@ public class MenuBar extends AbstractComponent implements LegacyComponent { private boolean htmlContentAllowed; + @Override + protected MenuBarState getState() { + return (MenuBarState) super.getState(); + } + /** Paint (serialise) the component for the client. */ @Override public void paintContent(PaintTarget target) throws PaintException { @@ -386,6 +394,27 @@ public class MenuBar extends AbstractComponent implements LegacyComponent { return htmlContentAllowed; } + @Override + public int getTabIndex() { + return getState().tabIndex; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.ui.Component.Focusable#setTabIndex(int) + */ + @Override + public void setTabIndex(int tabIndex) { + getState().tabIndex = tabIndex; + } + + @Override + public void focus() { + // Overridden only to make public + super.focus(); + } + /** * This interface contains the layer for menu commands of the * {@link com.vaadin.ui.MenuBar} class. It's method will fire when the user diff --git a/server/src/com/vaadin/ui/Slider.java b/server/src/com/vaadin/ui/Slider.java index e63fdc5e10..44fc49ba9b 100644 --- a/server/src/com/vaadin/ui/Slider.java +++ b/server/src/com/vaadin/ui/Slider.java @@ -16,6 +16,8 @@ package com.vaadin.ui; +import org.json.JSONException; + import com.vaadin.shared.ui.slider.SliderOrientation; import com.vaadin.shared.ui.slider.SliderServerRpc; import com.vaadin.shared.ui.slider.SliderState; @@ -32,6 +34,21 @@ public class Slider extends AbstractField<Double> { @Override public void valueChanged(double value) { + /* + * Client side updates the state before sending the event so we need + * to make sure the cached state is updated to match the client. If + * we do not do this, a reverting setValue() call in a listener will + * not cause the new state to be sent to the client. + * + * See #12133. + */ + try { + getUI().getConnectorTracker().getDiffState(Slider.this) + .put("value", value); + } catch (JSONException e) { + throw new RuntimeException(e); + } + try { setValue(value, true); } catch (final ValueOutOfBoundsException e) { diff --git a/server/src/com/vaadin/ui/Table.java b/server/src/com/vaadin/ui/Table.java index b5606b4e67..5dbf927658 100644 --- a/server/src/com/vaadin/ui/Table.java +++ b/server/src/com/vaadin/ui/Table.java @@ -1251,7 +1251,8 @@ public class Table extends AbstractSelect implements Action.Container, * * @param propertyId * the propertyID identifying the column. - * @return the specified column's alignment if it as one; null otherwise. + * @return the specified column's alignment if it as one; {@link Align#LEFT} + * otherwise. */ public Align getColumnAlignment(Object propertyId) { final Align a = columnAlignments.get(propertyId); @@ -1614,7 +1615,7 @@ public class Table extends AbstractSelect implements Action.Container, * guaranteed to be recreated. */ protected void refreshRenderedCells() { - if (getParent() == null) { + if (!isAttached()) { return; } diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java index 2138edd6ac..63f04acd43 100644 --- a/server/src/com/vaadin/ui/UI.java +++ b/server/src/com/vaadin/ui/UI.java @@ -1306,15 +1306,18 @@ public abstract class UI extends AbstractSingleComponentContainer implements * Pushes the pending changes and client RPC invocations of this UI to the * client-side. * <p> - * As with all UI methods, it is not safe to call push() without holding the - * {@link VaadinSession#lock() session lock}. + * As with all UI methods, the session must be locked when calling this + * method. It is also recommended that {@link UI#getCurrent()} is set up to + * return this UI since writing the response may invoke logic in any + * attached component or extension. The recommended way of fulfilling these + * conditions is to use {@link #access(Runnable)}. * * @throws IllegalStateException * if push is disabled. * @throws UIDetachedException * if this UI is not attached to a session. * - * @see #getPushMode() + * @see #getPushConfiguration() * * @since 7.1 */ diff --git a/server/src/com/vaadin/ui/components/colorpicker/ColorPickerPopup.java b/server/src/com/vaadin/ui/components/colorpicker/ColorPickerPopup.java index fee52d1a24..9774211bea 100644 --- a/server/src/com/vaadin/ui/components/colorpicker/ColorPickerPopup.java +++ b/server/src/com/vaadin/ui/components/colorpicker/ColorPickerPopup.java @@ -22,6 +22,8 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; @@ -276,11 +278,9 @@ public class ColorPickerPopup extends Window implements ClickListener, sliders.setStyleName("rgb-sliders"); redSlider = createRGBSlider("Red", "red"); - - try { - redSlider.setValue(((Integer) color.getRed()).doubleValue()); - } catch (ValueOutOfBoundsException e) { - } + greenSlider = createRGBSlider("Green", "green"); + blueSlider = createRGBSlider("Blue", "blue"); + setRgbSliderValues(color); redSlider.addValueChangeListener(new ValueChangeListener() { @Override @@ -296,13 +296,6 @@ public class ColorPickerPopup extends Window implements ClickListener, sliders.addComponent(redSlider); - greenSlider = createRGBSlider("Green", "green"); - - try { - greenSlider.setValue(((Integer) color.getGreen()).doubleValue()); - } catch (ValueOutOfBoundsException e) { - } - greenSlider.addValueChangeListener(new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { @@ -316,13 +309,6 @@ public class ColorPickerPopup extends Window implements ClickListener, }); sliders.addComponent(greenSlider); - blueSlider = createRGBSlider("Blue", "blue"); - - try { - blueSlider.setValue(((Integer) color.getBlue()).doubleValue()); - } catch (ValueOutOfBoundsException e) { - } - blueSlider.addValueChangeListener(new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { @@ -368,15 +354,15 @@ public class ColorPickerPopup extends Window implements ClickListener, hsvLayout.addComponent(hsvGradient); selectors.add(hsvGradient); - float[] hsv = color.getHSV(); VerticalLayout sliders = new VerticalLayout(); sliders.setStyleName("hsv-sliders"); hueSlider = new Slider("Hue", 0, 360); - try { - hueSlider.setValue(((Float) hsv[0]).doubleValue()); - } catch (ValueOutOfBoundsException e1) { - } + saturationSlider = new Slider("Saturation", 0, 100); + valueSlider = new Slider("Value", 0, 100); + + float[] hsv = color.getHSV(); + setHsvSliderValues(hsv); hueSlider.setStyleName("hsv-slider"); hueSlider.addStyleName("hue-slider"); @@ -410,13 +396,6 @@ public class ColorPickerPopup extends Window implements ClickListener, }); sliders.addComponent(hueSlider); - saturationSlider = new Slider("Saturation", 0, 100); - - try { - saturationSlider.setValue(((Float) hsv[1]).doubleValue()); - } catch (ValueOutOfBoundsException e1) { - } - saturationSlider.setStyleName("hsv-slider"); saturationSlider.setWidth("220px"); saturationSlider.setImmediate(true); @@ -438,13 +417,6 @@ public class ColorPickerPopup extends Window implements ClickListener, }); sliders.addComponent(saturationSlider); - valueSlider = new Slider("Value", 0, 100); - - try { - valueSlider.setValue(((Float) hsv[2]).doubleValue()); - } catch (ValueOutOfBoundsException e1) { - } - valueSlider.setStyleName("hsv-slider"); valueSlider.setWidth("220px"); valueSlider.setImmediate(true); @@ -576,23 +548,11 @@ public class ColorPickerPopup extends Window implements ClickListener, setColor(event.getColor()); updatingColors = true; - try { - redSlider - .setValue(((Integer) selectedColor.getRed()).doubleValue()); - blueSlider.setValue(((Integer) selectedColor.getBlue()) - .doubleValue()); - greenSlider.setValue(((Integer) selectedColor.getGreen()) - .doubleValue()); - - float[] hsv = selectedColor.getHSV(); - hueSlider.setValue(((Float) (hsv[0] * 360f)).doubleValue()); - saturationSlider.setValue(((Float) (hsv[1] * 100f)).doubleValue()); - valueSlider.setValue(((Float) (hsv[2] * 100f)).doubleValue()); + setRgbSliderValues(selectedColor); + float[] hsv = selectedColor.getHSV(); + setHsvSliderValues(hsv); - } catch (ValueOutOfBoundsException e) { - e.printStackTrace(); - } updatingColors = false; for (ColorSelector s : selectors) { @@ -603,6 +563,32 @@ public class ColorPickerPopup extends Window implements ClickListener, } } + private void setRgbSliderValues(Color color) { + try { + redSlider.setValue(((Integer) color.getRed()).doubleValue()); + blueSlider.setValue(((Integer) color.getBlue()).doubleValue()); + greenSlider.setValue(((Integer) color.getGreen()).doubleValue()); + } catch (ValueOutOfBoundsException e) { + getLogger().log( + Level.WARNING, + "Unable to set RGB color value to " + color.getRed() + "," + + color.getGreen() + "," + color.getBlue(), e); + } + } + + private void setHsvSliderValues(float[] hsv) { + try { + hueSlider.setValue(((Float) (hsv[0] * 360f)).doubleValue()); + saturationSlider.setValue(((Float) (hsv[1] * 100f)).doubleValue()); + valueSlider.setValue(((Float) (hsv[2] * 100f)).doubleValue()); + } catch (ValueOutOfBoundsException e) { + getLogger().log( + Level.WARNING, + "Unable to set HSV color value to " + hsv[0] + "," + hsv[1] + + "," + hsv[2], e); + } + } + @Override public void addColorChangeListener(ColorChangeListener listener) { addListener(ColorChangeEvent.class, listener, COLOR_CHANGE_METHOD); @@ -786,4 +772,8 @@ public class ColorPickerPopup extends Window implements ClickListener, return color; } }; + + public static Logger getLogger() { + return Logger.getLogger(ColorPickerPopup.class.getName()); + } }
\ No newline at end of file diff --git a/server/tests/src/com/vaadin/data/util/filter/LikeFilterTest.java b/server/tests/src/com/vaadin/data/util/filter/LikeFilterTest.java new file mode 100644 index 0000000000..15ad85e10d --- /dev/null +++ b/server/tests/src/com/vaadin/data/util/filter/LikeFilterTest.java @@ -0,0 +1,46 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.data.util.filter; + +import junit.framework.Assert; + +import com.vaadin.data.Item; +import com.vaadin.data.util.ObjectProperty; +import com.vaadin.data.util.PropertysetItem; + +public class LikeFilterTest extends AbstractFilterTest<Like> { + + protected Item item1 = new PropertysetItem(); + protected Item item2 = new PropertysetItem(); + protected Item item3 = new PropertysetItem(); + + public void testLikeWithNulls() { + + Like filter = new Like("value", "a"); + + item1.addItemProperty("value", new ObjectProperty<String>("a")); + item2.addItemProperty("value", new ObjectProperty<String>("b")); + item3.addItemProperty("value", new ObjectProperty<String>(null, + String.class)); + + Assert.assertTrue(filter.passesFilter(null, item1)); + Assert.assertFalse(filter.passesFilter(null, item2)); + Assert.assertFalse(filter.passesFilter(null, item3)); + + } + +} |