diff -r b4183b61e0c7 -r 58764cb313d3 themeinstaller/source/src/com/nokia/tools/themeinstaller/cssparser/CSSHandler.java --- a/themeinstaller/source/src/com/nokia/tools/themeinstaller/cssparser/CSSHandler.java Tue Jan 26 13:19:36 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,588 +0,0 @@ -/* -* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: This class gets notified during the CSS file parsing - * -*/ - - -package com.nokia.tools.themeinstaller.cssparser; - -import java.awt.Color; -import java.io.File; -import java.io.FileReader; -import java.io.Reader; -import java.util.HashMap; -import java.util.Vector; - -import org.w3c.css.sac.CSSException; -import org.w3c.css.sac.DocumentHandler; -import org.w3c.css.sac.InputSource; -import org.w3c.css.sac.LexicalUnit; -import org.w3c.css.sac.Parser; -import org.w3c.css.sac.SACMediaList; -import org.w3c.css.sac.SelectorList; -import org.w3c.css.sac.helpers.ParserFactory; -import org.w3c.dom.Document; - -import com.nokia.tools.themeinstaller.logger.LogWriter; - -/** - * The Class CSSHandler. Informs application of basic parsing events. This - * should be registered with CSS Parser with setDocumentHandler method. - * - * Handler gets notified during the CSS parsing: - * 1. startSelector(), when new selector is noticed - * 2. property(), when new property is noticed - * 3. lexicalValue() is used to calculate the values of the parsed property - * - * If you are using CSS import with paths relative to main CSS, you need to - * set the path of main CSS using setImportDirectory( String aImportDirectory ) - */ - -public class CSSHandler implements DocumentHandler - { - - /** The style map for style property. */ - private HashMap iStyleMap; - - /** List of parsed rules. */ - private Vector iRuleList; - - /** The DOM document. */ - private Document iDocument; - - /** Color resolver for resolving colors in string form */ - private ColorResolver iColorResolver; - - /** The main CSS directory for finding imported CSS File's relative path. */ - private String iImportDirectory; - - /** The Constant FUNCTION_HSL. */ - public static final String FUNCTION_HSL = "hsl"; - - /** The Constant COMMA. */ - public static final String COMMA = ","; - - /** The Constant CHAR_APOSTROPHE. */ - private static final char CHAR_APOSTROPHE = '"'; - - /** The Constant CHAR_SPACE. */ - private static final char CHAR_SPACE = ' '; - - /** The Constant CHAR_COLON. */ - private static final char CHAR_COLON = ':'; - - /** The Constant SEPARATOR. */ - public static final String SEPARATOR = "|"; - - /** The Constant FORWARD_SLASH. */ - public static final String FORWARD_SLASH = "/"; - - /** The Constant BACKWARD_SLASH. */ - public static final String BACKWARD_SLASH = "\\"; - - /** The CSS to DOM Processor for applying changes to DOM. */ - private CSSDOMProcessor iCSSDOMProcessor; - - /** - * Instantiates a new CSS handler. - */ - public CSSHandler() - { - super(); - iCSSDOMProcessor = new CSSDOMProcessor(); - iStyleMap = new HashMap(); - iRuleList = new Vector(); - iColorResolver = new ColorResolver(); - } - - /** - * Instantiates a new CSS handler. This one is used for handling imported - * CSS files - * - * @param aHandler The handler to retrieve previous rule list and DOM document - * from - */ - private CSSHandler( CSSHandler aHandler ) - { - super(); - iCSSDOMProcessor = new CSSDOMProcessor(); - iStyleMap = new HashMap(); - - iRuleList = aHandler.iRuleList; - iDocument = aHandler.iDocument; - iColorResolver = new ColorResolver(); - } - - /** - * Sets the document. - * - * @param aDocument The new document - */ - public void setDocument( Document aDocument ) - { - iDocument = aDocument; - } - - /** - * Gets the document. - * - * @return the document - */ - public Document getDocument() - { - return iDocument; - } - - /** - * Sets the directory of main CSS. - * - * @param aImportDirectory The directory of main CSS - */ - public void setImportDirectory( String aImportDirectory ) - { - iImportDirectory = aImportDirectory; - } - - /* - * (non-Javadoc) - * - * @see org.w3c.css.sac.DocumentHandler#startDocument(org.w3c.css.sac.InputSource) - */ - public void startDocument( InputSource arg0 ) throws CSSException - { - iRuleList = new Vector(); - } - - /* - * (non-Javadoc) - * - * @see org.w3c.css.sac.DocumentHandler#startSelector(org.w3c.css.sac.SelectorList) - */ - public void startSelector( SelectorList aSelectorList ) throws CSSException - { - iStyleMap = new HashMap(); - } - - /* - * (non-Javadoc) - * - * @see org.w3c.css.sac.DocumentHandler#endSelector(org.w3c.css.sac.SelectorList) - */ - public void endSelector( SelectorList aSelectors ) throws CSSException - { - if ( iStyleMap.size() != 0 ) - { - for ( int i = 0; i < aSelectors.getLength(); i++ ) - { -// System.out.println("CSSHandler Selectors --> "+aSelectors.item(i)); - CSSRule rule = new CSSRule( aSelectors.item( i ), iStyleMap ); - iRuleList.add( rule ); - } - } - } - - /* - * (non-Javadoc) - * - * @see org.w3c.css.sac.DocumentHandler#property(java.lang.String, - * org.w3c.css.sac.LexicalUnit, boolean) - */ - public void property( String aName, LexicalUnit aLexicalUnit, - boolean aImportant ) throws CSSException - { - Vector propertyValues = new Vector(); - lexicalValue( aLexicalUnit, propertyValues ); - iStyleMap.put( aName, new CSSStyleProperty( propertyValues, aImportant ) ); - } - - /* - * (non-Javadoc) - * - * @see org.w3c.css.sac.DocumentHandler#endDocument(org.w3c.css.sac.InputSource) - */ - public void endDocument( InputSource aInputSource ) throws CSSException - { - if ( iDocument == null ) - { - throw new IllegalStateException( "CSSHandler has null DOM Document" ); - } - - iCSSDOMProcessor.applyRulesToDom( iDocument, iRuleList ); - } - - - /** - * Finds out the property values and adds them into a Vector - * aPropertyValues. Property types that are taken into account are - * from Symbian side: ...\Xuikon\Dom\src\xndompropertyvalue.cpp - * - * @param aLexicalUnit Value - * @param aPropertyValues Vector for Property values - */ - public void lexicalValue( LexicalUnit aLexicalUnit, - Vector aPropertyValues ) - { - while ( aLexicalUnit != null ) - { - switch ( aLexicalUnit.getLexicalUnitType() ) - { - case LexicalUnit.SAC_OPERATOR_COMMA: - break; - // Allowed cases for integer value - case LexicalUnit.SAC_INTEGER: - aPropertyValues - .add( new CSSPropertyValue( - LexicalUnit.SAC_INTEGER, Integer - .toString( aLexicalUnit - .getIntegerValue() ) ) ); - break; - // Allowed cases for real value - // Fallthrough - case LexicalUnit.SAC_REAL: - case LexicalUnit.SAC_DIMENSION: - case LexicalUnit.SAC_EM: - case LexicalUnit.SAC_EX: - case LexicalUnit.SAC_INCH: - case LexicalUnit.SAC_PIXEL: - case LexicalUnit.SAC_CENTIMETER: - case LexicalUnit.SAC_MILLIMETER: - case LexicalUnit.SAC_POINT: - case LexicalUnit.SAC_PICA: - case LexicalUnit.SAC_PERCENTAGE: - case LexicalUnit.SAC_DEGREE: - case LexicalUnit.SAC_GRADIAN: - case LexicalUnit.SAC_RADIAN: - case LexicalUnit.SAC_MILLISECOND: - case LexicalUnit.SAC_SECOND: - case LexicalUnit.SAC_HERTZ: - case LexicalUnit.SAC_KILOHERTZ: - aPropertyValues.add( new CSSPropertyValue( aLexicalUnit - .getLexicalUnitType(), Float.toString( aLexicalUnit - .getFloatValue() ) ) ); - break; - // RGB Values - case LexicalUnit.SAC_RGBCOLOR: - //Using StringBuffer to store values of RGB property - //in order to handle values (R,G and B) as one value - StringBuffer sb = new StringBuffer(); - colorValue( aLexicalUnit.getParameters(), sb ); - aPropertyValues.add( new CSSPropertyValue( aLexicalUnit - .getLexicalUnitType(), sb.toString() ) ); - break; - // Allowed cases for string values - // Fallthrough - case LexicalUnit.SAC_URI: - case LexicalUnit.SAC_IDENT: - case LexicalUnit.SAC_STRING_VALUE: - case LexicalUnit.SAC_ATTR: - // Color value as string - if ( iColorResolver.get( aLexicalUnit.getStringValue() ) != null ) - { - Color color = ( Color ) iColorResolver.get( aLexicalUnit - .getStringValue() ); - aPropertyValues.add( new CSSPropertyValue( - LexicalUnit.SAC_RGBCOLOR, - LexicalUnit.SAC_INTEGER + SEPARATOR - + color.getRed() + COMMA - + LexicalUnit.SAC_INTEGER + SEPARATOR - + color.getGreen() + COMMA - + LexicalUnit.SAC_INTEGER + SEPARATOR - + color.getBlue() ) ); - } - // Space - else if ( aLexicalUnit.getStringValue() - .indexOf( CHAR_SPACE ) != -1 ) - { - aPropertyValues.add( new CSSPropertyValue( aLexicalUnit - .getLexicalUnitType(), CHAR_APOSTROPHE - + aLexicalUnit.getStringValue() - + CHAR_APOSTROPHE ) ); - } - // Text - else - { - aPropertyValues.add( new CSSPropertyValue( aLexicalUnit - .getLexicalUnitType(), aLexicalUnit - .getStringValue() ) ); - } - break; - // In case value is set as "inherit" already in CSS -file - // This sets it to DOM as Ident value that is "inherit" - case LexicalUnit.SAC_INHERIT: - aPropertyValues.add( new CSSPropertyValue( - LexicalUnit.SAC_IDENT, - CSSDOMProcessor.STRING_INHERIT ) ); - break; - case LexicalUnit.SAC_FUNCTION: - String functionName = aLexicalUnit.getFunctionName(); - if ( functionName.equals( FUNCTION_HSL ) ) - { - Color color = colorFromHsl( aLexicalUnit - .getParameters() ); - aPropertyValues.add( new CSSPropertyValue( - LexicalUnit.SAC_RGBCOLOR, - LexicalUnit.SAC_INTEGER + SEPARATOR - + color.getRed() + COMMA - + LexicalUnit.SAC_INTEGER + SEPARATOR - + color.getGreen() + COMMA - + LexicalUnit.SAC_INTEGER + SEPARATOR - + color.getBlue() ) ); - - } - else - { - throw new IllegalStateException( - "Unknown CSS Function : " + functionName ); - } - break; - default: - break; - } - aLexicalUnit = aLexicalUnit.getNextLexicalUnit(); - } - } - - /** - * Parses HSL Function using ColorResolver. - * - * @param aLexicalUnit Parameters containing color values - * - * @return the color - */ - private Color colorFromHsl( LexicalUnit aLexicalUnit ) - { - float h = 0; - float s = 0; - float l = 0; - try - { - h = ( float ) aLexicalUnit.getIntegerValue(); - aLexicalUnit = aLexicalUnit.getNextLexicalUnit() - .getNextLexicalUnit(); - s = aLexicalUnit.getFloatValue(); - aLexicalUnit = aLexicalUnit.getNextLexicalUnit() - .getNextLexicalUnit(); - l = aLexicalUnit.getFloatValue(); - } - catch ( RuntimeException e ) - { - throw new IllegalStateException( "Illegal HSL Color values" ); - } - if ( aLexicalUnit.getNextLexicalUnit() != null ) - { - throw new IllegalStateException( "Too many parameters in HSL color" ); - } - return iColorResolver.hslToRgb( h, s, l ); - } - - /** - * Finds out the property values for RGB color and adds them into a - * StringBuffer aProperty. - * - * @param aLexicalUnit Parameters containing color values - * @param aProperty StringBuffer for storing property information - */ - public void colorValue( LexicalUnit aLexicalUnit, StringBuffer aProperty ) - { - while ( aLexicalUnit != null ) - { - switch ( aLexicalUnit.getLexicalUnitType() ) - { - // Operator "," - case LexicalUnit.SAC_OPERATOR_COMMA: - aProperty.append( COMMA ); - break; - case LexicalUnit.SAC_INTEGER: - aProperty.append( aLexicalUnit.getLexicalUnitType() ); - aProperty.append( SEPARATOR ); - aProperty.append( aLexicalUnit.getIntegerValue() ); - break; - case LexicalUnit.SAC_PERCENTAGE: - aProperty.append( LexicalUnit.SAC_INTEGER ); - aProperty.append( SEPARATOR ); - aProperty.append( iColorResolver - .getColorValueFromPercentage( aLexicalUnit - .getFloatValue() ) ); - break; - default: - break; - } - aLexicalUnit = aLexicalUnit.getNextLexicalUnit(); - } - } - - /* - * (non-Javadoc) - * - * @see org.w3c.css.sac.DocumentHandler#startFontFace () - */ - public void startFontFace() throws CSSException - { - } - - /* - * (non-Javadoc) - * - * @see org.w3c.css.sac.DocumentHandler#startPage(java.lang.String, - * java.lang.String) - */ - public void startPage( String arg0, String arg1 ) throws CSSException - { - } - - /* - * (non-Javadoc) - * - * @see org.w3c.css.sac.DocumentHandler#endFontFace () - */ - public void endFontFace() throws CSSException - { - } - - /* - * (non-Javadoc) - * - * @see org.w3c.css.sac.DocumentHandler#endPage(java.lang.String, - * java.lang.String) - */ - public void endPage( String arg0, String arg1 ) throws CSSException - { - } - - /* - * (non-Javadoc) - * - * @see org.w3c.css.sac.DocumentHandler#comment (java.lang.String) - */ - public void comment( String arg0 ) throws CSSException - { - } - - /* - * (non-Javadoc) - * - * @see org.w3c.css.sac.DocumentHandler#endMedia (org.w3c.css.sac.SACMediaList) - */ - public void endMedia( SACMediaList arg0 ) throws CSSException - { - } - - /* - * (non-Javadoc) - * - * @see org.w3c.css.sac.DocumentHandler#ignorableAtRule (java.lang.String) - */ - public void ignorableAtRule( String arg0 ) throws CSSException - { - } - - /* - * (non-Javadoc) - * - * @see org.w3c.css.sac.DocumentHandler#importStyle (java.lang.String, - * org.w3c.css.sac.SACMediaList, java.lang.String) - */ - public void importStyle( String aCSSFileName, SACMediaList aMedia, - String aNameSpaceUri ) throws CSSException - { - try - { - CSSHandler handler = new CSSHandler( this ); - ParserFactory factory = new ParserFactory(); - - Parser parser = factory.makeParser(); - parser.setDocumentHandler( handler ); - Reader r = null; - - File cssImport = new File( aCSSFileName ); - if ( isAbsolutePath( aCSSFileName ) && cssImport.exists() ) - { - // The imported CSS file is given with absolute path - r = new FileReader( aCSSFileName ); - LogWriter.getInstance().logInfo( - "Imported CSS : " + cssImport.getAbsolutePath() ); - } - else if ( !isAbsolutePath( aCSSFileName ) - && iImportDirectory != null ) - { - // If the given imported CSS File is not found, - // try to locate it using path relative to main CSS - File relativeCSS = new File( iImportDirectory + File.separator - + aCSSFileName ); - r = new FileReader( relativeCSS ); - LogWriter.getInstance().logInfo( - "Imported CSS : " + relativeCSS.getAbsolutePath() ); - } - else - { - throw new IllegalStateException( - "Can't resolve imported CSS File: " + aCSSFileName ); - } - - InputSource is = new InputSource( r ); - parser.parseStyleSheet( is ); - } - catch ( Exception e ) - { - throw new CSSException( e.getMessage() ); - } - } - - /** - * Checks if path is absolute path. - * Path is absolute if it starts with '/', '\' - * or is of form [drive]:[path] - * @param aFilePath the a file path - * - * @return true, if is absolute path - */ - private boolean isAbsolutePath( String aFilePath ) - { - if ( aFilePath.startsWith( FORWARD_SLASH ) ) - { - return true; - } - if ( aFilePath.startsWith( BACKWARD_SLASH ) ) - { - return true; - } - if ( aFilePath.length() > 1 && aFilePath.charAt( 1 ) == CHAR_COLON ) - { - return true; - } - return false; - } - - /* - * (non-Javadoc) - * - * @see org.w3c.css.sac.DocumentHandler#namespaceDeclaration(java.lang.String, - * java.lang.String) - */ - public void namespaceDeclaration( String arg0, String arg1 ) - throws CSSException - { - } - - /* - * (non-Javadoc) - * - * @see org.w3c.css.sac.DocumentHandler#startMedia(org.w3c.css.sac.SACMediaList) - */ - public void startMedia( SACMediaList arg0 ) throws CSSException - { - } - - }