import org.xwiki.rendering.block.*;
import java.text.*;

public class calcgroovy {

 def withDebug = false
 def withDebugPrint = false
 def withTimer = true

 def sdebug = new StringBuffer();
 def timeMsg = new ArrayList()
 def times = new ArrayList();

 public void startTimer(msg) {
   if (withTimer) {
    timeMsg.add(msg)
    def time = (new Date()).getTime()
    times.add(time)
   }
 } 

 public void endTimer() {
   if (withTimer) {
    def msg = ""
    def time1 = 0
    def time2 = (new Date()).getTime()
    if (times.size()>0) {
      def pos = times.size() - 1
      time1 = times.get(pos)
      times.remove(pos)
    }
    if (timeMsg.size()>0) {
      def pos = timeMsg.size() - 1
      msg = timeMsg.get(pos)
      timeMsg.remove(pos)
    }
    def dtime = time2 - time1
    if (withDebugPrint)
      println "${msg}: ${dtime}"
   }
 } 

 public void addDebug(str) {
   if (withDebugPrint)
     println str;
   if (withDebug) {
    sdebug.append(str)
    sdebug.append("\n")
   }
 }

 public String getDebug() {
   return sdebug.toString();
 }

 public String format(value, sformat) {
   if (sformat==null)
    sformat = "0.00"
   addDebug("Using format: ${sformat}")
   def df = new DecimalFormat(sformat)
   return df.format(value)
 }

 public Expando getCurrentCells(mblock) {
   startTimer("getCurrentCells")
   def result = new Expando();

   def cblock = mblock;
   def nb = 50;
   while (cblock!=null) {
    cblock = cblock.getParent()
    println cblock
    nb;
    if (cblock instanceof org.xwiki.rendering.block.TableCellBlock) {
      result.currentcell = cblock;
    }

    if (cblock instanceof org.xwiki.rendering.block.TableRowBlock) {
      result.currentrow = cblock;
    }
    if (cblock instanceof org.xwiki.rendering.block.TableBlock) {
      result.currenttable = cblock;
      break;
    }

    if (nb==0)
     break;
    }

    result.currentcolumnnb = 1;
    for (child in result.currentrow.getChildren()) {
      if (child.is(result.currentcell))
       break;
      result.currentcolumnnb++;
    }

    result.currentrownb = 1;    
    for (child in result.currenttable.getChildren()) {
      if (child.is(result.currentrow)) {
       break;
      }
      result.currentrownb++;
    }

    addDebug("Current Cell: ${result.currentcell}")
    addDebug("Current Row: ${result.currentrow}")
    addDebug("Current Column Number: ${result.currentcolumnnb}")
    addDebug("Current Row Number: ${result.currentrownb}")
    endTimer()
    return result
  }

  public Float getValue(cell, xcontext) {
    def value = 0;
    try {
         def content = getValueAsText(cell, xcontext);
         println "VALUE: ${content}";
         value = Float.parseFloat(content)
    } catch (Exception e) {
    }
    return value;
  }

 
  public String getValueAsText(cell, xcontext) {
   def str = new StringBuffer()
   addDebug("Getting value from cell ${cell}");
   for (child2 in cell.getChildren()) {  
     if (child2 instanceof WordBlock||child2 instanceof SpecialSymbolBlock) {
         def content = child2.toString();
         addDebug("Found Word block: ${content}")
         println "Found Word block: ${content}"
         if (content.equals(".")||content.equals(","))
           str.append(".")
         else {
           def value = 0;
           try {
            value = Float.parseFloat(content)
            
println "ADDING: ${value} for content ${content}"
            str.append(content);
           } catch (Exception e) {
          }
        }
     } else if (child2 instanceof MacroBlock) {
        println "Ignoring block: ${child2}"
        
this is necessary if the block is not yet calculated
        /*
        startTimer("MACROBLOCK")
        addDebug("Found Macro block: ${child2.getId()}")
        def id = child2.getId();
        if (id=="sum") {
           addDebug("Handling sum macro")
        } else if (id=="calc") {
           addDebug("Handling calc macro")
           total += calc(child2, child2.getParameter("type"), child2.getParameter("formula"), xcontext, null)
        }
        endTimer()
        */
     } else {
        
println "Ignoring block: ${child2.getClass()}"
        addDebug("Ignoring block: ${child2}")
     }
     need to recurse
     str.append(getValueAsText(child2, xcontext))
   }
   return str.toString();
 }

 public Float sum(mblock, type, xcontext) {
  startTimer("SUM")
  def currentcells = getCurrentCells(mblock);
  def currenttable = currentcells.currenttable;
  def currentcolumnnb = currentcells.currentcolumnnb;

  Float total = 0;
  if (type=="col") {
    for (child in currenttable.getChildren()) {
      def cell = child.getChildren().get(currentcolumnnb - 1)
      only sum until the current cell is found
      if (cell!=currentcells.currentcell)
       total += getValue(cell, xcontext)
      else
       break;
    }
  }
  endTimer()
  return total;
 }

 public updateProperties(currentcells, xcontext) {
   try {
   def currentrowvalues = new ArrayList()
   currentrowvalues.add(0)
   def i = 0
   def letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
   for (child in currentcells.currentrow.getChildren()) {
      def value = 0
      if (child!=currentcells.currentcell) {
        try {
         println "GET CELL: ${child}"
         value = getValue(child, xcontext)
        } catch(Throwable e) {}
      }
      currentrowvalues.add(value)
      xcontext.vcontext.put(letters[i], value)
      i++
   }
   xcontext.vcontext.put("row", currentrowvalues)
   xcontext.vcontext.put("rownb", currentcells.currentcolumnnb)
   
columns
   letters = "abcdefghijklmnopqrstuvwxyz"
   def currentcolvalues = new ArrayList()
   currentcolvalues.add(0)
   i = 0
   for (child in currentcells.currenttable.getChildren()) {
      def cell = child.getChildren().get(currentcells.currentcolumnnb - 1)
      def value = 0
      if (child!=currentcells.currentcell) {
        try {
          value = getValue(child, xcontext)
        } catch(Throwable e) {}
      }
      currentcolvalues.add(value)
      xcontext.vcontext.put(letters[i], value)
      i++
   }
   xcontext.vcontext.put("col", currentcolvalues)
   xcontext.vcontext.put("colnb", currentcells.currentrownb)
   } catch (Throwable e2) {
     e2.printStackTrace()
   }
 }

 public Float calc(mblock, type, formula, xcontext, xwiki) {
  startTimer("CALC")
  Float total = 0;
  if (xwiki==null)
     return total;

  def currentcells = getCurrentCells(mblock);
  def currentrow = currentcells.currentrow;
  def currentcolumnnb = currentcells.currentcolumnnb;

  if (formula==null||formula=="") {
     def prevcell1 = currentrow.getChildren().get(currentcolumnnb - 2)
     def prevcell2 = currentrow.getChildren().get(currentcolumnnb - 3)
     def val1 = getValue(prevcell1, xcontext)
     def val2 = getValue(prevcell2, xcontext)
     addDebug("Value1: ${val1}")
     addDebug("Value2: ${val2}")
     total = val1 * val2
  } else {
  startTimer("updateProperties")
     updateProperties(currentcells, xcontext)
  endTimer()
  startTimer("velocity")
     def stotal = xwiki.parseContent("#set(\$X = ${formula})\$!X")
  endTimer()
     total = (stotal==null || stotal=="") ? 0 : Float.parseFloat(stotal)
  }
  endTimer()
  return total;
 }

 public void getTablesByHeading(block, currentheading, tables, keys) {
   def cheading = currentheading;
   for (child in block.getChildren()) {  
      if (child instanceof HeaderBlock) {
         addDebug("Extracting text from ${child}")
         cheading = getText(child)
      } else if (child instanceof TableBlock && !(child.getParent() instanceof MacroMarkerBlock)) {
         tables.put(cheading, child)
         keys.add(cheading)
      }
      getTablesByHeading(child, cheading, tables, keys)
   }
 }

 public void getTablesByColumn(block, tables, keys, xcontext) {
   for (child in block.getChildren()) {  
      if (child instanceof TableBlock && !(child.getParent() instanceof MacroMarkerBlock)) {
         def rows = child.getChildren()
         for (def i=1;i<rows.size()-1;i++) {
            def row = rows.getinformation.getChildren();
            def title = getText((row.size()>0) ? row.get(0) : "")
            def nbdays = getValue((row.size()>1) ? row.get(1) : "", xcontext)
            def price = getValue((row.size()>3) ? row.get(3) : "", xcontext)
            if (title!=null) {
               def res = tables.get(title)
               if (res==null) {
                  res = new Expando()
                  res.nbdays = 0
                  res.price = 0
                  tables.put(title, res)
                  keys.add(title)
               }
               res.nbdays += nbdays
               res.price += price
            }
         }
      }
      getTablesByColumn(child, tables, keys, xcontext)
   }
 }

 public String getText(cell) {
   def str = new StringBuffer()
   addDebug("begin ${cell}")
   for (child in cell.getChildren()) {  
     addDebug("Found ${child}")
     if (child instanceof SpaceBlock) {
       str.append(" ");
     } else if (child instanceof WordBlock) {
       str.append(child.toString());
     }
     
need to recurse
     str.append(getText(child))
   }
   addDebug("end ${cell}")
   return str.toString();
 }

 public String summary(mblock, title, summaryTitle, type, column, format1, format2, xcontext) {
   startTimer("SUMMARY")
   def root = mblock.getRoot()
   def tables = new HashMap()
   def keys = new ArrayList()
   def float totaldays = 0
   def float totalprice = 0
   def str = ""
   if (type=="column") {
    getTablesByColumn(root, tables, keys, xcontext);
    str = title
    str += "\n"
    for (key in keys) {
     def table = tables.get(key)
     addDebug("Table: ${table}")
     def nbdays = table.nbdays
     def price = table.price
     def snbdays = format(nbdays, format1)
     def sprice = format(price, format2)
     totaldays += nbdays
     totalprice += price
     str += "|=${key} | ${snbdays} | ${sprice}\n"
    }
    def stotaldays = format(totaldays, format1)
    def stotalprice = format(totalprice, format2)
    str += "|=${summaryTitle} |=${stotaldays}|=${stotalprice}\n"
    str += "\n"
   } else {
    getTablesByHeading(root, "", tables, keys);
    str = title
    str += "\n"
    for (key in keys) {
     def table = tables.get(key)
     addDebug("Table: ${table}")
     def lastrow = (table==null) ? null : table.getChildren().get(table.getChildren().size() - 1)
     def lastrowchilds = (lastrow==null) ? new ArrayList() : lastrow.getChildren()
     def nbdays = getValue((lastrowchilds.size()>1) ? lastrowchilds.get(1) : "", xcontext)
     def price = getValue((lastrowchilds.size()>3) ? lastrowchilds.get(3) : "", xcontext)
     def snbdays = format(nbdays, format1)
     def sprice = format(price, format2)
     totaldays += nbdays
     totalprice += price
     str += "|=${key} | ${snbdays} | ${sprice}\n"
    }
    def stotaldays = format(totaldays, format1)
    def stotalprice = format(totalprice, format2)
    str += "|=${summaryTitle} |=${stotaldays}|=${stotalprice}\n"
    str += "\n"
   }
  
   endTimer()
   return str
 }

}

Tags:
     
This wiki is licensed under a Creative Commons 2.0 license
XWiki Enterprise 12.10.2 - Documentation