Package org.pentaho.reporting.engine.classic.core.style.css

Source Code of org.pentaho.reporting.engine.classic.core.style.css.CSSStyleResolver

/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2002-2013 Pentaho Corporation..  All rights reserved.
*/

package org.pentaho.reporting.engine.classic.core.style.css;

import java.util.ArrayList;
import java.util.Collection;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.reporting.engine.classic.core.AttributeNames;
import org.pentaho.reporting.engine.classic.core.ReportDefinition;
import org.pentaho.reporting.engine.classic.core.ReportElement;
import org.pentaho.reporting.engine.classic.core.style.ElementStyleSheet;
import org.pentaho.reporting.engine.classic.core.style.ResolverStyleSheet;
import org.pentaho.reporting.engine.classic.core.style.StyleKey;
import org.pentaho.reporting.engine.classic.core.style.css.namespaces.NamespaceCollection;
import org.pentaho.reporting.engine.classic.core.style.css.selector.SelectorWeight;
import org.pentaho.reporting.engine.classic.core.style.resolver.SimpleStyleResolver;
import org.pentaho.reporting.engine.classic.core.style.resolver.StyleResolver;
import org.pentaho.reporting.libraries.resourceloader.Resource;
import org.pentaho.reporting.libraries.resourceloader.ResourceException;
import org.pentaho.reporting.libraries.resourceloader.ResourceKey;
import org.pentaho.reporting.libraries.resourceloader.ResourceKeyCreationException;
import org.pentaho.reporting.libraries.resourceloader.ResourceManager;


/**
* A cascading style resolver. This resolver follows the cascading rules
* as outlined by the Cascading Stylesheet Standard.
*
* @author Thomas Morgner
*/
public class CSSStyleResolver implements StyleResolver, Cloneable
{
  private static final Log logger = LogFactory.getLog(CSSStyleResolver.class);

  private StyleRuleMatcher styleRuleMatcher;
  private DocumentContext documentContext;
  private NamespaceCollection namespaces;
  private SimpleStyleResolver simpleStyleResolver;

  public CSSStyleResolver()
  {
    this(false);
  }

  public CSSStyleResolver(final boolean designTime)
  {
    this.simpleStyleResolver = new SimpleStyleResolver(designTime);
  }

  public static StyleResolver createDesignTimeResolver(final ReportDefinition report,
                                                        final ResourceManager resourceManager,
                                                        final ResourceKey contentBase,
                                                        final boolean designTime)
  {
    final ElementStyleDefinition styleDefinition = createStyleDefinition(report, resourceManager, contentBase);

    if (styleDefinition.getRuleCount() == 0 && styleDefinition.getStyleSheetCount() == 0)
    {
      return new SimpleStyleResolver(designTime);
    }
    else
    {
      final CSSStyleResolver resolver = new CSSStyleResolver(designTime);
      final NamespaceCollection namespaceCollection = StyleSheetParserUtil.getInstance().getNamespaceCollection();
      final DefaultDocumentContext documentContext =
          new DefaultDocumentContext(namespaceCollection, resourceManager, contentBase, null, styleDefinition);
      resolver.initialize(documentContext);
      return resolver;
    }
  }

  private static ElementStyleDefinition createStyleDefinition(final ReportDefinition reportDefinition,
                                                              final ResourceManager resourceManager,
                                                              final ResourceKey contentBase)
  {
    final ElementStyleDefinition styleDefinition;
    final Object maybeStyleSheet = reportDefinition.getAttribute(AttributeNames.Core.NAMESPACE, AttributeNames.Core.STYLE_SHEET);
    if (maybeStyleSheet instanceof ElementStyleDefinition)
    {
      final ElementStyleDefinition sd = (ElementStyleDefinition) maybeStyleSheet;
      styleDefinition = sd.clone();
    }
    else
    {
      styleDefinition = new ElementStyleDefinition();
    }

    final Object styleSheetRefs = reportDefinition.getAttribute(AttributeNames.Core.NAMESPACE, AttributeNames.Core.STYLE_SHEET_REFERENCE);
    final ArrayList<Object> styleRefs = new ArrayList<Object>();
    if (styleSheetRefs instanceof Object[])
    {
      final Object[] styleArray = (Object[]) styleSheetRefs;
      for (int i = 0; i < styleArray.length; i++)
      {
        styleRefs.add(styleArray[i]);
      }
    }
    else if (styleSheetRefs instanceof Collection)
    {
      final Collection c = (Collection) styleSheetRefs;
      styleRefs.addAll(c);
    }
    else if (styleSheetRefs != null)
    {
      styleRefs.add(styleSheetRefs);
    }

    for (int i = 0; i < styleRefs.size(); i++)
    {
      final Object o = styleRefs.get(i);
      try
      {
        final ResourceKey key = resourceManager.createOrDeriveKey(contentBase, o, null);
        final Resource resource = resourceManager.create(key, key, ElementStyleDefinition.class);
        final ElementStyleDefinition definition = (ElementStyleDefinition) resource.getResource();
        styleDefinition.addStyleSheet(definition);
      }
      catch (ResourceKeyCreationException e)
      {
        logger.debug("Failed to load referenced style-sheet: " + o, e);
      }
      catch (ResourceException e)
      {
        logger.info("Failed to load referenced style-sheet: " + o, e);
      }
    }
    return styleDefinition;
  }

  public void initialize(final DocumentContext layoutProcess)
  {
    this.documentContext = layoutProcess;
    this.namespaces = documentContext.getNamespaces();

    this.styleRuleMatcher = new SimpleStyleRuleMatcher();
    this.styleRuleMatcher.initialize(layoutProcess);
  }

  protected DocumentContext getDocumentContext()
  {
    return documentContext;
  }

  protected NamespaceCollection getNamespaces()
  {
    return namespaces;
  }

  public void resolve(final ReportElement element, final ResolverStyleSheet resolverTarget)
  {
    resolverTarget.clear();
    resolverTarget.setId(element.getStyle().getId());

    // Stage 1a: Add the parent styles (but only the one marked as inheritable).

    // If our element has a parent, get the parent's style information
    // so we can "inherit" the styles that support that kind of thing
    simpleStyleResolver.resolveParent(element, resolverTarget);

    // At this point, the parentStyle contains the "foundation" from which
    // the current element's style information will come....

    // Stage 1b: Find all matching stylesheet styles for the given element.
    performSelectionStep(element, resolverTarget);

    // Stage 2: Compute the 'specified' set of values.
    // Find all explicitly inherited styles and add them from the parent.
    // does not apply, we have no ability to specify an explicit INHERIT value.
    resolverTarget.addAll(element.getStyle());
    resolverTarget.addDefault(element.getDefaultStyleSheet());
  }

  /*
   * Todo: Make sure that the 'activeStyles' are sorted and then apply them with the
   * lowest style first. All Matching styles have to be added.
   */
  private void performSelectionStep(final ReportElement element,
                                    final ElementStyleSheet target)
  {
    final StyleRuleMatcher.MatcherResult[] activeStyleRules = styleRuleMatcher.getMatchingRules(element);

    final SelectorWeight[] weights = new SelectorWeight[target.getPropertyKeys().length];
    for (int i = 0; i < activeStyleRules.length; i++)
    {
      final StyleRuleMatcher.MatcherResult activeStyleRule = activeStyleRules[i];
      final ElementStyleRule rule = activeStyleRule.getRule();
      final SelectorWeight weight = activeStyleRule.getWeight();

      final StyleKey[] definedPropertyNamesArray = rule.getDefinedPropertyNamesArray();
      for (int j = 0; j < definedPropertyNamesArray.length; j++)
      {
        final StyleKey styleKey = definedPropertyNamesArray[j];
        if (styleKey == null)
        {
          continue;
        }
       
        final SelectorWeight selectorWeight = weights[j];
        if (selectorWeight == null || (selectorWeight.compareTo(weight) > 0))
        {
          final Object styleProperty = rule.getStyleProperty(styleKey);
          if (styleProperty != null)
          {
            target.setStyleProperty(styleKey, styleProperty);
            weights[j] = weight;
          }
        }
      }
    }
  }

  public StyleResolver clone()
  {
    try
    {
      return (StyleResolver) super.clone();
    }
    catch (CloneNotSupportedException e)
    {
      throw new IllegalStateException();
    }
  }

}
TOP

Related Classes of org.pentaho.reporting.engine.classic.core.style.css.CSSStyleResolver

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.