Class EssCubeViewImpl

java.lang.Object
com.appliedolap.essbase.impl.EssCubeViewImpl
All Implemented Interfaces:
EssCubeView, EssGrid

public class EssCubeViewImpl extends Object implements EssCubeView
  • Constructor Details

    • EssCubeViewImpl

      public EssCubeViewImpl(ApiContext api, String applicationName, String databaseName, com.appliedolap.essbase.client.model.Grid grid)
  • Method Details

    • getRows

      public int getRows()
      Specified by:
      getRows in interface EssGrid
    • getColumns

      public int getColumns()
      Specified by:
      getColumns in interface EssGrid
    • getCell

      public String getCell(int row, int col)
      Specified by:
      getCell in interface EssGrid
    • getCellType

      public EssCubeView.CellType getCellType(int row, int col)
      Description copied from interface: EssCubeView
      Classifies the cell at the given position as EssCubeView.CellType.DATA or EssCubeView.CellType.MEMBER. Based on whether the cell's (undocumented by Oracle) types code is exactly "2" - verified, against a live server, to mark the data-cell position consistently whether or not the cell currently holds a real value (confirmed both with real data present, and later with every data cell blank/missing after a database reload). Deliberately compares by equality rather than treating types as a bitmask: code "7" (blank filler cells) also has bit 2 set, but is not a data position, so a bitwise check misclassifies it.
      Specified by:
      getCellType in interface EssCubeView
      Parameters:
      row - the row of the cell
      col - the column of the cell
      Returns:
      the cell's type
    • setMembers

      public void setMembers(List<EssCubeView.MemberPlacement> placements)
      Description copied from interface: EssCubeView
      Replaces the members at the given positions, in one request. Verified live against a real server: this retargets an existing member-position on an existing axis tier to a different member (e.g. changing which Product shows in a given row) - it does not grow the grid to add rows or columns beyond what's already there, and the given member name must be valid for that position's dimension.
      Specified by:
      setMembers in interface EssCubeView
      Parameters:
      placements - the members to place, and where
    • submitData

      public void submitData(List<EssCubeView.CellEdit> edits)
      Description copied from interface: EssCubeView
      Writes values back into the cube, in one request.

      The same mechanism as EssCubeView.setMembers(java.util.List<com.appliedolap.essbase.EssCubeView.MemberPlacement>), which is not a coincidence: Essbase's grid has one submit action and what it writes depends on which cells were marked dirty. Members go in as labels, data as values, and both travel as edits to the grid the server already has.

      Positional, so there is nothing to resolve: the server knows what intersection each cell of its own grid is. Submitting a member cell's position is not rejected here but is not what this is for - use EssCubeView.setMembers(java.util.List<com.appliedolap.essbase.EssCubeView.MemberPlacement>).

      The grid is refreshed by the submit, as every operation is, so a value the cube transforms on the way in - a member with a formula, an aggregation, a cell the writer cannot write - reads back as whatever it actually became rather than as what was sent.

      The empty string clears a cell; #Missing does not. Established live: submitting "" leaves the intersection with no value, and submitting #Missing - the classic spreadsheet word for the same thing, in any spelling - writes a literal zero, which is a different number that aggregates. Anything passing a value a person typed has to translate that word itself; this does not, because guessing which strings are words rather than values is the caller's business and getting it wrong silently corrupts a cube.

      Specified by:
      submitData in interface EssCubeView
      Parameters:
      edits - the cells to write, and what to write in them
    • zoomIn

      public void zoomIn(int row, int col)
      Description copied from interface: EssCubeView
      Zooms in on the member at the given position, using the server's default zoom-in preference. See the class-level javadoc: this tries "ranges" first and only falls back to "coordinates" if the server itself rejects that shape - not a guess based on inspecting the cell, but a reaction to what the server says about the same literal click either way.
      Specified by:
      zoomIn in interface EssCubeView
      Parameters:
      row - the row of the member to zoom in on
      col - the column of the member to zoom in on
    • zoomIn

      public void zoomIn(List<EssCubeView.Range> ranges)
      Description copied from interface: EssCubeView
      Zooms in on the members in several rectangles at once.

      One request, so every member expands against the same grid. Zooming them one at a time would work from a grid that the previous zoom had already reshaped, and the positions would no longer mean what they meant when they were picked.

      Specified by:
      zoomIn in interface EssCubeView
      Parameters:
      ranges - the rectangles to zoom in on, in any order
    • zoomOut

      public void zoomOut(int row, int col)
      Description copied from interface: EssCubeView
      Zooms out from the member at the given position. See the class-level javadoc: this describes the click as-is and returns whatever the server does with it, rather than computing a request shaped to force a particular collapse.
      Specified by:
      zoomOut in interface EssCubeView
      Parameters:
      row - the row of the member to zoom out from
      col - the column of the member to zoom out from
    • zoomOut

      public void zoomOut(List<EssCubeView.Range> ranges)
      Description copied from interface: EssCubeView
      Zooms out of the members in several rectangles at once.
      Specified by:
      zoomOut in interface EssCubeView
      Parameters:
      ranges - the rectangles to zoom out of, in any order
    • keepOnly

      public void keepOnly(int row, int col)
      Description copied from interface: EssCubeView
      Keeps only the member at the given position. See the class-level javadoc: this describes the click as-is and returns whatever the server does with it, rather than computing a request shaped to force a particular outcome.
      Specified by:
      keepOnly in interface EssCubeView
      Parameters:
      row - the row of the member to keep
      col - the column of the member to keep
    • keepOnly

      public void keepOnly(int fromRow, int fromCol, int toRow, int toCol)
      Description copied from interface: EssCubeView
      Keeps only the members in a rectangle of cells, dropping their siblings.

      The corners may be given in either order. What reaches the server is the rectangle they describe - a range there is a start plus a row and column count, not a pair of corners, which is a distinction worth knowing about only if you are reading the wire format.

      Specified by:
      keepOnly in interface EssCubeView
      Parameters:
      fromRow - one corner's row
      fromCol - one corner's column
      toRow - the other corner's row
      toCol - the other corner's column
    • keepOnly

      public void keepOnly(List<EssCubeView.Range> ranges)
      Description copied from interface: EssCubeView
      Keeps only the members in several rectangles at once, dropping their siblings.

      The rectangles need not touch, and this is the point of the method: keeping the first and third of four quarters is not a rectangle, and sending two operations would drop everything outside the first before the second was asked. Verified live - [[2,0,1,1],[4,0,1,1]] against Qtr1..Qtr4, Year keeps Qtr1 and Qtr3.

      Specified by:
      keepOnly in interface EssCubeView
      Parameters:
      ranges - the rectangles to keep, in any order
    • removeOnly

      public void removeOnly(List<EssCubeView.Range> ranges)
      Description copied from interface: EssCubeView
      Removes the members in several rectangles at once, keeping their siblings.
      Specified by:
      removeOnly in interface EssCubeView
      Parameters:
      ranges - the rectangles to remove, in any order
    • removeOnly

      public void removeOnly(int fromRow, int fromCol, int toRow, int toCol)
      Description copied from interface: EssCubeView
      Removes the members in a rectangle of cells, keeping their siblings.
      Specified by:
      removeOnly in interface EssCubeView
      Parameters:
      fromRow - one corner's row
      fromCol - one corner's column
      toRow - the other corner's row
      toCol - the other corner's column
    • removeOnly

      public void removeOnly(int row, int col)
      Description copied from interface: EssCubeView
      Removes the member at the given position, keeping the rest.

      Not currently verified to work - every coordinate/range tried against a live server returns "This operation would generate a nonsensical report." See the class-level javadoc.

      Specified by:
      removeOnly in interface EssCubeView
      Parameters:
      row - the row of the member to remove
      col - the column of the member to remove
    • setLayout

      public void setLayout(List<String> cells)
      Sends the sheet as given and lets the engine read it.

      Deliberately no validation beyond the length: what layouts Essbase accepts is the engine's business and richer than anything worth reimplementing here, and its refusals say more than a guess would.

      Specified by:
      setLayout in interface EssCubeView
      Parameters:
      cells - the grid's labels, row by row, with empty strings for the blanks
    • setLayout

      public void setLayout(String[][] sheet, int headerRows, int leftColumns)
      Description copied from interface: EssCubeView
      Rewrites the grid as a sheet of labels of any shape, saying where the data region begins.

      The difference from EssCubeView.setLayout(List) is that this one can change the grid's structure - how many dimensions sit on the left, on top, and in the POV - and not just the order of what is already there. The single-argument form keeps the current grid's member/data partition and only rewrites the labels, which is enough to rotate a dimension from the left to the top but not to move a dimension between regions, because the server reads a label that lands in what it still believes is a data position as a heading it cannot interpret, and quietly answers with everything it could not place pushed into the POV.

      A grid has three regions, and headerRows and leftColumns are exactly the two numbers that divide them:

                       <- leftColumns ->
                    +----------------+----------------------+
        headerRows  |     blank      |  POV row, then one    |
                    |                |  row per top axis     |
                    +----------------+----------------------+
                    |  one column    |                       |
                    |  per left axis |      data region      |
                    +----------------+----------------------+
       

      Every cell above headerRows or left of leftColumns is a label. Of the rest, a cell carries data where both its column and its row do: a column does where the last header row - the innermost top axis, which names one member per data column - names something there, and a row does where the left axis names something on it. Leave the data cells empty; the server fills them.

      Deciding it per row and column rather than as a rectangle is what lets a sheet have a blank row or column ruled through it, the way a real template does.

      The POV does not have to be there: a grid with every dimension on an axis simply has no POV row, and headerRows is then just the number of top axes.

      Specified by:
      setLayout in interface EssCubeView
      Parameters:
      sheet - the grid's labels, row by row, with empty strings for blanks and data cells
      headerRows - how many rows precede the data region - the POV row, if there is one, plus one row per top/column axis
      leftColumns - how many columns the left/row axes occupy
    • getAliasTable

      public String getAliasTable()
      Description copied from interface: EssCubeView
      The alias table the grid's labels are in.

      Worth asking, because a grid takes member names on the way in and hands back aliases: send a layout saying ALL and the answer says All Accounts. Anything comparing what it asked for against what it got needs to know which table did that.

      Specified by:
      getAliasTable in interface EssCubeView
      Returns:
      the alias table's name, such as Default
    • setAliasTable

      public void setAliasTable(String aliasTable)
      Description copied from interface: EssCubeView
      Sets the alias table this grid's members are labelled from.

      Per request, not a stored preference: the alias table rides along on every grid action, so two grids open on the same connection can be reading different ones. That is unlike the rest of the grid preferences, which Essbase keeps per session and therefore shares between every grid a user has open.

      Null means the server's default, which is the Default table. A name the cube does not have is not ignored - the next action fails - so a name should come from EssCube.getAliasTables() or be EssCubeView.NO_ALIASES. EssCubeView.getAliasTable() reports what the last response was labelled from.

      Specified by:
      setAliasTable in interface EssCubeView
      Parameters:
      aliasTable - the alias table to label members from, or null for the server's default
    • getPlacements

      public List<EssCubeView.DimensionPlacement> getPlacements()
      Description copied from interface: EssCubeView
      Says where every dimension currently sits, as the server reports it rather than as the sheet of labels implies.

      This is the authoritative read of a grid's structure and the one worth asserting against: a layout the server reinterpreted looks perfectly reasonable in the returned labels and is only obvious here, as a dimension that came back in the POV when it was asked for on an axis.

      The count is the cube's dimension count, always - every dimension is in exactly one region.

      Specified by:
      getPlacements in interface EssCubeView
      Returns:
      one placement per dimension, in the server's order
    • refresh

      public void refresh()
      Description copied from interface: EssCubeView
      Re-executes the view as-is, picking up any data changes made since it was last retrieved.
      Specified by:
      refresh in interface EssCubeView
    • pivot

      public void pivot(int fromCell, int toCell)
      Description copied from interface: EssCubeView
      Moves a dimension to somewhere else in the grid.

      Both arguments are flat cell indices, counted across the grid row by row: row * getColumns() + column, which EssCubeView.cellIndex(int, int) will work out. They are not row/column pairs and not column numbers. Oracle's own examples are the authority here - the documented pivotToPOV call sends [8, 2] for a four-column grid, meaning the cell at row 2 column 0 and the one at row 0 column 2.

      This is the general move: name any cell holding a dimension, name the cell where it should go, and the grid comes back with it there. The source may be in the POV or on either axis, and the destination decides which region it lands in.

       // On Sample.Basic's default grid - Year down the side, Measures across the top, three in the POV:
       view.pivot(view.cellIndex(0, 1), view.cellIndex(1, 1));   // Product from the POV onto the top axis
       view.pivot(view.cellIndex(1, 1), view.cellIndex(0, 1));   // Measures off the top axis into the POV
       view.pivot(view.cellIndex(1, 1), view.cellIndex(1, 0));   // Measures off the top onto the row axis
       

      It refuses rather than corrupting the grid: taking the last dimension off an axis answers "Cannot pivot last row", and naming a data cell answers "Pivot starting point cannot be determined".

      Specified by:
      pivot in interface EssCubeView
      Parameters:
      fromCell - the flat index of a cell holding the dimension to move
      toCell - the flat index of the cell to move it to
    • pivot

      public void pivot(int fromCell)
      Description copied from interface: EssCubeView
      Moves a dimension to the front of the row axis, which is what a pivot with no destination does.

      The form Oracle's documentation shows, with a single coordinate. Works from the POV or from the column axis.

      Specified by:
      pivot in interface EssCubeView
      Parameters:
      fromCell - the flat index of a cell holding the dimension to move
    • pivotToPov

      public void pivotToPov(int fromCell, int toCell)
      Description copied from interface: EssCubeView
      Moves a dimension into the POV.

      Flat cell indices again, like EssCubeView.pivot(int, int). The destination names where in the POV row it should sit.

      The axis it leaves cannot be emptied: pivoting away the only dimension on the row axis answers "Cannot pivot last row". Where the grid can afford it, Essbase fills the gap by bringing a POV dimension back out - pivoting the second of two row dimensions away leaves the first in place and pulls something from the POV in beside it.

      Specified by:
      pivotToPov in interface EssCubeView
      Parameters:
      fromCell - the flat index of a cell holding the dimension to move
      toCell - the flat index of the POV cell to move it to
    • getPreferences

      public EssCubeView.GridPreferences getPreferences()
      Description copied from interface: EssCubeView
      Reads the current session's ad hoc display/navigation preferences.
      Specified by:
      getPreferences in interface EssCubeView
    • setPreferences

      public void setPreferences(EssCubeView.GridPreferences preferences)
      Description copied from interface: EssCubeView
      Replaces the current session's ad hoc display/navigation preferences. See EssCubeView.GridPreferences: this takes effect for every subsequent grid operation on this connection, not just this view, and persists until changed again.
      Specified by:
      setPreferences in interface EssCubeView
      Parameters:
      preferences - the preferences to apply