Package javax.swing.text

Source Code of javax.swing.text.TableView$GridCell

/*
* @(#)TableView.java  1.36 06/04/07
*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package javax.swing.text;

import java.awt.*;
import java.util.BitSet;
import java.util.Vector;
import javax.swing.SizeRequirements;
import javax.swing.event.DocumentEvent;

import javax.swing.text.html.HTML;

/**
* <p>
* Implements View interface for a table, that is composed of an
* element structure where the child elements of the element
* this view is responsible for represent rows and the child
* elements of the row elements are cells.  The cell elements can
* have an arbitrary element structure under them, which will
* be built with the ViewFactory returned by the getViewFactory
* method.
* <pre>
*
* &nbsp;  TABLE
* &nbsp;    ROW
* &nbsp;      CELL
* &nbsp;      CELL
* &nbsp;    ROW
* &nbsp;      CELL
* &nbsp;      CELL
*
* </pre>
* <p>
* This is implemented as a hierarchy of boxes, the table itself
* is a vertical box, the rows are horizontal boxes, and the cells
* are vertical boxes.  The cells are allowed to span multiple
* columns and rows.  By default, the table can be thought of as
* being formed over a grid (i.e. somewhat like one would find in
* gridbag layout), where table cells can request to span more
* than one grid cell.  The default horizontal span of table cells
* will be based upon this grid, but can be changed by reimplementing
* the requested span of the cell (i.e. table cells can have independant
* spans if desired).
*
* @author  Timothy Prinzing
* @version 1.36 04/07/06
* @see     View
*/
public abstract class TableView extends BoxView {

    /**
     * Constructs a TableView for the given element.
     *
     * @param elem the element that this view is responsible for
     */
    public TableView(Element elem) {
  super(elem, View.Y_AXIS);
  rows = new Vector();
  gridValid = false;
    }

    /**
     * Creates a new table row.
     *
     * @param elem an element
     * @return the row
     */
    protected TableRow createTableRow(Element elem) {
  return new TableRow(elem);
    }

    /**
     * @deprecated Table cells can now be any arbitrary
     * View implementation and should be produced by the
     * ViewFactory rather than the table.
     *
     * @param elem an element
     * @return the cell
     */
    @Deprecated
    protected TableCell createTableCell(Element elem) {
  return new TableCell(elem);
    }
   
    /**
     * The number of columns in the table.
     */
    int getColumnCount() {
  return columnSpans.length;
    }

    /**
     * Fetches the span (width) of the given column. 
     * This is used by the nested cells to query the
     * sizes of grid locations outside of themselves.
     */
    int getColumnSpan(int col) {
  return columnSpans[col];
    }

    /**
     * The number of rows in the table.
     */
    int getRowCount() {
  return rows.size();
    }

    /**
     * Fetches the span (height) of the given row.
     */
    int getRowSpan(int row) {
  View rv = getRow(row);
  if (rv != null) {
      return (int) rv.getPreferredSpan(Y_AXIS);
  }
  return 0;
    }

    TableRow getRow(int row) {
  if (row < rows.size()) {
      return (TableRow) rows.elementAt(row);
  }
  return null;
    }

    /**
     * Determines the number of columns occupied by
     * the table cell represented by given element.
     */
    /*protected*/ int getColumnsOccupied(View v) {
  // PENDING(prinz) this code should be in the html
  // paragraph, but we can't add api to enable it.
  AttributeSet a = v.getElement().getAttributes();
  String s = (String) a.getAttribute(HTML.Attribute.COLSPAN);
  if (s != null) {
      try {
    return Integer.parseInt(s);
      } catch (NumberFormatException nfe) {
    // fall through to one column
      }
  }

  return 1;
    }

    /**
     * Determines the number of rows occupied by
     * the table cell represented by given element.
     */
    /*protected*/ int getRowsOccupied(View v) {
  // PENDING(prinz) this code should be in the html
  // paragraph, but we can't add api to enable it.
  AttributeSet a = v.getElement().getAttributes();
  String s = (String) a.getAttribute(HTML.Attribute.ROWSPAN);
  if (s != null) {
      try {
    return Integer.parseInt(s);
      } catch (NumberFormatException nfe) {
    // fall through to one row
      }
  }

  return 1;
    }

    /*protected*/ void invalidateGrid() {
  gridValid = false;
    }

    protected void forwardUpdate(DocumentEvent.ElementChange ec,
             DocumentEvent e, Shape a, ViewFactory f) {
  super.forwardUpdate(ec, e, a, f);
  // A change in any of the table cells usually effects the whole table,
  // so redraw it all!
  if (a != null) {
      Component c = getContainer();
      if (c != null) {
    Rectangle alloc = (a instanceof Rectangle) ? (Rectangle)a :
                       a.getBounds();
    c.repaint(alloc.x, alloc.y, alloc.width, alloc.height);
      }
  }
    }

    /**
     * Change the child views.  This is implemented to
     * provide the superclass behavior and invalidate the
     * grid so that rows and columns will be recalculated.
     */
    public void replace(int offset, int length, View[] views) {
  super.replace(offset, length, views);
  invalidateGrid();
    }

    /**
     * Fill in the grid locations that are placeholders
     * for multi-column, multi-row, and missing grid
     * locations.
     */
    void updateGrid() {
  if (! gridValid) {
      // determine which views are table rows and clear out
      // grid points marked filled.
      rows.removeAllElements();
      int n = getViewCount();
      for (int i = 0; i < n; i++) {
    View v = getView(i);
    if (v instanceof TableRow) {
        rows.addElement(v);
        TableRow rv = (TableRow) v;
        rv.clearFilledColumns();
        rv.setRow(i);
    }
      }

      int maxColumns = 0;
      int nrows = rows.size();
      for (int row = 0; row < nrows; row++) {
    TableRow rv = getRow(row);
    int col = 0;
    for (int cell = 0; cell < rv.getViewCount(); cell++, col++) {
        View cv = rv.getView(cell);
        // advance to a free column
        for (; rv.isFilled(col); col++);
        int rowSpan = getRowsOccupied(cv);
        int colSpan = getColumnsOccupied(cv);
        if ((colSpan > 1) || (rowSpan > 1)) {
      // fill in the overflow entries for this cell
      int rowLimit = row + rowSpan;
      int colLimit = col + colSpan;
      for (int i = row; i < rowLimit; i++) {
          for (int j = col; j < colLimit; j++) {
        if (i != row || j != col) {
            addFill(i, j);
        }
          }
      }
      if (colSpan > 1) {
          col += colSpan - 1;
      }
        }
    }
    maxColumns = Math.max(maxColumns, col);
      }

      // setup the column layout/requirements
      columnSpans = new int[maxColumns];
      columnOffsets = new int[maxColumns];
      columnRequirements = new SizeRequirements[maxColumns];
      for (int i = 0; i < maxColumns; i++) {
    columnRequirements[i] = new SizeRequirements();
      }
      gridValid = true;
  }
    }

    /**
     * Mark a grid location as filled in for a cells overflow.
     */
    void addFill(int row, int col) {
  TableRow rv = getRow(row);
  if (rv != null) {
      rv.fillColumn(col);
  }
    }

    /**
     * Lays out the columns to fit within the given target span.
     * Returns the results through {@code offsets} and {@code spans}.
     *
     * @param targetSpan the given span for total of all the table
     *  columns
     * @param reqs the requirements desired for each column.  This
     *  is the column maximum of the cells minimum, preferred, and
     *  maximum requested span
     * @param spans the return value of how much to allocated to
     *  each column
     * @param offsets the return value of the offset from the
     *  origin for each column
     */
    protected void layoutColumns(int targetSpan, int[] offsets, int[] spans,
         SizeRequirements[] reqs) {
  // allocate using the convenience method on SizeRequirements
  SizeRequirements.calculateTiledPositions(targetSpan, null, reqs,
             offsets, spans);
    }

    /**
     * Perform layout for the minor axis of the box (i.e. the
     * axis orthoginal to the axis that it represents).  The results
     * of the layout should be placed in the given arrays which represent
     * the allocations to the children along the minor axis.  This
     * is called by the superclass whenever the layout needs to be
     * updated along the minor axis.
     * <p>
     * This is implemented to call the
     * <a href="#layoutColumns">layoutColumns</a> method, and then
     * forward to the superclass to actually carry out the layout
     * of the tables rows.
     *
     * @param targetSpan the total span given to the view, which
     *  whould be used to layout the children.
     * @param axis the axis being layed out.
     * @param offsets the offsets from the origin of the view for
     *  each of the child views.  This is a return value and is
     *  filled in by the implementation of this method.
     * @param spans the span of each child view.  This is a return
     *  value and is filled in by the implementation of this method.
     */
    protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets, int[] spans) {
  // make grid is properly represented
  updateGrid();

  // all of the row layouts are invalid, so mark them that way
  int n = getRowCount();
  for (int i = 0; i < n; i++) {
      TableRow row = getRow(i);
      row.layoutChanged(axis);
  }

  // calculate column spans
  layoutColumns(targetSpan, columnOffsets, columnSpans, columnRequirements);

  // continue normal layout
  super.layoutMinorAxis(targetSpan, axis, offsets, spans);
    }

    /**
     * Calculate the requirements for the minor axis.  This is called by
     * the superclass whenever the requirements need to be updated (i.e.
     * a preferenceChanged was messaged through this view). 
     * <p>
     * This is implemented to calculate the requirements as the sum of the
     * requirements of the columns.
     */
    protected SizeRequirements calculateMinorAxisRequirements(int axis, SizeRequirements r) {
  updateGrid();
 
  // calculate column requirements for each column
  calculateColumnRequirements(axis);


  // the requirements are the sum of the columns.
  if (r == null) {
      r = new SizeRequirements();
  }
  long min = 0;
  long pref = 0;
  long max = 0;
  for (int i = 0; i < columnRequirements.length; i++) {
      SizeRequirements req = columnRequirements[i];
      min += req.minimum;
      pref += req.preferred;
      max += req.maximum;
  }
  r.minimum = (int) min;
  r.preferred = (int) pref;
  r.maximum = (int) max;
  r.alignment = 0;
  return r;
    }

    /*
    boolean shouldTrace() {
  AttributeSet a = getElement().getAttributes();
  Object o = a.getAttribute(HTML.Attribute.ID);
  if ((o != null) && o.equals("debug")) {
      return true;
  }
  return false;
    }
    */

    /**
     * Calculate the requirements for each column.  The calculation
     * is done as two passes over the table.  The table cells that
     * occupy a single column are scanned first to determine the
     * maximum of minimum, preferred, and maximum spans along the
     * give axis.  Table cells that span multiple columns are excluded
     * from the first pass.  A second pass is made to determine if
     * the cells that span multiple columns are satisfied.  If the
     * column requirements are not satisified, the needs of the
     * multi-column cell is mixed into the existing column requirements.
     * The calculation of the multi-column distribution is based upon
     * the proportions of the existing column requirements and taking
     * into consideration any constraining maximums.
     */
    void calculateColumnRequirements(int axis) {
  // pass 1 - single column cells
  boolean hasMultiColumn = false;
  int nrows = getRowCount();
  for (int i = 0; i < nrows; i++) {
      TableRow row = getRow(i);
      int col = 0;
      int ncells = row.getViewCount();
      for (int cell = 0; cell < ncells; cell++, col++) {
    View cv = row.getView(cell);
    for (; row.isFilled(col); col++); // advance to a free column
    int rowSpan = getRowsOccupied(cv);
    int colSpan = getColumnsOccupied(cv);
    if (colSpan == 1) {
        checkSingleColumnCell(axis, col, cv);
    } else {
        hasMultiColumn = true;
        col += colSpan - 1;
    }
      }
  }

  // pass 2 - multi-column cells
  if (hasMultiColumn) {
      for (int i = 0; i < nrows; i++) {
    TableRow row = getRow(i);
    int col = 0;
    int ncells = row.getViewCount();
    for (int cell = 0; cell < ncells; cell++, col++) {
        View cv = row.getView(cell);
        for (; row.isFilled(col); col++); // advance to a free column
        int colSpan = getColumnsOccupied(cv);
        if (colSpan > 1) {
      checkMultiColumnCell(axis, col, colSpan, cv);
      col += colSpan - 1;
        }
    }
      }
  }

  /*
  if (shouldTrace()) {
      System.err.println("calc:");
      for (int i = 0; i < columnRequirements.length; i++) {
    System.err.println(" " + i + ": " + columnRequirements[i]);
      }
  }
  */
    }

    /**
     * check the requirements of a table cell that spans a single column.
     */
    void checkSingleColumnCell(int axis, int col, View v) {
  SizeRequirements req = columnRequirements[col];
  req.minimum = Math.max((int) v.getMinimumSpan(axis), req.minimum);
  req.preferred = Math.max((int) v.getPreferredSpan(axis), req.preferred);
  req.maximum = Math.max((int) v.getMaximumSpan(axis), req.maximum);
    }

    /**
     * check the requirements of a table cell that spans multiple
     * columns.
     */
    void checkMultiColumnCell(int axis, int col, int ncols, View v) {
  // calculate the totals
  long min = 0;
  long pref = 0;
  long max = 0;
  for (int i = 0; i < ncols; i++) {
      SizeRequirements req = columnRequirements[col + i];
      min += req.minimum;
      pref += req.preferred;
      max += req.maximum;
  }

  // check if the minimum size needs adjustment.
  int cmin = (int) v.getMinimumSpan(axis);
  if (cmin > min) {
      /*
       * the columns that this cell spans need adjustment to fit
       * this table cell.... calculate the adjustments.  The
       * maximum for each cell is the maximum of the existing
       * maximum or the amount needed by the cell.
       */
      SizeRequirements[] reqs = new SizeRequirements[ncols];
      for (int i = 0; i < ncols; i++) {
    SizeRequirements r = reqs[i] = columnRequirements[col + i];
    r.maximum = Math.max(r.maximum, (int) v.getMaximumSpan(axis));
      }
      int[] spans = new int[ncols];
      int[] offsets = new int[ncols];
      SizeRequirements.calculateTiledPositions(cmin, null, reqs,
                 offsets, spans);
      // apply the adjustments
      for (int i = 0; i < ncols; i++) {
    SizeRequirements req = reqs[i];
    req.minimum = Math.max(spans[i], req.minimum);
    req.preferred = Math.max(req.minimum, req.preferred);
    req.maximum = Math.max(req.preferred, req.maximum);
      }
  }

  // check if the preferred size needs adjustment.
  int cpref = (int) v.getPreferredSpan(axis);
  if (cpref > pref) {
      /*
       * the columns that this cell spans need adjustment to fit
       * this table cell.... calculate the adjustments.  The
       * maximum for each cell is the maximum of the existing
       * maximum or the amount needed by the cell.
       */
      SizeRequirements[] reqs = new SizeRequirements[ncols];
      for (int i = 0; i < ncols; i++) {
    SizeRequirements r = reqs[i] = columnRequirements[col + i];
      }
      int[] spans = new int[ncols];
      int[] offsets = new int[ncols];
      SizeRequirements.calculateTiledPositions(cpref, null, reqs,
                 offsets, spans);
      // apply the adjustments
      for (int i = 0; i < ncols; i++) {
    SizeRequirements req = reqs[i];
    req.preferred = Math.max(spans[i], req.preferred);
    req.maximum = Math.max(req.preferred, req.maximum);
      }
  }

    }

    /**
     * Fetches the child view that represents the given position in
     * the model.  This is implemented to walk through the children
     * looking for a range that contains the given position.  In this
     * view the children do not necessarily have a one to one mapping
     * with the child elements.
     *
     * @param pos  the search position >= 0
     * @param a  the allocation to the table on entry, and the
     *   allocation of the view containing the position on exit
     * @return  the view representing the given position, or
     *   <code>null</code> if there isn't one
     */
    protected View getViewAtPosition(int pos, Rectangle a) {
        int n = getViewCount();
        for (int i = 0; i < n; i++) {
            View v = getView(i);
            int p0 = v.getStartOffset();
            int p1 = v.getEndOffset();
            if ((pos >= p0) && (pos < p1)) {
                // it's in this view.
    if (a != null) {
        childAllocation(i, a);
    }
                return v;
            }
        }
  if (pos == getEndOffset()) {
      View v = getView(n - 1);
      if (a != null) {
    this.childAllocation(n - 1, a);
      }
      return v;
  }
        return null;
    }

    // ---- variables ----------------------------------------------------

    int[] columnSpans;
    int[] columnOffsets;
    SizeRequirements[] columnRequirements;
    Vector rows;
    boolean gridValid;
    static final private BitSet EMPTY = new BitSet();

    /**
     * View of a row in a row-centric table.
     */
    public class TableRow extends BoxView {

  /**
   * Constructs a TableView for the given element.
   *
   * @param elem the element that this view is responsible for
   * @since 1.4
   */
        public TableRow(Element elem) {
      super(elem, View.X_AXIS);
      fillColumns = new BitSet();
  }

  void clearFilledColumns() {
      fillColumns.and(EMPTY);
  }

  void fillColumn(int col) {
      fillColumns.set(col);
  }

  boolean isFilled(int col) {
      return fillColumns.get(col);
  }

  /** get location in the overall set of rows */
  int getRow() {
      return row;
  }

  /**
   * set location in the overall set of rows, this is
   * set by the TableView.updateGrid() method.
   */
  void setRow(int row) {
      this.row = row;
  }

  /**
   * The number of columns present in this row.
   */
  int getColumnCount() {
      int nfill = 0;
      int n = fillColumns.size();
      for (int i = 0; i < n; i++) {
    if (fillColumns.get(i)) {
        nfill ++;
    }
      }
      return getViewCount() + nfill;
  }

  /**
   * Change the child views.  This is implemented to
   * provide the superclass behavior and invalidate the
   * grid so that rows and columns will be recalculated.
   */
        public void replace(int offset, int length, View[] views) {
      super.replace(offset, length, views);
      invalidateGrid();
  }

  /**
   * Perform layout for the major axis of the box (i.e. the
   * axis that it represents).  The results of the layout should
   * be placed in the given arrays which represent the allocations
   * to the children along the major axis. 
   * <p>
   * This is re-implemented to give each child the span of the column
   * width for the table, and to give cells that span multiple columns
   * the multi-column span.
   *
   * @param targetSpan the total span given to the view, which
   *  whould be used to layout the children.
   * @param axis the axis being layed out.
   * @param offsets the offsets from the origin of the view for
   *  each of the child views.  This is a return value and is
   *  filled in by the implementation of this method.
   * @param spans the span of each child view.  This is a return
   *  value and is filled in by the implementation of this method.
   */
        protected void layoutMajorAxis(int targetSpan, int axis, int[] offsets, int[] spans) {
      int col = 0;
      int ncells = getViewCount();
      for (int cell = 0; cell < ncells; cell++, col++) {
    View cv = getView(cell);
    for (; isFilled(col); col++); // advance to a free column
    int colSpan = getColumnsOccupied(cv);
    spans[cell] = columnSpans[col];
    offsets[cell] = columnOffsets[col];
    if (colSpan > 1) {
        int n = columnSpans.length;
        for (int j = 1; j < colSpan; j++) {
      // Because the table may be only partially formed, some
      // of the columns may not yet exist.  Therefore we check
      // the bounds.
      if ((col+j) < n) {
          spans[cell] += columnSpans[col+j];
      }
        }
        col += colSpan - 1;
    }
      }
  }

  /**
   * Perform layout for the minor axis of the box (i.e. the
   * axis orthoginal to the axis that it represents).  The results
   * of the layout should be placed in the given arrays which represent
   * the allocations to the children along the minor axis.  This
   * is called by the superclass whenever the layout needs to be
   * updated along the minor axis.
   * <p>
   * This is implemented to delegate to the superclass, then adjust
   * the span for any cell that spans multiple rows.
   *
   * @param targetSpan the total span given to the view, which
   *  whould be used to layout the children.
   * @param axis the axis being layed out.
   * @param offsets the offsets from the origin of the view for
   *  each of the child views.  This is a return value and is
   *  filled in by the implementation of this method.
   * @param spans the span of each child view.  This is a return
   *  value and is filled in by the implementation of this method.
   */
        protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets, int[] spans) {
      super.layoutMinorAxis(targetSpan, axis, offsets, spans);
      int col = 0;
      int ncells = getViewCount();
      for (int cell = 0; cell < ncells; cell++, col++) {
    View cv = getView(cell);
    for (; isFilled(col); col++); // advance to a free column
    int colSpan = getColumnsOccupied(cv);
    int rowSpan = getRowsOccupied(cv);
    if (rowSpan > 1) {
        for (int j = 1; j < rowSpan; j++) {
      // test bounds of each row because it may not exist
      // either because of error or because the table isn't
      // fully loaded yet.
      int row = getRow() + j;
      if (row < TableView.this.getViewCount()) {
          int span = TableView.this.getSpan(Y_AXIS, getRow()+j);
          spans[cell] += span;
      }
        }
    }
    if (colSpan > 1) {
        col += colSpan - 1;
    }
      }
  }

  /**
   * Determines the resizability of the view along the
   * given axis.  A value of 0 or less is not resizable.
   *
   * @param axis may be either View.X_AXIS or View.Y_AXIS
   * @return the resize weight
   * @exception IllegalArgumentException for an invalid axis
   */
        public int getResizeWeight(int axis) {
      return 1;
  }

  /**
   * Fetches the child view that represents the given position in
   * the model.  This is implemented to walk through the children
   * looking for a range that contains the given position.  In this
   * view the children do not necessarily have a one to one mapping
   * with the child elements.
   *
   * @param pos  the search position >= 0
   * @param a  the allocation to the table on entry, and the
   *   allocation of the view containing the position on exit
   * @return  the view representing the given position, or
   *   <code>null</code> if there isn't one
   */
        protected View getViewAtPosition(int pos, Rectangle a) {
      int n = getViewCount();
      for (int i = 0; i < n; i++) {
    View v = getView(i);
    int p0 = v.getStartOffset();
    int p1 = v.getEndOffset();
    if ((pos >= p0) && (pos < p1)) {
        // it's in this view.
        if (a != null) {
      childAllocation(i, a);
        }
        return v;
    }
      }
      if (pos == getEndOffset()) {
    View v = getView(n - 1);
    if (a != null) {
        this.childAllocation(n - 1, a);
    }
    return v;
      }
      return null;
  }

  /** columns filled by multi-column or multi-row cells */
  BitSet fillColumns;
  /** the row within the overall grid */
  int row;
    }

    /**
     * @deprecated  A table cell can now be any View implementation.
     */
    @Deprecated
    public class TableCell extends BoxView implements GridCell {

  /**
   * Constructs a TableCell for the given element.
   *
   * @param elem the element that this view is responsible for
   * @since 1.4
   */
        public TableCell(Element elem) {
      super(elem, View.Y_AXIS);
  }
 
  // --- GridCell methods -------------------------------------

  /**
   * Gets the number of columns this cell spans (e.g. the
   * grid width).
         *
         * @return the number of columns
   */
  public int getColumnCount() {
      return 1;
  }

  /**
   * Gets the number of rows this cell spans (that is, the
   * grid height).
         *
         * @return the number of rows
   */
  public int getRowCount() {
      return 1;
  }


        /**
         * Sets the grid location.
         *
         * @param row the row >= 0
         * @param col the column >= 0
         */
        public void setGridLocation(int row, int col) {
            this.row = row;
            this.col = col;
  }

  /**
   * Gets the row of the grid location
   */
        public int getGridRow() {
      return row;
  }

  /**
   * Gets the column of the grid location
   */
        public int getGridColumn() {
      return col;
  }

  int row;
  int col;
    }

    /**
     * <em>
     * THIS IS NO LONGER USED, AND WILL BE REMOVED IN THE
     * NEXT RELEASE.  THE JCK SIGNATURE TEST THINKS THIS INTERFACE
     * SHOULD EXIST
     * </em>
     */
    interface GridCell {

        /**
         * Sets the grid location.
         *
         * @param row the row >= 0
         * @param col the column >= 0
         */
        public void setGridLocation(int row, int col);

  /**
   * Gets the row of the grid location
   */
  public int getGridRow();

  /**
   * Gets the column of the grid location
   */
  public int getGridColumn();

  /**
   * Gets the number of columns this cell spans (e.g. the
   * grid width).
         *
         * @return the number of columns
   */
  public int getColumnCount();

  /**
   * Gets the number of rows this cell spans (that is, the
   * grid height).
         *
         * @return the number of rows
   */
  public int getRowCount();

    }

}
TOP

Related Classes of javax.swing.text.TableView$GridCell

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.