/*******************************************************************************
* Copyright (c) 2011, 2015 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.internal.theme;
import static org.eclipse.rap.rwt.internal.protocol.JsonUtil.createJsonArray;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.rap.json.JsonArray;
import org.eclipse.rap.json.JsonObject;
import org.eclipse.rap.json.JsonValue;
import org.eclipse.rap.rwt.internal.protocol.JsonUtil;
import org.eclipse.rap.rwt.internal.theme.CssAnimation.Animation;
import org.eclipse.rap.rwt.service.ApplicationContext;
import org.eclipse.rap.rwt.theme.BoxDimensions;
public final class ThemePropertyAdapterRegistry {
static interface ThemePropertyAdapter {
/**
* The slot in the client's theme store to write the value into or <code>null</code> if no value
* needs to be written.
*/
String getSlot( CssValue value );
/**
* The id that references the property in the client's theme store of the value itself if no
* translation is needed.
*/
String getKey( CssValue value );
/**
* The value to write into the client's theme store or <code>null</code> if no value needs to be
* written.
*/
JsonValue getValue( CssValue value );
}
static class DirectPropertyAdapter implements ThemePropertyAdapter {
@Override
public String getKey( CssValue value ) {
return value.toDefaultString();
}
@Override
public String getSlot( CssValue value ) {
return null;
}
@Override
public JsonValue getValue( CssValue value ) {
return null;
}
}
static class DimensionPropertyAdapter implements ThemePropertyAdapter {
@Override
public String getKey( CssValue value ) {
return Integer.toHexString( value.hashCode() );
}
@Override
public String getSlot( CssValue value ) {
return "dimensions";
}
@Override
public JsonValue getValue( CssValue value ) {
return JsonValue.valueOf( ( ( CssDimension )value ).value );
}
}
static class BoxDimensionsPropertyAdapter implements ThemePropertyAdapter {
@Override
public String getKey( CssValue value ) {
return Integer.toHexString( value.hashCode() );
}
@Override
public String getSlot( CssValue value ) {
return "boxdims";
}
@Override
public JsonValue getValue( CssValue value ) {
BoxDimensions boxdim = ( ( CssBoxDimensions )value ).dimensions;
JsonArray result = new JsonArray();
result.add( boxdim.top );
result.add( boxdim.right );
result.add( boxdim.bottom );
result.add( boxdim.left );
return result;
}
}
static class FontPropertyAdapter implements ThemePropertyAdapter {
@Override
public String getKey( CssValue value ) {
return Integer.toHexString( value.hashCode() );
}
@Override
public String getSlot( CssValue value ) {
return "fonts";
}
@Override
public JsonValue getValue( CssValue value ) {
CssFont font = ( CssFont )value;
JsonObject result = new JsonObject();
result.add( "family", JsonUtil.createJsonArray( font.family ) );
result.add( "size", font.size );
result.add( "bold", font.bold );
result.add( "italic", font.italic );
return result;
}
}
static class ImagePropertyAdapter implements ThemePropertyAdapter {
@Override
public String getKey( CssValue value ) {
return createKey( value );
}
@Override
public String getSlot( CssValue value ) {
String result;
CssImage image = ( CssImage )value;
if( image.isGradient() ) {
result = "gradients";
} else {
result = "images";
}
return result;
}
@Override
public JsonValue getValue( CssValue value ) {
CssImage image = ( CssImage )value;
JsonValue result = null;
if( image.isGradient() ) {
JsonObject gradientObject = null;
gradientObject = new JsonObject();
JsonValue percents = createJsonArray( image.gradientPercents );
gradientObject.add( "percents", percents );
JsonValue colors = createJsonArray( image.gradientColors );
gradientObject.add( "colors", colors );
gradientObject.add( "vertical", image.vertical );
result = gradientObject;
} else if( !image.none ) {
Size imageSize = image.getSize();
result = new JsonArray().add( imageSize.width ).add( imageSize.height );
}
return result;
}
private static String createKey( CssValue value ) {
String result = Integer.toHexString( value.hashCode() );
CssImage image = ( CssImage )value;
if( image.path != null ) {
int index = image.path.lastIndexOf( '.' );
if( index >= 0 ) {
result = result + image.path.substring( index );
}
}
return result;
}
}
static class ColorPropertyAdapter implements ThemePropertyAdapter {
@Override
public String getKey( CssValue value ) {
return Integer.toHexString( value.hashCode() );
}
@Override
public String getSlot( CssValue value ) {
return "colors";
}
@Override
public JsonValue getValue( CssValue value ) {
CssColor color = ( CssColor )value;
JsonValue result;
if( color.isTransparent() ) {
result = JsonValue.valueOf( "undefined" );
} else {
JsonArray colorArray = new JsonArray();
colorArray.add( color.red );
colorArray.add( color.green );
colorArray.add( color.blue );
colorArray.add( color.alpha );
result = colorArray;
}
return result;
}
}
static class BorderPropertyAdapter implements ThemePropertyAdapter {
@Override
public String getKey( CssValue value ) {
return Integer.toHexString( value.hashCode() );
}
@Override
public String getSlot( CssValue value ) {
return "borders";
}
@Override
public JsonValue getValue( CssValue value ) {
CssBorder border = ( CssBorder )value;
JsonObject result = new JsonObject();
result.add( "width", border.width );
result.add( "style", border.style );
result.add( "color", border.color == null ? null : border.color.toDefaultString() );
return result;
}
}
static class CursorPropertyAdapter implements ThemePropertyAdapter {
@Override
public String getKey( CssValue value ) {
return createKey( value );
}
@Override
public String getSlot( CssValue value ) {
return "cursors";
}
@Override
public JsonValue getValue( CssValue value ) {
CssCursor cursor = ( CssCursor )value;
JsonValue result;
if( cursor.isCustomCursor() ) {
result = JsonValue.NULL;
} else {
result = JsonValue.valueOf( cursor.value );
}
return result;
}
private static String createKey( CssValue value ) {
String result = Integer.toHexString( value.hashCode() );
CssCursor cursor = ( CssCursor )value;
if( cursor.isCustomCursor() ) {
int index = cursor.value.lastIndexOf( '.' );
if( index >= 0 ) {
result = result + cursor.value.substring( index );
}
}
return result;
}
}
static class AnimationPropertyAdapter implements ThemePropertyAdapter {
@Override
public String getKey( CssValue value ) {
return Integer.toHexString( value.hashCode() );
}
@Override
public String getSlot( CssValue value ) {
return "animations";
}
@Override
public JsonValue getValue( CssValue value ) {
CssAnimation animation = ( CssAnimation )value;
JsonObject result = new JsonObject();
for( int j = 0; j < animation.animations.length; j++ ) {
Animation currentAnimation = animation.animations[ j ];
JsonArray currentAnimationArray = new JsonArray();
currentAnimationArray.add( currentAnimation.duration );
String timingFunction = CssAnimation.toCamelCaseString( currentAnimation.timingFunction );
currentAnimationArray.add( timingFunction );
result.add( currentAnimation.name, currentAnimationArray );
}
return result;
}
}
static class ShadowPropertyAdapter implements ThemePropertyAdapter {
@Override
public String getKey( CssValue value ) {
return Integer.toHexString( value.hashCode() );
}
@Override
public String getSlot( CssValue value ) {
return "shadows";
}
@Override
public JsonValue getValue( CssValue value ) {
CssShadow shadow = ( CssShadow )value;
JsonValue result;
if( shadow.equals( CssShadow.NONE ) ) {
result = JsonValue.NULL;
} else {
JsonArray array = new JsonArray();
array.add( shadow.inset );
array.add( shadow.offsetX );
array.add( shadow.offsetY );
array.add( shadow.blur );
array.add( shadow.spread );
array.add( shadow.color );
array.add( shadow.opacity );
result = array;
}
return result;
}
}
private static final Object LOCK = new Object();
private static final String ATTR_NAME
= ThemePropertyAdapterRegistry.class.getName() + "#instance";
public static ThemePropertyAdapterRegistry getInstance( ApplicationContext applicationContext ) {
ThemePropertyAdapterRegistry result;
synchronized( LOCK ) {
result = ( ThemePropertyAdapterRegistry )applicationContext.getAttribute( ATTR_NAME );
if( result == null ) {
result = new ThemePropertyAdapterRegistry();
applicationContext.setAttribute( ATTR_NAME, result );
}
}
return result;
}
private final Map<Class<? extends CssValue>,ThemePropertyAdapter> map;
private ThemePropertyAdapterRegistry() {
map = new HashMap<>();
map.put( CssAnimation.class, new AnimationPropertyAdapter() );
map.put( CssBorder.class, new BorderPropertyAdapter() );
map.put( CssBoxDimensions.class, new BoxDimensionsPropertyAdapter() );
map.put( CssColor.class, new ColorPropertyAdapter() );
map.put( CssCursor.class, new CursorPropertyAdapter() );
map.put( CssDimension.class, new DimensionPropertyAdapter() );
map.put( CssFloat.class, new DirectPropertyAdapter() );
map.put( CssFont.class, new FontPropertyAdapter() );
map.put( CssIdentifier.class, new DirectPropertyAdapter() );
map.put( CssImage.class, new ImagePropertyAdapter() );
map.put( CssShadow.class, new ShadowPropertyAdapter() );
}
ThemePropertyAdapter getPropertyAdapter( Class<?> key ) {
return map.get( key );
}
}