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

org.eclipse.rap.rwt.remote.JsonMapping Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright (c) 2014, 2020 EclipseSource and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    EclipseSource - initial API and implementation
 ******************************************************************************/
package org.eclipse.rap.rwt.remote;

import static org.eclipse.rap.rwt.internal.protocol.ProtocolUtil.parseFontName;
import static org.eclipse.swt.internal.graphics.FontUtil.getData;

import java.lang.reflect.Field;

import org.eclipse.rap.json.JsonArray;
import org.eclipse.rap.json.JsonValue;
import org.eclipse.rap.rwt.internal.lifecycle.WidgetUtil;
import org.eclipse.rap.rwt.internal.protocol.JsonUtil;
import org.eclipse.rap.rwt.internal.util.ParamCheck;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.internal.graphics.ImageFactory;
import org.eclipse.swt.widgets.Widget;


/**
 * Provides utility methods that map common SWT types to their JSON representations used in the RAP
 * protocol and back.
 *
 * @see http://wiki.eclipse.org/RAP/Protocol
 * @since 2.3
 */
public class JsonMapping {

  private static final String CURSOR_UPARROW
    = "rwt-resources/resource/widget/rap/cursors/up_arrow.cur";

  private JsonMapping() {
    // prevent instantiation
  }

  /**
   * Returns the JSON representation for the given Widget. This method accepts null,
   * which will be mapped to JsonValue.NULL. Disposed widgets cannot be mapped to JSON.
   *
   * @param widget the widget to encode or null, must not be disposed
   * @return a JSON value that represents the given widget
   */
  public static JsonValue toJson( Widget widget ) {
    if( widget == null ) {
      return JsonValue.NULL;
    }
    if( widget.isDisposed() ) {
      throw new IllegalArgumentException( "Widget is disposed" );
    }
    return JsonValue.valueOf( WidgetUtil.getId( widget ) );
  }

  /**
   * Returns the JSON representation for the given array of widgets. The array must not contain
   * disposed widgets, as those cannot be mapped to JSON.
   *
   * @param widgets the array of widgets to encode, must not be null
   * @return a JSON value that represents the given widget array
   * @since 3.1
   */
  public static JsonValue toJson( Widget[] widgets ) {
    JsonArray widgetIds = new JsonArray();
    for( Widget widget : widgets ) {
      widgetIds.add( toJson( widget ) );
    }
    return widgetIds;
  }

  /**
   * Returns the JSON representation for the given Point. This method accepts null,
   * which will be mapped to JsonValue.NULL.
   *
   * @param point the Point to encode or null
   * @return a JSON value that represents the given point
   */
  public static JsonValue toJson( Point point ) {
    return point == null ? JsonValue.NULL : new JsonArray().add( point.x ).add( point.y );
  }

  /**
   * Returns the JSON representation for the given array Point. This method accepts null,
   * which will be mapped to JsonValue.NULL.
   *
   * @param points the array Point to encode or null
   * @return a JSON value that represents the given point
   *
   * @since 3.13
   */
  public static JsonValue toJson( Point[] points ) {
    if( points == null ) {
      return JsonValue.NULL;
    }
    JsonArray jsonPoints = new JsonArray();
    for( Point point : points ) {
      jsonPoints.add( toJson( point ) );
    }
    return jsonPoints;
  }

  /**
   * Returns the JSON representation for the given Rectangle. This method accepts null,
   * which will be mapped to JsonValue.NULL.
   *
   * @param rect the Rectangle to encode or null
   * @return a JSON value that represents the given rectangle
   */
  public static JsonValue toJson( Rectangle rect ) {
    if( rect == null ) {
      return JsonValue.NULL;
    }
    return new JsonArray().add( rect.x ).add( rect.y ).add( rect.width ).add( rect.height );
  }

  /**
   * Returns the JSON representation for the given Color. This method accepts null,
   * which will be mapped to JsonValue.NULL. Disposed colors cannot be mapped to JSON.
   *
   * @param color the Color to encode or null, must not be disposed
   * @return a JSON value that represents the given color
   */
  public static JsonValue toJson( Color color ) {
    return toJson( color, 255 );
  }

  /**
   * Returns the JSON representation for the given Color with an additional alpha (opacity) value.
   * This method accepts null, which will be mapped to JsonValue.NULL
   * regardless of the given alpha value. Disposed colors cannot be mapped to JSON.
   *
   * @param color the Color to encode or null, must not be disposed
   * @param alpha a value in the range of 0 (transparent) to 255 (opaque)
   * @return a JSON value that represents the given color
   */
  public static JsonValue toJson( Color color, int alpha ) {
    if( alpha < 0 || alpha > 255 ) {
      throw new IllegalArgumentException( "Illegal alpha value: " + alpha );
    }
    if( color == null ) {
      return JsonValue.NULL;
    }
    if( color.isDisposed() ) {
      throw new IllegalArgumentException( "Color is disposed" );
    }
    return toJson( color.getRGB(), alpha );
  }

  /**
   * Returns the JSON representation for the given RGB. This method accepts null,
   * which will be mapped to JsonValue.NULL.
   *
   * @param rgb the Color to encode or null
   * @return a JSON value that represents the given color
   */
  public static JsonValue toJson( RGB rgb ) {
    return toJson( rgb, 255 );
  }

  /**
   * Returns the JSON representation for the given RGB with an additional alpha (opacity) value.
   * This method accepts null, which will be mapped to JsonValue.NULL
   * regardless of the given alpha value.
   *
   * @param rgb the RGB to encode or null
   * @param alpha a value in the range of 0 (transparent) to 255 (opaque)
   * @return a JSON value that represents the given rgb
   */
  public static JsonValue toJson( RGB rgb, int alpha ) {
    if( alpha < 0 || alpha > 255 ) {
      throw new IllegalArgumentException( "Illegal alpha value: " + alpha );
    }
    if( rgb == null ) {
      return JsonValue.NULL;
    }
    return new JsonArray().add( rgb.red ).add( rgb.green ).add( rgb.blue ).add( alpha );
  }

  /**
   * Returns the JSON representation for the given Image. This method accepts null,
   * which will be mapped to JsonValue.NULL. Disposed images cannot be mapped to JSON.
   *
   * @param image the Image to encode or null, must not be disposed
   * @return a JSON value that represents the given rgb
   */
  public static JsonValue toJson( Image image ) {
    if( image == null ) {
      return JsonValue.NULL;
    }
    if( image.isDisposed() ) {
      throw new IllegalArgumentException( "Image is disposed" );
    }
    String imagePath = ImageFactory.getImagePath( image );
    Rectangle bounds = image.getBounds();
    return new JsonArray()
      .add( imagePath )
      .add( bounds.width )
      .add( bounds.height );
  }

  /**
   * Returns the JSON representation for the given Font. This method accepts null,
   * which will be mapped to JsonValue.NULL. Disposed fonts cannot be mapped to JSON.
   *
   * @param font the Font to encode or null, must not be disposed
   * @return a JSON value that represents the given font
   */
  public static JsonValue toJson( Font font ) {
    if( font == null ) {
      return JsonValue.NULL;
    }
    if( font.isDisposed() ) {
      throw new IllegalArgumentException( "Font is disposed" );
    }
    return toJson( getData( font ) );
  }

  /**
   * Returns the JSON representation for the given FontData. This method accepts null,
   * which will be mapped to JsonValue.NULL.
   *
   * @param fontData the FontData to encode or null
   * @return a JSON value that represents the given font data
   */
  public static JsonValue toJson( FontData fontData ) {
    return fontData == null ? JsonValue.NULL : new JsonArray()
      .add( JsonUtil.createJsonArray( parseFontName( fontData.getName() ) ) )
      .add( fontData.getHeight() )
      .add( ( fontData.getStyle() & SWT.BOLD ) != 0 )
      .add( ( fontData.getStyle() & SWT.ITALIC ) != 0 );
  }

  /**
   * Returns the JSON representation for the given Cursor. This method accepts null,
   * which will be mapped to JsonValue.NULL.
   *
   * @param cursor the Cursor to encode or null
   * @return a JSON value that represents the given cursor
   *
   * @since 3.1
   */
  public static JsonValue toJson( Cursor cursor ) {
    if( cursor == null ) {
      return JsonValue.NULL;
    }
    // TODO [rst] Find a better way of obtaining the Cursor value
    // TODO [tb] adjust strings to match name of constants
    int value = 0;
    try {
      Field field = Cursor.class.getDeclaredField( "value" );
      field.setAccessible( true );
      value = field.getInt( cursor );
    } catch( Exception e ) {
      throw new RuntimeException( e );
    }
    switch( value ) {
      case SWT.CURSOR_ARROW:
        return JsonValue.valueOf( "default" );
      case SWT.CURSOR_WAIT:
        return JsonValue.valueOf( "wait" );
      case SWT.CURSOR_APPSTARTING:
        return JsonValue.valueOf( "progress" );
      case SWT.CURSOR_CROSS:
        return JsonValue.valueOf( "crosshair" );
      case SWT.CURSOR_HELP:
        return JsonValue.valueOf( "help" );
      case SWT.CURSOR_SIZEALL:
        return JsonValue.valueOf( "move" );
      case SWT.CURSOR_SIZENS:
        return JsonValue.valueOf( "row-resize" );
      case SWT.CURSOR_SIZEWE:
        return JsonValue.valueOf( "col-resize" );
      case SWT.CURSOR_SIZEN:
        return JsonValue.valueOf( "n-resize" );
      case SWT.CURSOR_SIZES:
        return JsonValue.valueOf( "s-resize" );
      case SWT.CURSOR_SIZEE:
        return JsonValue.valueOf( "e-resize" );
      case SWT.CURSOR_SIZEW:
        return JsonValue.valueOf( "w-resize" );
      case SWT.CURSOR_SIZENE:
      case SWT.CURSOR_SIZENESW:
        return JsonValue.valueOf( "ne-resize" );
      case SWT.CURSOR_SIZESE:
        return JsonValue.valueOf( "se-resize" );
      case SWT.CURSOR_SIZESW:
        return JsonValue.valueOf( "sw-resize" );
      case SWT.CURSOR_SIZENW:
      case SWT.CURSOR_SIZENWSE:
        return JsonValue.valueOf( "nw-resize" );
      case SWT.CURSOR_IBEAM:
        return JsonValue.valueOf( "text" );
      case SWT.CURSOR_HAND:
        return JsonValue.valueOf( "pointer" );
      case SWT.CURSOR_NO:
        return JsonValue.valueOf( "not-allowed" );
      case SWT.CURSOR_UPARROW:
        return JsonValue.valueOf( CURSOR_UPARROW );
      default:
        return JsonValue.NULL;
    }
  }

  /**
   * Returns an instance of Point for the given JSON representation. This method returns
   * null if the given JSON value is JsonValue.NULL.
   *
   * @param value a JsonValue that represents a point or JsonValue.NULL
   * @return a Point that corresponds to the given JSON value or null
   */
  public static Point readPoint( JsonValue value ) {
    ParamCheck.notNull( value, "value" );
    if( JsonValue.NULL.equals( value ) ) {
      return null;
    }
    try {
      JsonArray array = value.asArray();
      if( array.size() != 2 ) {
        throw new IllegalArgumentException( "array size != 2" );
      }
      return new Point( array.get( 0 ).asInt(), array.get( 1 ).asInt() );
    } catch( Exception exception ) {
      String message = "Could not create Point for: " + value;
      throw new IllegalArgumentException( message, exception );
    }
  }

  /**
   * Returns an instance of Rectangle for the given JSON representation. This method returns
   * null if the given JSON value is JsonValue.NULL.
   *
   * @param value a JsonValue that represents a rectangle or JsonValue.NULL
   * @return a Rectangle that corresponds to the given JSON value or null
   */
  public static Rectangle readRectangle( JsonValue value ) {
    ParamCheck.notNull( value, "value" );
    if( JsonValue.NULL.equals( value ) ) {
      return null;
    }
    try {
      JsonArray array = value.asArray();
      if( array.size() != 4 ) {
        throw new IllegalArgumentException( "array size != 4" );
      }
      return new Rectangle( array.get( 0 ).asInt(),
                            array.get( 1 ).asInt(),
                            array.get( 2 ).asInt(),
                            array.get( 3 ).asInt() );
    } catch( Exception exception ) {
      String message = "Could not create Rectangle for: " + value;
      throw new IllegalArgumentException( message, exception );
    }
  }

  /**
   * Returns an instance of RGB for the given JSON representation. This method returns
   * null if the given JSON value is JsonValue.NULL.
   *
   * @param value a JsonValue that represents a color or JsonValue.NULL
   * @return an RGB that corresponds to the given JSON value or null
   */
  public static RGB readRGB( JsonValue value ) {
    ParamCheck.notNull( value, "value" );
    if( value.isNull() ) {
      return null;
    }
    try {
      JsonArray array = value.asArray();
      if( array.size() < 3 || array.size() > 4 ) {
        throw new IllegalArgumentException( "Expected array of size 3 or 4" );
      }
      return new RGB( array.get( 0 ).asInt(), array.get( 1 ).asInt(), array.get( 2 ).asInt() );
    } catch( Exception exception ) {
      String message = "Could not create RGB for: " + value;
      throw new IllegalArgumentException( message, exception );
    }
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy