/******************************************************************************* * Copyright (c) 2007, 2015 Innoopract Informationssysteme GmbH 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: * Innoopract Informationssysteme GmbH - initial API and implementation * EclipseSource - ongoing development ******************************************************************************/ package org.eclipse.rap.rwt.internal.theme; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import org.eclipse.rap.rwt.RWT; import org.eclipse.rap.rwt.internal.theme.css.CssElementHolder; import org.eclipse.rap.rwt.internal.theme.css.StyleSheet; import org.eclipse.rap.rwt.service.ApplicationContext; import org.eclipse.rap.rwt.service.ResourceManager; public class Theme { private static final String JS_THEME_PREFIX = "rwt.theme."; private final String id; private final String jsId; private final String name; private StyleSheetBuilder styleSheetBuilder; private CssValuesMap valuesMap; private String registeredLocation; private CssElement[] elements; public Theme( String id, String name, StyleSheet styleSheet ) { if( id == null ) { throw new NullPointerException( "id" ); } this.id = id; this.name = name != null ? name : "Unnamed Theme"; jsId = createUniqueJsId( id ); valuesMap = null; styleSheetBuilder = new StyleSheetBuilder(); if( styleSheet != null ) { styleSheetBuilder.addStyleSheet( styleSheet ); } } public String getId() { return id; } public String getJsId() { return jsId; } public String getName() { return name; } public void addStyleSheet( StyleSheet styleSheet ) { if( valuesMap != null ) { throw new IllegalStateException( "Theme is already initialized" ); } styleSheetBuilder.addStyleSheet( styleSheet ); } public void initialize( ThemeableWidget[] themeableWidgets ) { elements = extractElements( themeableWidgets ); if( valuesMap != null ) { throw new IllegalStateException( "Theme is already initialized" ); } StyleSheet styleSheet = styleSheetBuilder.getStyleSheet(); valuesMap = new CssValuesMap( styleSheet, themeableWidgets ); styleSheetBuilder = null; } private static CssElement[] extractElements( ThemeableWidget[] themeableWidgets ) { CssElementHolder elements = new CssElementHolder(); for( ThemeableWidget themeableWidget : themeableWidgets ) { if( themeableWidget.elements != null ) { for( CssElement element : themeableWidget.elements ) { elements.addElement( element ); } } } return elements.getAllElements(); } public StyleSheet getStyleSheet() { return styleSheetBuilder.getStyleSheet(); } public CssValuesMap getValuesMap() { if( valuesMap == null ) { throw new IllegalStateException( "Theme is not initialized" ); } return valuesMap; } public String getRegisteredLocation() { return registeredLocation; } public void registerResources( ApplicationContext applicationContext ) { try { registerThemeResources( applicationContext ); registerThemeStoreFile( applicationContext ); } catch( IOException ioe ) { throw new ThemeManagerException( "Failed to register theme resources for theme " + id, ioe ); } } private void registerThemeResources( ApplicationContext applicationContext ) throws IOException { CssValue[] values = valuesMap.getAllValues(); for( CssValue value : values ) { if( value instanceof ThemeResource ) { registerResource( applicationContext, ( ThemeResource )value ); } } } private void registerThemeStoreFile( ApplicationContext applicationContext ) { ThemeStoreWriter storeWriter = new ThemeStoreWriter( applicationContext, this, elements ); String name = "rap-" + jsId + ".json"; String code = storeWriter.createJson(); registeredLocation = registerResource( applicationContext, name, code ); } private static void registerResource( ApplicationContext applicationContext, ThemeResource value ) throws IOException { String registerPath = value.getResourcePath( applicationContext ); if( registerPath != null ) { InputStream inputStream = value.getResourceAsStream(); if( inputStream == null ) { throw new IllegalArgumentException( "Resource not found for theme property: " + value ); } try { applicationContext.getResourceManager().register( registerPath, inputStream ); } finally { inputStream.close(); } } } private static String registerResource( ApplicationContext applicationContext, String name, String content ) { byte[] buffer; try { buffer = content.getBytes( "UTF-8" ); } catch( UnsupportedEncodingException shouldNotHappen ) { throw new RuntimeException( shouldNotHappen ); } InputStream inputStream = new ByteArrayInputStream( buffer ); ResourceManager resourceManager = applicationContext.getResourceManager(); resourceManager.register( name, inputStream ); return resourceManager.getLocation( name ); } private static String createUniqueJsId( String id ) { if( RWT.DEFAULT_THEME_ID.equals( id ) ) { return JS_THEME_PREFIX + "Default"; } if( ThemeManager.FALLBACK_THEME_ID.equals( id ) ) { return JS_THEME_PREFIX + "Fallback"; } String hash = Integer.toHexString( id.hashCode() ); return JS_THEME_PREFIX + "Custom_" + hash; } }