Package org.gephi.datalab.impl

Source Code of org.gephi.datalab.impl.AttributeColumnsMergeStrategiesControllerImpl

/*
Copyright 2008-2010 Gephi
Authors : Eduardo Ramos <eduramiba@gmail.com>
Website : http://www.gephi.org

This file is part of Gephi.

Gephi is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

Gephi 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 Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with Gephi.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.gephi.datalab.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import org.gephi.data.attributes.api.AttributeColumn;
import org.gephi.data.attributes.api.AttributeOrigin;
import org.gephi.data.attributes.api.AttributeTable;
import org.gephi.data.attributes.api.AttributeType;
import org.gephi.data.attributes.api.AttributeUtils;
import org.gephi.data.attributes.type.TimeInterval;
import org.gephi.datalab.api.AttributeColumnsMergeStrategiesController;
import org.gephi.datalab.api.AttributeColumnsController;
import org.gephi.dynamic.api.DynamicController;
import org.gephi.dynamic.api.DynamicModel;
import org.gephi.graph.api.Attributes;
import org.gephi.utils.StatisticsUtils;
import org.openide.util.Lookup;
import org.openide.util.lookup.ServiceProvider;

/**
* Implementation of the AttributeColumnsMergeStrategiesController interface
* declared in the Data Laboratory API.
* @author Eduardo Ramos <eduramiba@gmail.com>
* @see AttributeColumnsMergeStrategiesController
*/
@ServiceProvider(service = AttributeColumnsMergeStrategiesController.class)
public class AttributeColumnsMergeStrategiesControllerImpl implements AttributeColumnsMergeStrategiesController {

    public AttributeColumn joinWithSeparatorMerge(AttributeTable table, AttributeColumn[] columnsToMerge, AttributeType newColumnType, String newColumnTitle, String separator) {
        if (table == null || columnsToMerge == null) {
            throw new IllegalArgumentException("Table or columns can't be null");
        }

        AttributeColumnsController ac = Lookup.getDefault().lookup(AttributeColumnsController.class);
        AttributeColumn newColumn;
        newColumn = ac.addAttributeColumn(table, newColumnTitle, newColumnType != null ? newColumnType : AttributeType.STRING);//Create as STRING column by default. Then it can be duplicated to other type.
        if (newColumn == null) {
            return null;
        }

        final int newColumnIndex = newColumn.getIndex();

        if (separator == null) {
            separator = "";
        }

        Object value;
        StringBuilder sb;
        final int columnsCount = columnsToMerge.length;

        for (Attributes row : ac.getTableAttributeRows(table)) {
            sb = new StringBuilder();
            for (int i = 0; i < columnsCount; i++) {
                value = row.getValue(columnsToMerge[i].getIndex());
                if (value != null) {
                    sb.append(value.toString());
                    if (i < columnsCount - 1) {
                        sb.append(separator);
                    }
                }
            }
            row.setValue(newColumnIndex, sb.toString());
        }

        return newColumn;
    }

    public AttributeColumn booleanLogicOperationsMerge(AttributeTable table, AttributeColumn[] columnsToMerge, BooleanOperations[] booleanOperations, String newColumnTitle) {
        AttributeUtils attributeUtils = AttributeUtils.getDefault();
        AttributeColumnsController ac = Lookup.getDefault().lookup(AttributeColumnsController.class);
        if (table == null || columnsToMerge == null || !attributeUtils.areAllColumnsOfType(columnsToMerge, AttributeType.BOOLEAN) || booleanOperations == null || booleanOperations.length != columnsToMerge.length - 1) {
            throw new IllegalArgumentException("All columns have to be boolean columns, table, columns or operations can't be null and operations length must be columns length -1");
        }

        AttributeColumn newColumn;
        newColumn = ac.addAttributeColumn(table, newColumnTitle, AttributeType.BOOLEAN);
        if (newColumn == null) {
            return null;
        }

        final int newColumnIndex = newColumn.getIndex();

        Boolean value;
        Boolean secondValue;

        for (Attributes row : ac.getTableAttributeRows(table)) {
            value = (Boolean) row.getValue(columnsToMerge[0].getIndex());
            value = value != null ? value : false;//Use false if null
            for (int i = 0; i < booleanOperations.length; i++) {
                secondValue = (Boolean) row.getValue(columnsToMerge[i + 1].getIndex());
                secondValue = secondValue != null ? secondValue : false;//Use false if null
                switch (booleanOperations[i]) {
                    case AND:
                        value = value && secondValue;
                        break;
                    case OR:
                        value = value || secondValue;
                        break;
                    case XOR:
                        value = value ^ secondValue;
                        break;
                    case NAND:
                        value = !(value && secondValue);
                        break;
                    case NOR:
                        value = !(value || secondValue);
                        break;
                }
            }
            row.setValue(newColumnIndex, value);
        }

        return newColumn;
    }

    public AttributeColumn mergeNumericColumnsToTimeInterval(AttributeTable table, AttributeColumn startColumn, AttributeColumn endColumn, double defaultStart, double defaultEnd) {
        checkTableAndOneColumn(table, startColumn, endColumn);

        AttributeColumn timeIntervalColumn = getTimeIntervalColumn(table);
        final int timeIntervalColumnIndex = timeIntervalColumn.getIndex();
        final int startColumnIndex = startColumn != null ? startColumn.getIndex() : -1;
        final int endColumnIndex = endColumn != null ? endColumn.getIndex() : -1;
        final boolean isStartColumnNumeric = startColumn != null ? AttributeUtils.getDefault().isNumberColumn(startColumn) : false;
        final boolean isEndColumnNumeric = endColumn != null ? AttributeUtils.getDefault().isNumberColumn(endColumn) : false;

        AttributeColumnsController ac = Lookup.getDefault().lookup(AttributeColumnsController.class);
        Object value;
        double start, end;
        TimeInterval timeInterval;
        for (Attributes row : ac.getTableAttributeRows(table)) {
            if (startColumnIndex != -1) {
                value = row.getValue(startColumnIndex);
                if (value != null) {
                    if (isStartColumnNumeric) {
                        start = ((Number) value).doubleValue();
                    } else {
                        start = parseDouble(value.toString(), defaultStart);
                    }
                } else {
                    start = defaultStart;
                }
            } else {
                start = defaultStart;
            }
            if (endColumnIndex != -1) {
                value = row.getValue(endColumnIndex);
                if (value != null) {
                    if (isEndColumnNumeric) {
                        end = ((Number) value).doubleValue();
                    } else {
                        end = parseDouble(value.toString(), defaultEnd);
                    }
                } else {
                    end = defaultEnd;
                }
            } else {
                end = defaultEnd;
            }
            if (!Double.isInfinite(start) && !Double.isInfinite(end) && start > end) {
                //When start>end, check what column was provided and keep its value. If both columns were provided, set an infinite interval:
                if (startColumnIndex == -1) {
                    start = Double.NEGATIVE_INFINITY;
                } else if (endColumnIndex == -1) {
                    end = Double.POSITIVE_INFINITY;
                } else {
                    start = Double.NEGATIVE_INFINITY;
                    end = Double.POSITIVE_INFINITY;
                }
            }
            timeInterval = new TimeInterval(start, end);
            row.setValue(timeIntervalColumnIndex, timeInterval);
        }
        Lookup.getDefault().lookup(DynamicController.class).setTimeFormat(DynamicModel.TimeFormat.DOUBLE);
        return timeIntervalColumn;
    }

    public AttributeColumn mergeDateColumnsToTimeInterval(AttributeTable table, AttributeColumn startColumn, AttributeColumn endColumn, SimpleDateFormat dateFormat, String defaultStartDate, String defaultEndDate) {
        checkTableAndOneColumn(table, startColumn, endColumn);
        if (dateFormat == null) {
            throw new IllegalArgumentException("Date format can't be null can't be null");
        }

        AttributeColumn timeIntervalColumn = getTimeIntervalColumn(table);
        final int timeIntervalColumnIndex = timeIntervalColumn.getIndex();
        final int startColumnIndex = startColumn != null ? startColumn.getIndex() : -1;
        final int endColumnIndex = endColumn != null ? endColumn.getIndex() : -1;
        double defaultStart = parseDateToDouble(dateFormat, defaultStartDate, Double.NEGATIVE_INFINITY);
        double defaultEnd = parseDateToDouble(dateFormat, defaultEndDate, Double.POSITIVE_INFINITY);

        AttributeColumnsController ac = Lookup.getDefault().lookup(AttributeColumnsController.class);
        Object value;
        double start, end;
        TimeInterval timeInterval;
        for (Attributes row : ac.getTableAttributeRows(table)) {
            if (startColumnIndex != -1) {
                value = row.getValue(startColumnIndex);
                start = parseDateToDouble(dateFormat, value != null ? value.toString() : null, defaultStart);
            } else {
                start = defaultStart;
            }
            if (endColumnIndex != -1) {
                value = row.getValue(endColumnIndex);
                end = parseDateToDouble(dateFormat, value != null ? value.toString() : null, defaultEnd);
            } else {
                end = defaultEnd;
            }
            if (!Double.isInfinite(start) && !Double.isInfinite(end) && start > end) {
                //When start>end, check what column was provided and keep its value. If both columns were provided, set an infinite interval:
                if (startColumnIndex == -1) {
                    start = Double.NEGATIVE_INFINITY;
                } else if (endColumnIndex == -1) {
                    end = Double.POSITIVE_INFINITY;
                } else {
                    start = Double.NEGATIVE_INFINITY;
                    end = Double.POSITIVE_INFINITY;
                }
            }
            timeInterval = new TimeInterval(start, end);
            row.setValue(timeIntervalColumnIndex, timeInterval);
        }
        Lookup.getDefault().lookup(DynamicController.class).setTimeFormat(DynamicModel.TimeFormat.DATE);
        return timeIntervalColumn;
    }

    public AttributeColumn averageNumberMerge(AttributeTable table, AttributeColumn[] columnsToMerge, String newColumnTitle) {
        checkTableAndColumnsAreNumberOrNumberList(table, columnsToMerge);

        AttributeColumnsController ac = Lookup.getDefault().lookup(AttributeColumnsController.class);
        AttributeColumn newColumn;
        newColumn = ac.addAttributeColumn(table, newColumnTitle, AttributeType.BIGDECIMAL);//Create as BIGDECIMAL column by default. Then it can be duplicated to other type.
        if (newColumn == null) {
            return null;
        }
        final int newColumnIndex = newColumn.getIndex();

        BigDecimal average;
        for (Attributes row : ac.getTableAttributeRows(table)) {
            average = StatisticsUtils.average(ac.getRowNumbers(row, columnsToMerge));
            row.setValue(newColumnIndex, average);
        }

        return newColumn;
    }

    public AttributeColumn firstQuartileNumberMerge(AttributeTable table, AttributeColumn[] columnsToMerge, String newColumnTitle) {
        checkTableAndColumnsAreNumberOrNumberList(table, columnsToMerge);

        AttributeColumnsController ac = Lookup.getDefault().lookup(AttributeColumnsController.class);
        AttributeColumn newColumn;
        newColumn = ac.addAttributeColumn(table, newColumnTitle, AttributeType.BIGDECIMAL);//Create as BIGDECIMAL column by default. Then it can be duplicated to other type.
        if (newColumn == null) {
            return null;
        }

        if (newColumn == null) {
            return null;
        }

        final int newColumnIndex = newColumn.getIndex();

        BigDecimal Q1;
        for (Attributes row : ac.getTableAttributeRows(table)) {
            Q1 = StatisticsUtils.quartile1(ac.getRowNumbers(row, columnsToMerge));
            row.setValue(newColumnIndex, Q1);
        }

        return newColumn;
    }

    public AttributeColumn medianNumberMerge(AttributeTable table, AttributeColumn[] columnsToMerge, String newColumnTitle) {
        checkTableAndColumnsAreNumberOrNumberList(table, columnsToMerge);

        AttributeColumnsController ac = Lookup.getDefault().lookup(AttributeColumnsController.class);
        AttributeColumn newColumn;
        newColumn = ac.addAttributeColumn(table, newColumnTitle, AttributeType.BIGDECIMAL);//Create as BIGDECIMAL column by default. Then it can be duplicated to other type.
        if (newColumn == null) {
            return null;
        }

        final int newColumnIndex = newColumn.getIndex();

        BigDecimal median;
        for (Attributes row : ac.getTableAttributeRows(table)) {
            median = StatisticsUtils.median(ac.getRowNumbers(row, columnsToMerge));
            row.setValue(newColumnIndex, median);
        }

        return newColumn;
    }

    public AttributeColumn thirdQuartileNumberMerge(AttributeTable table, AttributeColumn[] columnsToMerge, String newColumnTitle) {
        checkTableAndColumnsAreNumberOrNumberList(table, columnsToMerge);

        AttributeColumnsController ac = Lookup.getDefault().lookup(AttributeColumnsController.class);
        AttributeColumn newColumn;
        newColumn = ac.addAttributeColumn(table, newColumnTitle, AttributeType.BIGDECIMAL);//Create as BIGDECIMAL column by default. Then it can be duplicated to other type.
        if (newColumn == null) {
            return null;
        }

        final int newColumnIndex = newColumn.getIndex();

        BigDecimal Q3;
        for (Attributes row : ac.getTableAttributeRows(table)) {
            Q3 = StatisticsUtils.quartile3(ac.getRowNumbers(row, columnsToMerge));
            row.setValue(newColumnIndex, Q3);
        }

        return newColumn;
    }

    public AttributeColumn interQuartileRangeNumberMerge(AttributeTable table, AttributeColumn[] columnsToMerge, String newColumnTitle) {
        checkTableAndColumnsAreNumberOrNumberList(table, columnsToMerge);

        AttributeColumnsController ac = Lookup.getDefault().lookup(AttributeColumnsController.class);
        AttributeColumn newColumn;
        newColumn = ac.addAttributeColumn(table, newColumnTitle, AttributeType.BIGDECIMAL);//Create as BIGDECIMAL column by default. Then it can be duplicated to other type.
        if (newColumn == null) {
            return null;
        }

        final int newColumnIndex = newColumn.getIndex();

        BigDecimal IQR, Q1, Q3;
        Number[] rowNumbers;
        for (Attributes row : ac.getTableAttributeRows(table)) {
            rowNumbers = ac.getRowNumbers(row, columnsToMerge);
            Q3 = StatisticsUtils.quartile3(rowNumbers);
            Q1 = StatisticsUtils.quartile1(rowNumbers);
            if (Q3 != null && Q1 != null) {
                IQR = Q3.subtract(Q1);
            } else {
                IQR = null;
            }
            row.setValue(newColumnIndex, IQR);
        }

        return newColumn;
    }

    public AttributeColumn sumNumbersMerge(AttributeTable table, AttributeColumn[] columnsToMerge, String newColumnTitle) {
        checkTableAndColumnsAreNumberOrNumberList(table, columnsToMerge);

        AttributeColumnsController ac = Lookup.getDefault().lookup(AttributeColumnsController.class);
        AttributeColumn newColumn;
        newColumn = ac.addAttributeColumn(table, newColumnTitle, AttributeType.BIGDECIMAL);//Create as BIGDECIMAL column by default. Then it can be duplicated to other type.
        if (newColumn == null) {
            return null;
        }

        final int newColumnIndex = newColumn.getIndex();

        BigDecimal sum;
        for (Attributes row : ac.getTableAttributeRows(table)) {
            sum = StatisticsUtils.sum(ac.getRowNumbers(row, columnsToMerge));
            row.setValue(newColumnIndex, sum);
        }

        return newColumn;
    }

    public AttributeColumn minValueNumbersMerge(AttributeTable table, AttributeColumn[] columnsToMerge, String newColumnTitle) {
        checkTableAndColumnsAreNumberOrNumberList(table, columnsToMerge);

        AttributeColumnsController ac = Lookup.getDefault().lookup(AttributeColumnsController.class);
        AttributeColumn newColumn;
        newColumn = ac.addAttributeColumn(table, newColumnTitle, AttributeType.BIGDECIMAL);//Create as BIGDECIMAL column by default. Then it can be duplicated to other type.
        if (newColumn == null) {
            return null;
        }

        final int newColumnIndex = newColumn.getIndex();

        BigDecimal min;
        for (Attributes row : ac.getTableAttributeRows(table)) {
            min = StatisticsUtils.minValue(ac.getRowNumbers(row, columnsToMerge));
            row.setValue(newColumnIndex, min);
        }

        return newColumn;
    }

    public AttributeColumn maxValueNumbersMerge(AttributeTable table, AttributeColumn[] columnsToMerge, String newColumnTitle) {
        checkTableAndColumnsAreNumberOrNumberList(table, columnsToMerge);

        AttributeColumnsController ac = Lookup.getDefault().lookup(AttributeColumnsController.class);
        AttributeColumn newColumn;
        newColumn = ac.addAttributeColumn(table, newColumnTitle, AttributeType.BIGDECIMAL);//Create as BIGDECIMAL column by default. Then it can be duplicated to other type.
        if (newColumn == null) {
            return null;
        }

        final int newColumnIndex = newColumn.getIndex();

        BigDecimal max;
        for (Attributes row : ac.getTableAttributeRows(table)) {
            max = StatisticsUtils.maxValue(ac.getRowNumbers(row, columnsToMerge));
            row.setValue(newColumnIndex, max);
        }

        return newColumn;
    }

    /*************Private methods:*************/
    private AttributeColumn getTimeIntervalColumn(AttributeTable table) {
        AttributeColumn column = table.getColumn(DynamicModel.TIMEINTERVAL_COLUMN);
        if (column == null) {
            column = table.addColumn(DynamicModel.TIMEINTERVAL_COLUMN, "Time Interval", AttributeType.TIME_INTERVAL, AttributeOrigin.PROPERTY, null);
        }
        return column;
    }

    private double parseDouble(String number, double defaultValue) {
        if (number == null) {
            return defaultValue;
        }
        try {
            return Double.parseDouble(number);
        } catch (Exception ex) {
            return defaultValue;
        }
    }

    private double parseDateToDouble(SimpleDateFormat dateFormat, String date, double defaultValue) {
        if (date == null) {
            return defaultValue;
        }
        try {
            Date d = dateFormat.parse(date);
            Calendar cal = Calendar.getInstance();
            cal.setTime(d);
            return cal.getTimeInMillis();
        } catch (Exception ex) {
            return defaultValue;
        }
    }

    private void checkTableAndOneColumn(AttributeTable table, AttributeColumn startColumn, AttributeColumn endColumn) {
        if (table == null) {
            throw new IllegalArgumentException("Table can't be null");
        }
        if (startColumn == null && endColumn == null) {
            throw new IllegalArgumentException("Only one column could be null");
        }
    }

    private void checkTableAndColumnsAreNumberOrNumberList(AttributeTable table, AttributeColumn[] columns) {
        if (table == null) {
            throw new IllegalArgumentException("Table can't be null");
        }
        checkColumnsAreNumberOrNumberList(columns);
    }

    private void checkColumnsAreNumberOrNumberList(AttributeColumn[] columns) {
        if (columns == null || !AttributeUtils.getDefault().areAllNumberOrNumberListColumns(columns)) {
            throw new IllegalArgumentException("All columns have to be number or number list columns and can't be null");
        }
    }
}
TOP

Related Classes of org.gephi.datalab.impl.AttributeColumnsMergeStrategiesControllerImpl

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.