public void processContent(
      final ReportElement element, final Object computedValue, final Object rawValue) {
    if (computedValue == null) {
      final StyleSheet resolvedStyle = element.getComputedStyle();
      final RenderBox parentRenderBox = this.context.getRenderBox();
      if (parentRenderBox.isEmptyNodesHaveSignificance()
          || metaData.isExtraContentElement(resolvedStyle, element.getAttributes())) {
        ensureEmptyChildIsAdded(parentRenderBox, element);
        this.context.setEmpty(false);
      }
      return;
    }

    if (String.class.equals(computedValue.getClass())) {
      processText(element, (String) computedValue, rawValue);
    } else if (computedValue instanceof Shape) {
      final StyleSheet resolvedStyle = element.getComputedStyle();
      final Shape shape = (Shape) computedValue;
      final ReportDrawable reportDrawable =
          new ShapeDrawable(
              shape, resolvedStyle.getBooleanStyleProperty(ElementStyleKeys.KEEP_ASPECT_RATIO));
      processReportDrawable(element, reportDrawable, rawValue);
    } else if (computedValue instanceof ReportDrawable) {
      processReportDrawable(element, (ReportDrawable) computedValue, rawValue);
    } else if (computedValue instanceof ImageContainer
        || computedValue instanceof DrawableWrapper) {
      processReplacedContent(element, computedValue, rawValue);
    } else if (DrawableWrapper.isDrawable(computedValue)) {
      processReplacedContent(element, new DrawableWrapper(computedValue), rawValue);
    } else {
      processText(element, String.valueOf(computedValue), rawValue);
    }
  }
  protected boolean evaluateElement(final ReportElement e) {
    // only if needed ...
    configureDefaultBehaviour();

    if (ObjectUtilities.equal(e.getName(), getElement())) {
      final Color color = computeColor();
      if (defineBackground) {
        e.getStyle().setStyleProperty(ElementStyleKeys.BACKGROUND_COLOR, color);
      } else {
        e.getStyle().setStyleProperty(ElementStyleKeys.PAINT, color);
      }
      return true;
    }
    return false;
  }
 public InstanceID createSubflowPlaceholder(final ReportElement element) {
   final StyleSheet resolverStyleSheet = element.getComputedStyle();
   final RenderBox subReportBox =
       renderNodeFactory.produceSubReportPlaceholder(element, resolverStyleSheet, stateKey);
   this.context.addChild(subReportBox);
   this.context.setEmpty(false);
   return subReportBox.getInstanceId();
 }
  protected void processText(
      final ReportElement element, String computedValue, final Object rawValue) {
    final SimpleStyleSheet resolverStyleSheet = element.getComputedStyle();
    if (computedValue != null
        && resolverStyleSheet.getBooleanStyleProperty(TextStyleKeys.TRIM_TEXT_CONTENT)) {
      computedValue = computedValue.trim();
    }

    if (this.context.getRenderBox().isAcceptInlineBoxes() == false) {
      final StyleSheet elementStyle;
      final int parentNodeType = this.context.getRenderBox().getLayoutNodeType();
      if (strictLegacyMode
          && (parentNodeType & LayoutNodeTypes.MASK_BOX_CANVAS)
              == LayoutNodeTypes.MASK_BOX_CANVAS) {
        // A table always claims all elements as dynamic. Use the max-height to limit the expansion
        // of elements.
        if (isTableContext(this.context.getRenderBox()) == false
            && resolverStyleSheet.getBooleanStyleProperty(ElementStyleKeys.DYNAMIC_HEIGHT)
                == false) {
          elementStyle = new NonDynamicHeightWrapperStyleSheet(resolverStyleSheet);
        } else {
          elementStyle = new DynamicHeightWrapperStyleSheet(resolverStyleSheet);
        }
      } else {
        elementStyle = resolverStyleSheet;
      }

      this.textProducer.startText();

      final RenderBox renderBox =
          renderNodeFactory.createAutoParagraph(element, elementStyle, stateKey);
      final RenderNode[] renderNodes =
          textProducer.getRenderNodes(element, elementStyle, computedValue);
      renderBox.addChilds(renderNodes);
      renderBox.setRawValue(rawValue);

      this.context = new DefaultLayoutModelBuilderContext(this.context, renderBox);
      this.context.setEmpty(
          renderNodes.length == 0 && isEmptyElement(element, resolverStyleSheet, metaData));
      this.context = this.context.close();
    } else {
      final StyleSheet safeElementStyle = renderNodeFactory.createStyle(resolverStyleSheet);
      final RenderBox renderBox =
          renderNodeFactory.produceRenderBox(
              element, resolverStyleSheet, BandStyleKeys.LAYOUT_INLINE, stateKey);
      final RenderNode[] renderNodes =
          textProducer.getRenderNodes(element, safeElementStyle, computedValue);
      renderBox.addChilds(renderNodes);
      renderBox.setRawValue(rawValue);

      this.context = new DefaultLayoutModelBuilderContext(this.context, renderBox);
      this.context.setEmpty(
          renderNodes.length == 0 && isEmptyElement(element, resolverStyleSheet, metaData));
      this.context = this.context.close();
    }
  }
  protected void processReplacedContent(
      final ReportElement element, final Object value, final Object rawValue) {
    final RenderBox box = this.context.getRenderBox();
    final SimpleStyleSheet resolverStyleSheet = element.getComputedStyle();

    final StyleSheet elementStyle;
    if (box.isAcceptInlineBoxes() == false) {
      if (isTableContext(box) == false
          && resolverStyleSheet.getBooleanStyleProperty(ElementStyleKeys.DYNAMIC_HEIGHT) == false) {
        elementStyle = new NonDynamicReplacedContentStyleSheet(resolverStyleSheet);
      } else {
        elementStyle = new DynamicReplacedContentStyleSheet(resolverStyleSheet);
      }
    } else {
      elementStyle = resolverStyleSheet;
    }

    final RenderableReplacedContentBox child =
        renderNodeFactory.createReplacedContent(element, elementStyle, value, rawValue, stateKey);
    child.setName(element.getName());
    this.context.addChild(child);
    this.context.setEmpty(false);
  }
  protected void processReportDrawable(
      final ReportElement element, final ReportDrawable reportDrawable, final Object rawValue) {

    final SimpleStyleSheet resolverStyleSheet = element.getComputedStyle();
    reportDrawable.setStyleSheet(resolverStyleSheet);
    reportDrawable.setConfiguration(processingContext.getConfiguration());
    reportDrawable.setResourceBundleFactory(processingContext.getResourceBundleFactory());

    if (reportDrawable instanceof DrawableWrapper) {
      processReplacedContent(element, reportDrawable, rawValue);
    } else {
      processReplacedContent(element, new DrawableWrapper(reportDrawable), rawValue);
    }
  }
  protected void traverseAttributeExpressions(final ReportElement element) {

    final String[] attrExprNamespaces = element.getAttributeExpressionNamespaces();
    for (int i = 0; i < attrExprNamespaces.length; i++) {
      final String attrExprNamespace = attrExprNamespaces[i];
      final String[] names = element.getAttributeExpressionNames(attrExprNamespace);
      for (int j = 0; j < names.length; j++) {
        final String name = names[j];
        final Expression expression = element.getAttributeExpression(attrExprNamespace, name);
        if (expression == null) {
          continue;
        }
        final String expressionName = expression.getClass().getName();
        if (ExpressionRegistry.getInstance().isExpressionRegistered(expressionName) == false) {
          inspectAttributeExpression(element, attrExprNamespace, name, expression, null);
        } else {
          final ExpressionMetaData metaData =
              ExpressionRegistry.getInstance().getExpressionMetaData(expressionName);
          inspectAttributeExpression(element, attrExprNamespace, name, expression, metaData);
        }
      }
    }
  }
  public void startSubFlow(final ReportElement element) {
    final StyleSheet resolverStyleSheet = element.getComputedStyle();

    final RenderBox box;
    if (metaData.isFeatureSupported(OutputProcessorFeature.STRICT_COMPATIBILITY)) {
      final StyleSheet styleSheet =
          new SubReportStyleSheet(
              resolverStyleSheet.getBooleanStyleProperty(BandStyleKeys.PAGEBREAK_BEFORE),
              (resolverStyleSheet.getBooleanStyleProperty(BandStyleKeys.PAGEBREAK_AFTER)));

      final SimpleStyleSheet reportStyle = new SimpleStyleSheet(styleSheet);
      final BoxDefinition boxDefinition = renderNodeFactory.getBoxDefinition(reportStyle);
      box =
          new BlockRenderBox(
              reportStyle,
              element.getObjectID(),
              boxDefinition,
              SubReportType.INSTANCE,
              element.getAttributes(),
              null);
    } else {
      box =
          renderNodeFactory.produceRenderBox(
              element, resolverStyleSheet, BandStyleKeys.LAYOUT_BLOCK, stateKey);
    }

    box.getStaticBoxLayoutProperties()
        .setPlaceholderBox(StaticBoxLayoutProperties.PlaceholderType.SECTION);
    if (element.getName() != null) {
      box.setName("Banded-SubReport-Section" + ": name=" + element.getName());
    } else {
      box.setName("Banded-SubReport-Section");
    }

    pushBoxToContext(box, false);
  }
 private void ensureEmptyChildIsAdded(final RenderBox parent, final ReportElement element) {
   final StyleSheet resolverStyleSheet = element.getComputedStyle();
   final RenderBox box;
   if (parent.isAcceptInlineBoxes()) {
     box =
         renderNodeFactory.produceRenderBox(
             element, resolverStyleSheet, BandStyleKeys.LAYOUT_INLINE, getStateKey());
   } else {
     box =
         renderNodeFactory.produceRenderBox(
             element, resolverStyleSheet, BandStyleKeys.LAYOUT_BLOCK, getStateKey());
   }
   box.getStaticBoxLayoutProperties()
       .setPlaceholderBox(StaticBoxLayoutProperties.PlaceholderType.SECTION);
   box.close();
   parent.addChild(box);
 }
  public void startSection(final ReportElement element, final int sectionSize) {
    final StyleSheet resolverStyleSheet = element.getComputedStyle();
    final String layoutMode;
    final boolean legacyMode =
        metaData.isFeatureSupported(OutputProcessorFeature.STRICT_COMPATIBILITY);
    if (legacyMode) {
      layoutMode = BandStyleKeys.LAYOUT_BLOCK;
    } else {
      String layout =
          (String)
              resolverStyleSheet.getStyleProperty(BandStyleKeys.LAYOUT, BandStyleKeys.LAYOUT_AUTO);
      if (BandStyleKeys.LAYOUT_INLINE.equals(layout)
          && !this.context.getRenderBox().isAcceptInlineBoxes()) {
        layoutMode = BandStyleKeys.LAYOUT_BLOCK;
      } else {
        layoutMode = layout;
      }
    }

    final GroupSection groupSection =
        new GroupSection(
            renderNodeFactory.produceRenderBox(element, resolverStyleSheet, layoutMode, null),
            renderNodeFactory.createAutoGeneratedSectionStyleSheet(resolverStyleSheet),
            sectionSize,
            legacyMode);
    this.context = new SectionLayoutModelBuilderContext(this.context, groupSection, legacyMode);
    this.context.setEmpty(true);

    if (element instanceof GroupBody || element instanceof Group) {
      // PRD-3154 - do we need to set placeholder to true?
      // todo: PRD-3154: This is black magic, placeholder box true is evil.
      // Need to evaluate side-effects of this beast. Is it safe for keep-together boxes?
      this.context
          .getRenderBox()
          .getStaticBoxLayoutProperties()
          .setPlaceholderBox(StaticBoxLayoutProperties.PlaceholderType.SECTION);
    }
    this.textProducer.startText();
  }
  protected void traverseStyleExpressions(final ReportElement element) {

    final Map map = element.getStyleExpressions();
    final Iterator styleExprIt = map.entrySet().iterator();
    while (styleExprIt.hasNext()) {
      final Map.Entry entry = (Map.Entry) styleExprIt.next();
      final StyleKey styleKey = (StyleKey) entry.getKey();
      final Expression expression = (Expression) entry.getValue();

      if (expression == null) {
        continue;
      }
      final String expressionName = expression.getClass().getName();
      if (ExpressionRegistry.getInstance().isExpressionRegistered(expressionName) == false) {
        inspectStyleExpression(element, styleKey, expression, null);
      } else {
        final ExpressionMetaData metaData =
            ExpressionRegistry.getInstance().getExpressionMetaData(expressionName);
        inspectStyleExpression(element, styleKey, expression, metaData);
      }
    }
  }
  private static boolean isEmptyElement(
      final ReportElement band, final StyleSheet style, final OutputProcessorMetaData metaData) {
    if (isControlBand(style)) {
      return false;
    }

    if (metaData.isFeatureSupported(OutputProcessorFeature.STRICT_COMPATIBILITY)) {
      if (band instanceof Band) {
        final Band b = (Band) band;
        if (b.getElementCount() > 0) {
          return false;
        }
      }
    }

    if (BandStyleKeys.LAYOUT_AUTO.equals(style.getStyleProperty(BandStyleKeys.LAYOUT))) {
      // A auto-band is considered empty.
      return true;
    }

    // A band is not empty, if it has a defined minimum or preferred height
    if (isLengthDefined(ElementStyleKeys.HEIGHT, style)) {
      return false;
    }
    if (isLengthDefined(ElementStyleKeys.WIDTH, style)) {
      return false;
    }
    if (isLengthDefined(ElementStyleKeys.POS_Y, style)) {
      return false;
    }
    if (isLengthDefined(ElementStyleKeys.POS_X, style)) {
      return false;
    }
    if (isLengthDefined(ElementStyleKeys.MIN_HEIGHT, style)) {
      return false;
    }
    if (isLengthDefined(ElementStyleKeys.MIN_WIDTH, style)) {
      return false;
    }
    if (isLengthDefined(ElementStyleKeys.PADDING_TOP, style)) {
      return false;
    }
    if (isLengthDefined(ElementStyleKeys.PADDING_LEFT, style)) {
      return false;
    }
    if (isLengthDefined(ElementStyleKeys.PADDING_BOTTOM, style)) {
      return false;
    }
    if (isLengthDefined(ElementStyleKeys.PADDING_RIGHT, style)) {
      return false;
    }
    if (BorderStyle.NONE.equals(
            style.getStyleProperty(ElementStyleKeys.BORDER_BOTTOM_STYLE, BorderStyle.NONE))
        == false) {
      return false;
    }
    if (BorderStyle.NONE.equals(
            style.getStyleProperty(ElementStyleKeys.BORDER_TOP_STYLE, BorderStyle.NONE))
        == false) {
      return false;
    }
    if (BorderStyle.NONE.equals(
            style.getStyleProperty(ElementStyleKeys.BORDER_LEFT_STYLE, BorderStyle.NONE))
        == false) {
      return false;
    }
    if (BorderStyle.NONE.equals(
            style.getStyleProperty(ElementStyleKeys.BORDER_RIGHT_STYLE, BorderStyle.NONE))
        == false) {
      return false;
    }
    if (style.getStyleProperty(ElementStyleKeys.BACKGROUND_COLOR) != null) {
      return false;
    }

    if (metaData.isExtraContentElement(band.getStyle(), band.getAttributes())) {
      return false;
    }
    return true;
  }
 public InstanceID startBox(final ReportElement element) {
   final StyleSheet computedStyle = element.getComputedStyle();
   final String layout =
       (String) computedStyle.getStyleProperty(BandStyleKeys.LAYOUT, BandStyleKeys.LAYOUT_CANVAS);
   return startBox(element, computedStyle, layout, false);
 }
 public BundleElementWriteHandler getWriteHandler(final ReportElement element)
     throws BundleWriterException {
   return getWriteHandler(element.getElementType().getMetaData().getName());
 }