/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id$ */ package org.apache.fop.fo.flow; import org.apache.fop.apps.FOPException; import org.apache.fop.datatypes.Numeric; import org.apache.fop.datatypes.ValidationPercentBaseContext; import org.apache.fop.fo.Constants; import org.apache.fop.fo.FONode; import org.apache.fop.fo.FObj; import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.expr.PropertyException; import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.NumberProperty; import org.apache.fop.fo.properties.Property; /** * Common base class for table-related FOs */ public abstract class TableFObj extends FObj { private Numeric borderAfterPrecedence; private Numeric borderBeforePrecedence; private Numeric borderEndPrecedence; private Numeric borderStartPrecedence; /** * Main constructor * * @param parent the parent node */ public TableFObj(FONode parent) { super(parent); } /** * {@inheritDoc} */ public void bind(PropertyList pList) throws FOPException { super.bind(pList); borderAfterPrecedence = pList.get(PR_BORDER_AFTER_PRECEDENCE).getNumeric(); borderBeforePrecedence = pList.get(PR_BORDER_BEFORE_PRECEDENCE).getNumeric(); borderEndPrecedence = pList.get(PR_BORDER_END_PRECEDENCE).getNumeric(); borderStartPrecedence = pList.get(PR_BORDER_START_PRECEDENCE).getNumeric(); if (getNameId() != FO_TABLE //Separate check for fo:table in Table.java && getNameId() != FO_TABLE_CELL && getCommonBorderPaddingBackground().hasPadding( ValidationPercentBaseContext.getPseudoContext())) { attributeWarning( "padding-* properties are not applicable to " + getName() + ", but a non-zero value for padding was found."); } } /** * * @param side the side for which to return the border precedence * @return the "border-precedence" value for the given side */ public Numeric getBorderPrecedence(int side) { switch (side) { case CommonBorderPaddingBackground.BEFORE: return borderBeforePrecedence; case CommonBorderPaddingBackground.AFTER: return borderAfterPrecedence; case CommonBorderPaddingBackground.START: return borderStartPrecedence; case CommonBorderPaddingBackground.END: return borderEndPrecedence; default: return null; } } /** * Convenience method to returns a reference * to the base Table instance * * @return the base table instance * */ public Table getTable() { // Will be overridden in Table; for any other Table-node, recursive call to // parent.getTable() return ((TableFObj) parent).getTable(); } /** * @return the Common Border, Padding, and Background Properties. */ public abstract CommonBorderPaddingBackground getCommonBorderPaddingBackground(); /** * PropertyMaker subclass for the column-number property * */ public static class ColumnNumberPropertyMaker extends NumberProperty.Maker { /** * Constructor * @param propId the id of the property for which the maker should * be created */ public ColumnNumberPropertyMaker(int propId) { super(propId); } /** * {@inheritDoc} */ public Property make(PropertyList propertyList) throws PropertyException { FObj fo = propertyList.getFObj(); return NumberProperty.getInstance(((ColumnNumberManagerHolder) fo.getParent()) .getColumnNumberManager().getCurrentColumnNumber()); } /** * Check the value of the column-number property. * Return the parent's column index (initial value) in case * of a negative or zero value * * @see org.apache.fop.fo.properties.PropertyMaker#make(PropertyList, String, FObj) */ public Property make(PropertyList propertyList, String value, FObj fo) throws PropertyException { Property p = super.make(propertyList, value, fo); ColumnNumberManagerHolder parent = (ColumnNumberManagerHolder) propertyList.getParentFObj(); ColumnNumberManager columnIndexManager = parent.getColumnNumberManager(); int columnIndex = p.getNumeric().getValue(); if (columnIndex <= 0) { log.warn("Specified negative or zero value for " + "column-number on " + fo.getName() + ": " + columnIndex + " forced to " + columnIndexManager.getCurrentColumnNumber()); return NumberProperty.getInstance(columnIndexManager.getCurrentColumnNumber()); } else { double tmpIndex = p.getNumeric().getNumericValue(); if (tmpIndex - columnIndex > 0.0) { columnIndex = (int) Math.round(tmpIndex); log.warn("Rounding specified column-number of " + tmpIndex + " to " + columnIndex); p = NumberProperty.getInstance(columnIndex); } } int colSpan = propertyList.get(Constants.PR_NUMBER_COLUMNS_SPANNED) .getNumeric().getValue(); int i = -1; while (++i < colSpan) { if (columnIndexManager.isColumnNumberUsed(columnIndex + i)) { /* if column-number is already in use by another * cell/column => error! */ StringBuffer errorMessage = new StringBuffer(); errorMessage.append(fo.getName() + " overlaps in column ") .append(columnIndex + i); org.xml.sax.Locator loc = fo.getLocator(); if (loc != null && loc.getLineNumber() != -1) { errorMessage.append(" (line #") .append(loc.getLineNumber()).append(", column #") .append(loc.getColumnNumber()).append(")"); } throw new PropertyException(errorMessage.toString()); } } return p; } } }