/******************************************************************************* * Copyright (c) 2008, 2009 Innoopract Informationssysteme GmbH. * 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.rwt.internal.theme.css; import java.util.*; import org.eclipse.rwt.internal.theme.QxType; import org.w3c.css.sac.Selector; import org.w3c.css.sac.SelectorList; /** * Instances of this class represent a parsed CSS stylesheet. */ public final class StyleSheet { private static final SelectorWrapperComparator COMPARATOR = new SelectorWrapperComparator(); private final StyleRule[] styleRules; private SelectorWrapper[] selectorWrappers; public StyleSheet( final StyleRule[] styleRules ) { this.styleRules = ( StyleRule[] )styleRules.clone(); createSelectorWrappers(); } public StyleRule[] getStyleRules() { return ( StyleRule[] )styleRules.clone(); } public ConditionalValue[] getValues( final String elementName, final String propertyName ) { List buffer = new ArrayList(); for( int i = 0; i < selectorWrappers.length; i++ ) { SelectorWrapper selectorWrapper = selectorWrappers[ i ]; String selectorElement = ( ( SelectorExt )selectorWrapper.selector ).getElementName(); if( selectorElement == null || selectorElement.equals( elementName ) ) { QxType value = selectorWrapper.propertyMap.getValue( propertyName ); if( value != null ) { String[] constraints = ( ( SelectorExt )selectorWrapper.selector ).getConstraints(); Arrays.sort( constraints ); if( !containsConstraintsAlready( buffer, constraints ) ) { buffer.add( new ConditionalValue( constraints, value ) ); } } } } ConditionalValue[] result = new ConditionalValue[ buffer.size() ]; buffer.toArray( result ); return result; } public String toString() { StringBuffer buffer = new StringBuffer(); StyleRule[] styleRules = getStyleRules(); for( int i = 0; i < styleRules.length; i++ ) { StyleRule styleRule = styleRules[ i ]; SelectorList selectors = styleRule.getSelectors(); int length = selectors.getLength(); for( int j = 0; j < length; j++ ) { if( j > 0 ) { buffer.append( "," ); } if( i > 0 ) { buffer.append( "\n" ); } buffer.append( selectors.item( j ) ); } buffer.append( "\n" ); buffer.append( styleRule.getProperties() ); buffer.append( "\n" ); } return buffer.toString(); } private static boolean containsConstraintsAlready( List conditionalValuesList, String[] constraints ) { Iterator iterator = conditionalValuesList.iterator(); boolean result = false; while( iterator.hasNext() && !result ) { ConditionalValue condValue = ( ConditionalValue )iterator.next(); if( Arrays.equals( condValue.constraints, constraints ) ) { result = true; } } return result; } private void createSelectorWrappers() { ArrayList selectorWrappersList = new ArrayList(); for( int pos = 0; pos < styleRules.length; pos++ ) { StyleRule styleRule = styleRules[ pos ]; SelectorList selectors = styleRule.getSelectors(); IStylePropertyMap properties = styleRule.getProperties(); int length = selectors.getLength(); for( int i = 0; i < length; i++ ) { Selector selector = selectors.item( i ); SelectorWrapper selectorWrapper = new SelectorWrapper( selector, properties, pos ); selectorWrappersList.add( selectorWrapper ); } } Collections.sort( selectorWrappersList, COMPARATOR ); Collections.reverse( selectorWrappersList ); selectorWrappers = new SelectorWrapper[ selectorWrappersList.size() ]; selectorWrappersList.toArray( selectorWrappers ); } static class SelectorWrapper { public final Selector selector; public final IStylePropertyMap propertyMap; public final int position; public SelectorWrapper( final Selector selector, final IStylePropertyMap propertyMap, final int position ) { this.selector = selector; this.propertyMap = propertyMap; this.position = position; } } private static class SelectorWrapperComparator implements Comparator { public int compare( final Object object1, final Object object2 ) { int result = 0; SelectorWrapper selectorWrapper1 = ( SelectorWrapper )object1; SelectorWrapper selectorWrapper2 = ( SelectorWrapper )object2; int specificity1 = ( ( Specific )selectorWrapper1.selector ).getSpecificity(); int specificity2 = ( ( Specific )selectorWrapper2.selector ).getSpecificity(); if( specificity1 > specificity2 ) { result = 1; } else if( specificity1 < specificity2 ) { result = -1; } else if( selectorWrapper1.position > selectorWrapper2.position ) { result = 1; } else if( selectorWrapper1.position < selectorWrapper2.position ) { result = -1; } return result; } } }