Package org.itsnat.impl.core.domutil

Source Code of org.itsnat.impl.core.domutil.ElementTableImpl

/*
  ItsNat Java Web Application Framework
  Copyright (C) 2007-2011 Jose Maria Arranz Santamaria, Spanish citizen

  This software is free software; you can redistribute it and/or modify it
  under the terms of the GNU Lesser General Public License as
  published by the Free Software Foundation; either version 3 of
  the License, or (at your option) any later version.
  This software 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. You should have received
  a copy of the GNU Lesser General Public License along with this program.
  If not, see <http://www.gnu.org/licenses/>.
*/

package org.itsnat.impl.core.domutil;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.itsnat.core.ItsNatException;
import org.itsnat.core.domutil.ElementTable;
import org.itsnat.core.domutil.ElementTableRenderer;
import org.itsnat.core.domutil.ElementTableStructure;
import org.itsnat.core.domutil.ListElementInfo;
import org.itsnat.impl.core.doc.ItsNatDocumentImpl;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;

/**
*
* @author jmarranz
*/
public class ElementTableImpl extends ElementTableBaseImpl implements ElementTable
{
    protected ElementTableRenderer renderer;
    protected ElementTableStructure structure;
    protected ElementListImpl columnListPattern;
    protected DocumentFragment cellContentPatternFragment; // Ser� recordado como patr�n del contenido
    protected boolean usePatternMarkupToRender;

    /**
     * Creates a new instance of ElementTableImpl
     */
    public ElementTableImpl(ItsNatDocumentImpl itsNatDoc,Element parentElement,boolean removePattern,ElementTableStructure structure,ElementTableRenderer renderer)
    {
        super(itsNatDoc,parentElement);

        this.structure = structure;
        this.renderer = renderer;
        this.usePatternMarkupToRender = itsNatDoc.isUsePatternMarkupToRender();

        this.columnListOfRow = new ArrayList<ElementListBaseImpl>(); // Siempre es modo master

        ElementGroupManagerImpl factory = getItsNatDocumentImpl().getElementGroupManagerImpl();
        this.rows = factory.createElementListNoRenderInternal(parentElement,null,!removePattern,false);

        Element rowContentParentPattern = structure.getRowContentElement(this,0,getRowPatternElement());
        this.columnListPattern = factory.createElementListNoRenderInternal(rowContentParentPattern,null,!removePattern,false);

        if (removePattern)
            rows.removeAllElements(); // Quita la primera fila (pattern)
        else
            createAndSyncColumnArrayList();   // Est� el pattern (no eliminado)
    }

    public boolean isUsePatternMarkupToRender()
    {
        return usePatternMarkupToRender;
    }

    public void setUsePatternMarkupToRender(boolean usePatternMarkupToRender)
    {
        this.usePatternMarkupToRender = usePatternMarkupToRender;
    }

    public ElementListFreeImpl getRowsAsElementListFree()
    {
        return getRowElementList().getInternalElementListFree();
    }

    public ElementListImpl getRowElementList()
    {
        return (ElementListImpl)rows;
    }

    public ElementTableRenderer getElementTableRenderer()
    {
        return renderer;
    }

    public void setElementTableRenderer(ElementTableRenderer renderer)
    {
        this.renderer = renderer;
    }

    public ElementTableStructure getElementTableStructure()
    {
        return structure;
    }

    public void setElementTableStructure(ElementTableStructure structure)
    {
        this.structure = structure;
    }

    public Element getRowPatternElement()
    {
        return getRowElementList().getChildPatternElement();
    }

    public Element getCellPatternElement()
    {
        return columnListPattern.getChildPatternElement();
    }

    public DocumentFragment getCellContentPatternFragment()
    {
        if (cellContentPatternFragment == null)
        {
            // El cellContentPatternFragment necesario para el renderTable con usePatternMarkupToRender = true
            Element cellPatternContentElem = structure.getCellContentElement(this,0,0,getCellPatternElement());
            if (cellPatternContentElem != null) // Si no se puede no se puede
            {
                Element clonedItemContentElem = (Element)cellPatternContentElem.cloneNode(true); // Necesitamos clonar porque al extraer los nodos hijos se vaciar� el contenido
                this.cellContentPatternFragment = DOMUtilInternal.extractChildrenToDocFragment(clonedItemContentElem);
            }
        }

        return cellContentPatternFragment;
    }

    protected void setRowContent(int row,Element rowElem,Object[] rowData,boolean isNew)
    {
        if ((rowData != null)&&(rowData.length > 0))
        {
            ElementListImpl columns = (ElementListImpl)getColumnsOfRowElementList(row,rowElem);
            // Si la longitud de rowData es menor que el n�mero de columnas dar� error
            int col = 0;
            for(Element columElem : columns.getInternalElementListFree())
            {
                Object value = rowData[col];
                setCellValueAt(row,col,value,columElem,isNew);

                col++;
            }
        }
    }


    public Element addRow()
    {
        return addRow((Object[])null);
    }

    public Element addRow(List<Object> rowData)
    {
        return addRow(toObjectArray(rowData));
    }

    public Element addRow(Object[] rowData)
    {
        int row = rows.getLength();
        Element rowElem = getRowElementList().addElement();

        insertColumnListOfRow(row,rowElem);

        setRowContent(row,rowElem,rowData,true);
        return rowElem;
    }

    public Element insertRowAt(int row)
    {
        return insertRowAt(row,(Object[])null);
    }

    public Element insertRowAt(int row,List<Object> rowData)
    {
        return insertRowAt(row,toObjectArray(rowData));
    }

    public Element insertRowAt(int row,Object[] rowData)
    {
        Element rowElem = getRowElementList().insertElementAt(row);
        if (rowElem == null) return null; // Fuera de rango

        insertColumnListOfRow(row,rowElem);

        setRowContent(row,rowElem,rowData,true);
        return rowElem;
    }

    public void setRowValuesAt(int row,List<Object> rowData)
    {
        setRowValuesAt(row,toObjectArray(rowData));
    }

    public void setRowValuesAt(int row,Object[] rowData)
    {
        Element rowElem = getRowElementAt(row);
        setRowContent(row,rowElem,rowData,false);
    }

    public ElementListBaseImpl getColumnsOfRowElementList(int row,Element rowElem)
    {
        return (ElementListImpl)columnListOfRow.get(row);
    }

    public ElementListBaseImpl newColumnsOfRowElementList(int row,Element rowElem)
    {
        Element rowContentElem = getRowContentElementAt(row,rowElem);
        Element cellPattern = getCellPatternElement();
        DocumentFragment cellContentPattern = getCellContentPatternFragment();
        ElementGroupManagerImpl factory = getItsNatDocumentImpl().getElementGroupManagerImpl();
        return factory.createElementListInternal(true,rowContentElem,cellPattern,false,cellContentPattern,false,null,null); // No clonamos pues el mismo elemento patr�n celda ya fue clonado y es utilizado para crear todas las columnas
    }

    public Element[] addOrInsertColumn(int column,Object[] columnData,boolean add)
    {
        if (add)
            columnListPattern.addElement(); // A�adimos tambi�n al patr�n para que al a�adir una nueva fila tenga el nuevo n�mero de columnas
        else
            columnListPattern.insertElementAt(column); // A�adimos tambi�n al patr�n para que al a�adir una nueva fila tenga el nuevo n�mero de columnas

        ElementListFreeImpl rows = getRowsAsElementListFree();
        if (rows.isEmpty()) return new Element[0]; // Nada m�s que hacer

        Element[] newCells = new Element[rows.getLength()];

        // Si la longitud de columnData es menor que el n�mero de columnas dar� error
        int row = 0;
        for(Element rowElem : rows)
        {
            ElementListImpl columns = (ElementListImpl)getColumnsOfRowElementList(row,rowElem);
            Element columnElem = null;
            if (add)
                columnElem = columns.addElement();
            else
                columnElem = columns.insertElementAt(column);

            newCells[row] = columnElem;
            if (columnData != null)
                setCellValueAt(row,column,columnData[row],columnElem,true);

            row++;
        }

        return newCells;
    }

    public Element[] addColumn()
    {
        return addColumn((Object[])null);
    }

    public Element[] addColumn(List<Object> columnData)
    {
        return addColumn(toObjectArray(columnData));
    }

    public Element[] addColumn(Object[] columnData)
    {
        int column = getColumnCount();
        return addOrInsertColumn(column,columnData,true);
    }

    public Element[] insertColumnAt(int column)
    {
        return insertColumnAt(column,(Object[])null);
    }

    public Element[] insertColumnAt(int column,List<Object> columnData)
    {
        return insertColumnAt(column,toObjectArray(columnData));
    }

    public Element[] insertColumnAt(int column,Object[] columnData)
    {
        return addOrInsertColumn(column,columnData,false);
    }

    public void setColumnValuesAt(int column,List<Object> columnData)
    {
        setColumnValuesAt(column,toObjectArray(columnData));
    }

    public void setColumnValuesAt(int column,Object[] columnData)
    {
        // Nada que hacer al pattern

        ElementListFreeImpl rows = getRowsAsElementListFree();
        if (rows.isEmpty()) return; // Nada que hacer

        // Si la longitud de columnData es menor que el n�mero de columnas dar� error
        int row = 0;
        for(Element rowElem : rows)
        {
            ElementListImpl columns = (ElementListImpl)getColumnsOfRowElementList(row,rowElem);
            Element columnElem = columns.getElementAt(column);
            setCellValueAt(row,column,columnData[row],columnElem,false);

            row++;
        }
    }

    @Override
    public void removeColumnAt(int column)
    {
        ElementTableRenderer renderer = getElementTableRenderer();
        if (renderer != null)
        {
            int rowCount = getRowCount();
            for(int row = 0; row < rowCount; row++)
                unrenderCell(row,column);
        }

        columnListPattern.removeElementAt(column); // Quitamos tambi�n al patr�n para que al a�adir una nueva fila tenga el nuevo n�mero de columnas

        super.removeColumnAt(column);
    }

    @Override
    public void removeAllColumns()
    {
        unrenderAllCells();

        columnListPattern.removeAllElements(); // Quitamos tambi�n al patr�n para que al a�adir una nueva fila tenga el nuevo n�mero de columnas

        super.removeAllColumns();
    }

    public int getColumnCount()
    {
        return columnListPattern.getLength();
    }

    public Element getCellContentElementAt(int row, int column)
    {
        Element cellElem = getCellElementAt(row,column);
        if (cellElem == null) return null;
        return getCellContentElementAt(row,column,cellElem);
    }

    public Element getCellContentElementAt(int row, int column,Element cellElem)
    {
        return getElementTableStructure().getCellContentElement(this,row,column,cellElem);
    }

    public Element getRowContentElementAt(int row)
    {
        Element rowElem = getRowElementAt(row);
        if (rowElem == null) return null;
        return getRowContentElementAt(row,rowElem);
    }

    public Element getRowContentElementAt(int row,Element rowElem)
    {
        return getElementTableStructure().getRowContentElement(this,row,rowElem);
    }

    public void setCellValueAt(int row, int column,Object value)
    {
        Element cellElem = getCellElementAt(row,column);
        if (cellElem == null) throw new ItsNatException("Out of range",this);

        setCellValueAt(row,column,value,cellElem,false);
    }

    public void setCellValueAt(int row, int column,Object value,Element cellElem,boolean isNew)
    {
        Element cellContentElem = getCellContentElementAt(row,column,cellElem);
        prepareRendering(cellContentElem,isNew);
        ElementTableRenderer renderer = getElementTableRenderer();
        if (renderer != null)
            renderer.renderTable(this,row,column,value,cellContentElem,isNew);
    }

    public void prepareRendering(Element cellContentElem,boolean isNew)
    {
        if (!isNew && isUsePatternMarkupToRender())  // Si es nuevo el markup es ya el del patr�n
        {
            // Es una actualizaci�n en donde tenemos que usar el markup pattern en vez del contenido actual
            restorePatternMarkupWhenRendering(cellContentElem,getCellContentPatternFragment());
        }
    }

    @Override
    public Element removeRowAt(int row)
    {
        ElementTableRenderer renderer = getElementTableRenderer();
        if (renderer != null)
        {
            int columnCount = getColumnCount();
            for(int col = 0; col < columnCount; col++)
                unrenderCell(row,col);
        }

        return super.removeRowAt(row);
    }

    @Override
    public void removeRowRange(int fromIndex, int toIndex)
    {
        ElementTableRenderer renderer = getElementTableRenderer();
        if (renderer != null)
        {
            int columnCount = getColumnCount();
            for(int row = fromIndex; row <= toIndex; row++)
                for(int col = 0; col < columnCount; col++)
                    unrenderCell(row,col);
        }

        super.removeRowRange(fromIndex,toIndex);
    }

    @Override
    public void removeAllRows()
    {
        unrenderAllCells();

        super.removeAllRows();
    }

    public void unrenderCell(int row,int column)
    {
        ElementTableRenderer renderer = getElementTableRenderer();
        if (renderer == null) return;

        Element cellElem = getCellElementAt(row,column);
        if (cellElem == null) return;

        Element cellContentElem = getCellContentElementAt(row,column,cellElem);
        renderer.unrenderTable(this,row,column,cellContentElem);
    }

    public void unrenderAllCells()
    {
        ElementTableRenderer renderer = getElementTableRenderer();
        if (renderer == null) return;

        int rowCount = getRowCount();
        int columnCount = getColumnCount();
        for(int row = 0; row < rowCount; row++)
            for(int col = 0; col < columnCount; col++)
                unrenderCell(row,col);
    }

    public void setRowCount(int rowCount)
    {
        if (rowCount < 0) throw new ItsNatException("Negative row count: " + rowCount,this);
        int currentRowCount = getRowCount();
        int diff = rowCount - currentRowCount;
        if (diff > 0)
            for(int i = 0; i < diff; i++)
                addRow();
        else if (diff < 0)
            for(int i = currentRowCount - 1; i >= rowCount; i--)
                removeRowAt(i);
    }

    public void setColumnCount(int columnCount)
    {
        if (columnCount < 0) throw new ItsNatException("Negative column count: " + columnCount,this);
        int currentColumnCount = getColumnCount();
        int diff = columnCount - currentColumnCount;
        if (diff > 0)
            for(int i = 0; i < diff; i++)
                addColumn();
        else if (diff < 0)
            for(int i = currentColumnCount - 1; i >= columnCount; i--)
                removeColumnAt(i);
    }

    public void setTableValues(List<List<Object>> values)
    {
        for(int i = 0; i < values.size(); i++)
        {
            List<Object> rowValues = values.get(i);
            for(int j = 0; j < rowValues.size(); j++)
            {
                Object cellValue = rowValues.get(j);
                setCellValueAt(i,j,cellValue);
            }
        }
    }

    public void setTableValues(Object[][] values)
    {
        for(int i = 0; i < values.length; i++)
        {
            Object[] rowValues = values[i];
            for(int j = 0; j < rowValues.length; j++)
            {
                Object cellValue = rowValues[j];
                setCellValueAt(i,j,cellValue);
            }
        }
    }

    public void moveColumn(int columnIndex, int newIndex)
    {
        if (columnIndex == newIndex) return;

        columnListPattern.moveElement(columnIndex,columnIndex,newIndex);

        ElementListFreeImpl rows = getRowsAsElementListFree();
        if (rows.isEmpty()) return; // Nada que hacer

        int row = 0;
        for(Element rowElem : rows)
        {
            ElementListImpl columns = (ElementListImpl)getColumnsOfRowElementList(row,rowElem);
            columns.moveElement(columnIndex,columnIndex,newIndex);

            row++;
        }
    }

    public TableCellElementInfoImpl getTableCellElementInfo(ListElementInfo rowInfo, ListElementInfo cellInfo)
    {
        return TableCellElementInfoMasterImpl.getTableCellElementInfoMaster((ListElementInfoMasterImpl)rowInfo,(ListElementInfoMasterImpl)cellInfo,this);
    }

    public static Object[] toObjectArray(List<Object> data)
    {
        if (data == null) return null;

        Object[] dataArray = new Object[data.size()];
        dataArray = data.toArray(dataArray);
        return dataArray;
    }
}
TOP

Related Classes of org.itsnat.impl.core.domutil.ElementTableImpl

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.