From 8e0cf5eb27991dafacaf6ef1208d0ea07c5a35d5 Mon Sep 17 00:00:00 2001 From: Eduardo Ramos Date: Thu, 1 Nov 2012 19:41:51 +0100 Subject: [PATCH] More fixes for correct dynamic index updates due to attribute events. --- .../data/attributes/api/AttributeModel.java | 308 +++++----- .../data/attributes/api/AttributeUtils.java | 266 ++++---- .../attributes/AbstractAttributeModel.java | 383 ++++++------ .../attributes/AttributeControllerImpl.java | 250 ++++---- .../data/attributes/AttributeRowImpl.java | 40 +- .../data/attributes/AttributeTableImpl.java | 62 +- .../data/attributes/AttributeUtilsImpl.java | 581 +++++++++--------- .../model/IndexedAttributeModel.java | 152 ++--- .../model/TemporaryAttributeModel.java | 164 ++--- .../AttributeModelPersistenceProvider.java | 180 +++--- .../java/org/gephi/dynamic/DynamicIndex.java | 345 +++++------ .../org/gephi/dynamic/DynamicModelImpl.java | 66 +- 12 files changed, 1454 insertions(+), 1343 deletions(-) diff --git a/modules/AttributesAPI/src/main/java/org/gephi/data/attributes/api/AttributeModel.java b/modules/AttributesAPI/src/main/java/org/gephi/data/attributes/api/AttributeModel.java index e833db1cf..ba437d819 100644 --- a/modules/AttributesAPI/src/main/java/org/gephi/data/attributes/api/AttributeModel.java +++ b/modules/AttributesAPI/src/main/java/org/gephi/data/attributes/api/AttributeModel.java @@ -1,150 +1,158 @@ -/* -Copyright 2008-2010 Gephi -Authors : Mathieu Bastian -Website : http://www.gephi.org - -This file is part of Gephi. - -DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - -Copyright 2011 Gephi Consortium. All rights reserved. - -The contents of this file are subject to the terms of either the GNU -General Public License Version 3 only ("GPL") or the Common -Development and Distribution License("CDDL") (collectively, the -"License"). You may not use this file except in compliance with the -License. You can obtain a copy of the License at -http://gephi.org/about/legal/license-notice/ -or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the -specific language governing permissions and limitations under the -License. When distributing the software, include this License Header -Notice in each file and include the License files at -/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the -License Header, with the fields enclosed by brackets [] replaced by -your own identifying information: -"Portions Copyrighted [year] [name of copyright owner]" - -If you wish your version of this file to be governed by only the CDDL -or only the GPL Version 3, indicate your decision by adding -"[Contributor] elects to include this software in this distribution -under the [CDDL or GPL Version 3] license." If you do not indicate a -single choice of license, a recipient has the option to distribute -your version of this file under either the CDDL, the GPL Version 3 or -to extend the choice of license to its licensees as provided above. -However, if you add GPL Version 3 code and therefore, elected the GPL -Version 3 license, then the option applies only if the new code is -made subject to such option by the copyright holder. - -Contributor(s): - -Portions Copyrighted 2011 Gephi Consortium. -*/ -package org.gephi.data.attributes.api; - -/** - * Represents the data model, like a standard database would do. As a database, - * contains a list of tables, where columns are defined. By default, a model - * owns a node and edge table, but more could exist, depending - * of the model implementation. - *

- * The model also provides factories that are linked to this model. Use row - * factory to build new rows and value factory to push new values to these - * rows. Columns are manipulated from the AttributeTable class. - * - * @author Mathieu Bastian - * @see AttributeController - */ -public interface AttributeModel { - - /** - * Returns the node table. Contains all the columns associated to - * node elements. - *

- * An AttributeModel has always node, edge and - * graph tables by default. - * - * @return the node table, contains node columns - */ - public AttributeTable getNodeTable(); - - /** - * Returns the edge table. Contains all the columns associated to - * edge elements. - *

- * An AttributeModel has always node, edge and - * graph tables by default. - * - * @return the edge table, contains edge columns - */ - public AttributeTable getEdgeTable(); - - /** - * Returns the graph table. Contains all the columns associated to - * the graph. - *

- * An AttributeModel has always node, edge and - * graph tables by default. - * - * @return the edge table, contains edge columns - */ - public AttributeTable getGraphTable(); - - /** - * Returns the AttributeTable which has the given name - * or null if this table doesn't exist. - * - * @param name the table's name - * @return the table that has been found, or null - */ - public AttributeTable getTable(String name); - - /** - * Returns all tables this model contains. By default, only contains - * node and edge tables. - * - * @return all the tables of this model - */ - public AttributeTable[] getTables(); - - /** - * Return the value factory. - * - * @return the value factory - */ - public AttributeValueFactory valueFactory(); - - /** - * Returns the row factory. - * - * @return the row factory - */ - public AttributeRowFactory rowFactory(); - - /** - * Adds listener to the listeners of this table. It receives - * events when columns are added or removed, as well as when values are set. - * @param listener the listener that is to be added - */ - public void addAttributeListener(AttributeListener listener); - - /** - * Removes listener to the listeners of this table. - * @param listener the listener that is to be removed - */ - public void removeAttributeListener(AttributeListener listener); - - /** - * Merge model in this model. Makes the union of tables and - * columns of both models. Copy tables this model don't - * have and merge existing ones. For existing tables, call - * {@link AttributeTable#mergeTable(AttributeTable)} - * to merge columns. - *

- * Columns are compared according to their id and type. - * Columns found in model are appended only if they no column - * exist with the same id and type. - * - * @param model the model that is to be merged in this model - */ - public void mergeModel(AttributeModel model); -} +/* +Copyright 2008-2010 Gephi +Authors : Mathieu Bastian +Website : http://www.gephi.org + +This file is part of Gephi. + +DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + +Copyright 2011 Gephi Consortium. All rights reserved. + +The contents of this file are subject to the terms of either the GNU +General Public License Version 3 only ("GPL") or the Common +Development and Distribution License("CDDL") (collectively, the +"License"). You may not use this file except in compliance with the +License. You can obtain a copy of the License at +http://gephi.org/about/legal/license-notice/ +or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the +specific language governing permissions and limitations under the +License. When distributing the software, include this License Header +Notice in each file and include the License files at +/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the +License Header, with the fields enclosed by brackets [] replaced by +your own identifying information: +"Portions Copyrighted [year] [name of copyright owner]" + +If you wish your version of this file to be governed by only the CDDL +or only the GPL Version 3, indicate your decision by adding +"[Contributor] elects to include this software in this distribution +under the [CDDL or GPL Version 3] license." If you do not indicate a +single choice of license, a recipient has the option to distribute +your version of this file under either the CDDL, the GPL Version 3 or +to extend the choice of license to its licensees as provided above. +However, if you add GPL Version 3 code and therefore, elected the GPL +Version 3 license, then the option applies only if the new code is +made subject to such option by the copyright holder. + +Contributor(s): + +Portions Copyrighted 2011 Gephi Consortium. +*/ +package org.gephi.data.attributes.api; + +import org.gephi.project.api.Workspace; + +/** + * Represents the data model, like a standard database would do. As a database, + * contains a list of tables, where columns are defined. By default, a model + * owns a node and edge table, but more could exist, depending + * of the model implementation. + *

+ * The model also provides factories that are linked to this model. Use row + * factory to build new rows and value factory to push new values to these + * rows. Columns are manipulated from the AttributeTable class. + * + * @author Mathieu Bastian + * @see AttributeController + */ +public interface AttributeModel { + + /** + * Returns the node table. Contains all the columns associated to + * node elements. + *

+ * An AttributeModel has always node, edge and + * graph tables by default. + * + * @return the node table, contains node columns + */ + public AttributeTable getNodeTable(); + + /** + * Returns the edge table. Contains all the columns associated to + * edge elements. + *

+ * An AttributeModel has always node, edge and + * graph tables by default. + * + * @return the edge table, contains edge columns + */ + public AttributeTable getEdgeTable(); + + /** + * Returns the graph table. Contains all the columns associated to + * the graph. + *

+ * An AttributeModel has always node, edge and + * graph tables by default. + * + * @return the edge table, contains edge columns + */ + public AttributeTable getGraphTable(); + + /** + * Returns the AttributeTable which has the given name + * or null if this table doesn't exist. + * + * @param name the table's name + * @return the table that has been found, or null + */ + public AttributeTable getTable(String name); + + /** + * Returns all tables this model contains. By default, only contains + * node and edge tables. + * + * @return all the tables of this model + */ + public AttributeTable[] getTables(); + + /** + * Return the value factory. + * + * @return the value factory + */ + public AttributeValueFactory valueFactory(); + + /** + * Returns the row factory. + * + * @return the row factory + */ + public AttributeRowFactory rowFactory(); + + /** + * Adds listener to the listeners of this table. It receives + * events when columns are added or removed, as well as when values are set. + * @param listener the listener that is to be added + */ + public void addAttributeListener(AttributeListener listener); + + /** + * Removes listener to the listeners of this table. + * @param listener the listener that is to be removed + */ + public void removeAttributeListener(AttributeListener listener); + + /** + * Merge model in this model. Makes the union of tables and + * columns of both models. Copy tables this model don't + * have and merge existing ones. For existing tables, call + * {@link AttributeTable#mergeTable(AttributeTable)} + * to merge columns. + *

+ * Columns are compared according to their id and type. + * Columns found in model are appended only if they no column + * exist with the same id and type. + * + * @param model the model that is to be merged in this model + */ + public void mergeModel(AttributeModel model); + + /** + * Returns the workspace this Attribute model belongs to. + * @return the workspace that owns this Attribute model or null if it is independent from a Workspace + */ + public Workspace getWorkspace(); +} diff --git a/modules/AttributesAPI/src/main/java/org/gephi/data/attributes/api/AttributeUtils.java b/modules/AttributesAPI/src/main/java/org/gephi/data/attributes/api/AttributeUtils.java index e6f12cca7..1554fdb49 100644 --- a/modules/AttributesAPI/src/main/java/org/gephi/data/attributes/api/AttributeUtils.java +++ b/modules/AttributesAPI/src/main/java/org/gephi/data/attributes/api/AttributeUtils.java @@ -1,132 +1,134 @@ -/* - Copyright 2008-2010 Gephi - Authors : Mathieu Bastian , Martin Škurla - Website : http://www.gephi.org - - This file is part of Gephi. - - DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - - Copyright 2011 Gephi Consortium. All rights reserved. - - The contents of this file are subject to the terms of either the GNU - General Public License Version 3 only ("GPL") or the Common - Development and Distribution License("CDDL") (collectively, the - "License"). You may not use this file except in compliance with the - License. You can obtain a copy of the License at - http://gephi.org/about/legal/license-notice/ - or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the - specific language governing permissions and limitations under the - License. When distributing the software, include this License Header - Notice in each file and include the License files at - /cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the - License Header, with the fields enclosed by brackets [] replaced by - your own identifying information: - "Portions Copyrighted [year] [name of copyright owner]" - - If you wish your version of this file to be governed by only the CDDL - or only the GPL Version 3, indicate your decision by adding - "[Contributor] elects to include this software in this distribution - under the [CDDL or GPL Version 3] license." If you do not indicate a - single choice of license, a recipient has the option to distribute - your version of this file under either the CDDL, the GPL Version 3 or - to extend the choice of license to its licensees as provided above. - However, if you add GPL Version 3 code and therefore, elected the GPL - Version 3 license, then the option applies only if the new code is - made subject to such option by the copyright holder. - - Contributor(s): - - Portions Copyrighted 2011 Gephi Consortium. - */ -package org.gephi.data.attributes.api; - -import java.util.GregorianCalendar; -import javax.xml.datatype.DatatypeConfigurationException; -import javax.xml.datatype.DatatypeFactory; -import org.openide.util.Lookup; - -/** - * - * @author Mathieu Bastian - * @author Martin Škurla - */ -public abstract class AttributeUtils { - - private static DatatypeFactory dateFactory; - - static { - try { - dateFactory = DatatypeFactory.newInstance(); - } catch (DatatypeConfigurationException ex) { - } - } - - public abstract boolean isNodeColumn(AttributeColumn column); - - public abstract boolean isEdgeColumn(AttributeColumn column); - - public abstract boolean isColumnOfType(AttributeColumn column, AttributeType type); - - public abstract boolean areAllColumnsOfType(AttributeColumn[] columns, AttributeType type); - - public abstract boolean areAllColumnsOfSameType(AttributeColumn[] columns); - - public abstract boolean isStringColumn(AttributeColumn column); - - public abstract boolean areAllStringColumns(AttributeColumn[] columns); - - public abstract boolean isNumberColumn(AttributeColumn column); - - public abstract boolean areAllNumberColumns(AttributeColumn[] columns); - - public abstract boolean isNumberListColumn(AttributeColumn column); - - public abstract boolean areAllNumberListColumns(AttributeColumn[] columns); - - public abstract boolean isNumberOrNumberListColumn(AttributeColumn column); - - public abstract boolean areAllNumberOrNumberListColumns(AttributeColumn[] columns); - - public abstract boolean isDynamicNumberColumn(AttributeColumn column); - - public abstract boolean areAllDynamicNumberColumns(AttributeColumn[] columns); - - public abstract AttributeColumn[] getNumberColumns(AttributeTable table); - - public abstract AttributeColumn[] getStringColumns(AttributeTable table); - - public abstract AttributeColumn[] getAllCollums(AttributeModel model); - - @SuppressWarnings("rawtypes") - public abstract Comparable getMin(AttributeColumn column, Comparable[] values); - - @SuppressWarnings("rawtypes") - public abstract Comparable getMax(AttributeColumn column, Comparable[] values); - - public static synchronized AttributeUtils getDefault() { - return Lookup.getDefault().lookup(AttributeUtils.class); - } - - /** - * Used for attributes representation. - * - * @param d a double to convert from - * - * @return an XML date string. - * - * @throws IllegalArgumentException if {@code d} is infinite. - */ - public static String getXMLDateStringFromDouble(double d) { - if (d == Double.NEGATIVE_INFINITY) { - return "-Infinity"; - } else if (d == Double.POSITIVE_INFINITY) { - return "Infinity"; - } - GregorianCalendar gc = new GregorianCalendar(); - gc.setTimeInMillis((long) d); - String s = dateFactory.newXMLGregorianCalendar(gc).toXMLFormat().substring(0, 23); - s = s.endsWith("T00:00:00.000") ? s.substring(0, 10) : s; - return s; - } -} +/* + Copyright 2008-2010 Gephi + Authors : Mathieu Bastian , Martin Škurla + Website : http://www.gephi.org + + This file is part of Gephi. + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + + Copyright 2011 Gephi Consortium. All rights reserved. + + The contents of this file are subject to the terms of either the GNU + General Public License Version 3 only ("GPL") or the Common + Development and Distribution License("CDDL") (collectively, the + "License"). You may not use this file except in compliance with the + License. You can obtain a copy of the License at + http://gephi.org/about/legal/license-notice/ + or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the + specific language governing permissions and limitations under the + License. When distributing the software, include this License Header + Notice in each file and include the License files at + /cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the + License Header, with the fields enclosed by brackets [] replaced by + your own identifying information: + "Portions Copyrighted [year] [name of copyright owner]" + + If you wish your version of this file to be governed by only the CDDL + or only the GPL Version 3, indicate your decision by adding + "[Contributor] elects to include this software in this distribution + under the [CDDL or GPL Version 3] license." If you do not indicate a + single choice of license, a recipient has the option to distribute + your version of this file under either the CDDL, the GPL Version 3 or + to extend the choice of license to its licensees as provided above. + However, if you add GPL Version 3 code and therefore, elected the GPL + Version 3 license, then the option applies only if the new code is + made subject to such option by the copyright holder. + + Contributor(s): + + Portions Copyrighted 2011 Gephi Consortium. + */ +package org.gephi.data.attributes.api; + +import java.util.GregorianCalendar; +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import org.openide.util.Lookup; + +/** + * + * @author Mathieu Bastian + * @author Martin Škurla + */ +public abstract class AttributeUtils { + + private static DatatypeFactory dateFactory; + + static { + try { + dateFactory = DatatypeFactory.newInstance(); + } catch (DatatypeConfigurationException ex) { + } + } + + public abstract boolean isNodeColumn(AttributeColumn column); + + public abstract boolean isEdgeColumn(AttributeColumn column); + + public abstract boolean isGraphColumn(AttributeColumn column); + + public abstract boolean isColumnOfType(AttributeColumn column, AttributeType type); + + public abstract boolean areAllColumnsOfType(AttributeColumn[] columns, AttributeType type); + + public abstract boolean areAllColumnsOfSameType(AttributeColumn[] columns); + + public abstract boolean isStringColumn(AttributeColumn column); + + public abstract boolean areAllStringColumns(AttributeColumn[] columns); + + public abstract boolean isNumberColumn(AttributeColumn column); + + public abstract boolean areAllNumberColumns(AttributeColumn[] columns); + + public abstract boolean isNumberListColumn(AttributeColumn column); + + public abstract boolean areAllNumberListColumns(AttributeColumn[] columns); + + public abstract boolean isNumberOrNumberListColumn(AttributeColumn column); + + public abstract boolean areAllNumberOrNumberListColumns(AttributeColumn[] columns); + + public abstract boolean isDynamicNumberColumn(AttributeColumn column); + + public abstract boolean areAllDynamicNumberColumns(AttributeColumn[] columns); + + public abstract AttributeColumn[] getNumberColumns(AttributeTable table); + + public abstract AttributeColumn[] getStringColumns(AttributeTable table); + + public abstract AttributeColumn[] getAllCollums(AttributeModel model); + + @SuppressWarnings("rawtypes") + public abstract Comparable getMin(AttributeColumn column, Comparable[] values); + + @SuppressWarnings("rawtypes") + public abstract Comparable getMax(AttributeColumn column, Comparable[] values); + + public static synchronized AttributeUtils getDefault() { + return Lookup.getDefault().lookup(AttributeUtils.class); + } + + /** + * Used for attributes representation. + * + * @param d a double to convert from + * + * @return an XML date string. + * + * @throws IllegalArgumentException if {@code d} is infinite. + */ + public static String getXMLDateStringFromDouble(double d) { + if (d == Double.NEGATIVE_INFINITY) { + return "-Infinity"; + } else if (d == Double.POSITIVE_INFINITY) { + return "Infinity"; + } + GregorianCalendar gc = new GregorianCalendar(); + gc.setTimeInMillis((long) d); + String s = dateFactory.newXMLGregorianCalendar(gc).toXMLFormat().substring(0, 23); + s = s.endsWith("T00:00:00.000") ? s.substring(0, 10) : s; + return s; + } +} diff --git a/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/AbstractAttributeModel.java b/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/AbstractAttributeModel.java index 174390b9d..0765e0e1b 100644 --- a/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/AbstractAttributeModel.java +++ b/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/AbstractAttributeModel.java @@ -1,188 +1,195 @@ -/* -Copyright 2008-2010 Gephi -Authors : Mathieu Bastian , Martin Škurla -Website : http://www.gephi.org - -This file is part of Gephi. - -DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - -Copyright 2011 Gephi Consortium. All rights reserved. - -The contents of this file are subject to the terms of either the GNU -General Public License Version 3 only ("GPL") or the Common -Development and Distribution License("CDDL") (collectively, the -"License"). You may not use this file except in compliance with the -License. You can obtain a copy of the License at -http://gephi.org/about/legal/license-notice/ -or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the -specific language governing permissions and limitations under the -License. When distributing the software, include this License Header -Notice in each file and include the License files at -/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the -License Header, with the fields enclosed by brackets [] replaced by -your own identifying information: -"Portions Copyrighted [year] [name of copyright owner]" - -If you wish your version of this file to be governed by only the CDDL -or only the GPL Version 3, indicate your decision by adding -"[Contributor] elects to include this software in this distribution -under the [CDDL or GPL Version 3] license." If you do not indicate a -single choice of license, a recipient has the option to distribute -your version of this file under either the CDDL, the GPL Version 3 or -to extend the choice of license to its licensees as provided above. -However, if you add GPL Version 3 code and therefore, elected the GPL -Version 3 license, then the option applies only if the new code is -made subject to such option by the copyright holder. - -Contributor(s): - -Portions Copyrighted 2011 Gephi Consortium. - */ -package org.gephi.data.attributes; - -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import org.gephi.data.attributes.api.AttributeListener; -import org.gephi.data.attributes.api.AttributeModel; -import org.gephi.data.attributes.api.AttributeRowFactory; -import org.gephi.data.attributes.api.AttributeTable; -import org.gephi.data.attributes.api.AttributeType; -import org.gephi.data.attributes.api.AttributeValueFactory; -import org.gephi.data.attributes.event.AbstractEvent; -import org.gephi.data.attributes.event.AttributeEventManager; -import org.gephi.data.properties.PropertiesColumn; -import org.openide.util.NbBundle; - -/** - * - * @author Mathieu Bastian - * @author Martin Škurla - */ -public abstract class AbstractAttributeModel implements AttributeModel { - - //Classes - private final ConcurrentMap tableMap; - private final AttributeTableImpl nodeTable; - private final AttributeTableImpl edgeTable; - private final AttributeTableImpl graphTable; - //Factory - private final AttributeFactoryImpl factory; - //Events - protected AttributeEventManager eventManager; - - //Data API - public AbstractAttributeModel() { - tableMap = new ConcurrentHashMap(); - nodeTable = new AttributeTableImpl(this, NbBundle.getMessage(AttributeTableImpl.class, "NodeAttributeTable.name")); - edgeTable = new AttributeTableImpl(this, NbBundle.getMessage(AttributeTableImpl.class, "EdgeAttributeTable.name")); - graphTable = new AttributeTableImpl(this, NbBundle.getMessage(AttributeTableImpl.class, "GraphAttributeTable.name")); - tableMap.put(nodeTable.name, nodeTable); - tableMap.put(edgeTable.name, edgeTable); - tableMap.put(graphTable.name, graphTable); - factory = new AttributeFactoryImpl(this); - } - - protected void createPropertiesColumn() { - // !!! the position of PropertiesColumn enum constants in following arrays must be the same - // !!! as index in each constant - PropertiesColumn[] columnsForNodeTable = {PropertiesColumn.NODE_ID, - PropertiesColumn.NODE_LABEL}; - PropertiesColumn[] columnsForEdgeTable = {PropertiesColumn.EDGE_ID, - PropertiesColumn.EDGE_LABEL, - PropertiesColumn.EDGE_WEIGHT}; - PropertiesColumn[] columnsForGraphTable = {PropertiesColumn.GRAPH_NAME, - PropertiesColumn.GRAPH_DESCRIPTION}; - - for (PropertiesColumn columnForNodeTable : columnsForNodeTable) { - nodeTable.addPropertiesColumn(columnForNodeTable); - } - - for (PropertiesColumn columnForEdgeTable : columnsForEdgeTable) { - edgeTable.addPropertiesColumn(columnForEdgeTable); - } - - for (PropertiesColumn columnForGraphTable : columnsForGraphTable) { - graphTable.addPropertiesColumn(columnForGraphTable); - } - } - - public abstract Object getManagedValue(Object obj, AttributeType attributeType); - - public void clear() { - } - - public AttributeTableImpl getNodeTable() { - return nodeTable; - } - - public AttributeTableImpl getGraphTable() { - return graphTable; - } - - public AttributeTableImpl getEdgeTable() { - return edgeTable; - } - - public AttributeTableImpl getTable(String name) { - AttributeTableImpl attTable = tableMap.get(name); - if (attTable != null) { - return attTable; - } - return null; - } - - public AttributeTableImpl[] getTables() { - return tableMap.values().toArray(new AttributeTableImpl[0]); - } - - public AttributeRowFactory rowFactory() { - return factory; - } - - public AttributeValueFactory valueFactory() { - return factory; - } - - public AttributeFactoryImpl getFactory() { - return factory; - } - - public void addTable(AttributeTableImpl table) { - tableMap.put(table.getName(), table); - } - - public void addAttributeListener(AttributeListener listener) { - eventManager.addAttributeListener(listener); - } - - public void removeAttributeListener(AttributeListener listener) { - eventManager.removeAttributeListener(listener); - } - - public void fireAttributeEvent(AbstractEvent event) { - eventManager.fireEvent(event); - } - - public void mergeModel(AttributeModel model) { - if (model.getNodeTable() != null) { - nodeTable.mergeTable(model.getNodeTable()); - } - if (model.getEdgeTable() != null) { - edgeTable.mergeTable(model.getEdgeTable()); - } - - for (AttributeTable table : model.getTables()) { - if (table != model.getNodeTable() && table != model.getEdgeTable()) { - AttributeTable existingTable = tableMap.get(table.getName()); - if (existingTable != null) { - ((AttributeTableImpl) existingTable).mergeTable(table); - } else { - AttributeTableImpl newTable = new AttributeTableImpl(this, table.getName()); - tableMap.put(newTable.getName(), newTable); - newTable.mergeTable(table); - } - } - } - } -} +/* +Copyright 2008-2010 Gephi +Authors : Mathieu Bastian , Martin Škurla +Website : http://www.gephi.org + +This file is part of Gephi. + +DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + +Copyright 2011 Gephi Consortium. All rights reserved. + +The contents of this file are subject to the terms of either the GNU +General Public License Version 3 only ("GPL") or the Common +Development and Distribution License("CDDL") (collectively, the +"License"). You may not use this file except in compliance with the +License. You can obtain a copy of the License at +http://gephi.org/about/legal/license-notice/ +or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the +specific language governing permissions and limitations under the +License. When distributing the software, include this License Header +Notice in each file and include the License files at +/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the +License Header, with the fields enclosed by brackets [] replaced by +your own identifying information: +"Portions Copyrighted [year] [name of copyright owner]" + +If you wish your version of this file to be governed by only the CDDL +or only the GPL Version 3, indicate your decision by adding +"[Contributor] elects to include this software in this distribution +under the [CDDL or GPL Version 3] license." If you do not indicate a +single choice of license, a recipient has the option to distribute +your version of this file under either the CDDL, the GPL Version 3 or +to extend the choice of license to its licensees as provided above. +However, if you add GPL Version 3 code and therefore, elected the GPL +Version 3 license, then the option applies only if the new code is +made subject to such option by the copyright holder. + +Contributor(s): + +Portions Copyrighted 2011 Gephi Consortium. + */ +package org.gephi.data.attributes; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import org.gephi.data.attributes.api.AttributeListener; +import org.gephi.data.attributes.api.AttributeModel; +import org.gephi.data.attributes.api.AttributeRowFactory; +import org.gephi.data.attributes.api.AttributeTable; +import org.gephi.data.attributes.api.AttributeType; +import org.gephi.data.attributes.api.AttributeValueFactory; +import org.gephi.data.attributes.event.AbstractEvent; +import org.gephi.data.attributes.event.AttributeEventManager; +import org.gephi.data.properties.PropertiesColumn; +import org.gephi.project.api.Workspace; +import org.openide.util.NbBundle; + +/** + * + * @author Mathieu Bastian + * @author Martin Škurla + */ +public abstract class AbstractAttributeModel implements AttributeModel { + + private final Workspace workspace; + //Classes + private final ConcurrentMap tableMap; + private final AttributeTableImpl nodeTable; + private final AttributeTableImpl edgeTable; + private final AttributeTableImpl graphTable; + //Factory + private final AttributeFactoryImpl factory; + //Events + protected AttributeEventManager eventManager; + + //Data API + public AbstractAttributeModel(Workspace workspace) { + this.workspace = workspace; + tableMap = new ConcurrentHashMap(); + nodeTable = new AttributeTableImpl(this, NbBundle.getMessage(AttributeTableImpl.class, "NodeAttributeTable.name")); + edgeTable = new AttributeTableImpl(this, NbBundle.getMessage(AttributeTableImpl.class, "EdgeAttributeTable.name")); + graphTable = new AttributeTableImpl(this, NbBundle.getMessage(AttributeTableImpl.class, "GraphAttributeTable.name")); + tableMap.put(nodeTable.name, nodeTable); + tableMap.put(edgeTable.name, edgeTable); + tableMap.put(graphTable.name, graphTable); + factory = new AttributeFactoryImpl(this); + } + + protected void createPropertiesColumn() { + // !!! the position of PropertiesColumn enum constants in following arrays must be the same + // !!! as index in each constant + PropertiesColumn[] columnsForNodeTable = {PropertiesColumn.NODE_ID, + PropertiesColumn.NODE_LABEL}; + PropertiesColumn[] columnsForEdgeTable = {PropertiesColumn.EDGE_ID, + PropertiesColumn.EDGE_LABEL, + PropertiesColumn.EDGE_WEIGHT}; + PropertiesColumn[] columnsForGraphTable = {PropertiesColumn.GRAPH_NAME, + PropertiesColumn.GRAPH_DESCRIPTION}; + + for (PropertiesColumn columnForNodeTable : columnsForNodeTable) { + nodeTable.addPropertiesColumn(columnForNodeTable); + } + + for (PropertiesColumn columnForEdgeTable : columnsForEdgeTable) { + edgeTable.addPropertiesColumn(columnForEdgeTable); + } + + for (PropertiesColumn columnForGraphTable : columnsForGraphTable) { + graphTable.addPropertiesColumn(columnForGraphTable); + } + } + + public abstract Object getManagedValue(Object obj, AttributeType attributeType); + + public void clear() { + } + + public AttributeTableImpl getNodeTable() { + return nodeTable; + } + + public AttributeTableImpl getGraphTable() { + return graphTable; + } + + public AttributeTableImpl getEdgeTable() { + return edgeTable; + } + + public AttributeTableImpl getTable(String name) { + AttributeTableImpl attTable = tableMap.get(name); + if (attTable != null) { + return attTable; + } + return null; + } + + public AttributeTableImpl[] getTables() { + return tableMap.values().toArray(new AttributeTableImpl[0]); + } + + public AttributeRowFactory rowFactory() { + return factory; + } + + public AttributeValueFactory valueFactory() { + return factory; + } + + public AttributeFactoryImpl getFactory() { + return factory; + } + + public void addTable(AttributeTableImpl table) { + tableMap.put(table.getName(), table); + } + + public void addAttributeListener(AttributeListener listener) { + eventManager.addAttributeListener(listener); + } + + public void removeAttributeListener(AttributeListener listener) { + eventManager.removeAttributeListener(listener); + } + + public void fireAttributeEvent(AbstractEvent event) { + eventManager.fireEvent(event); + } + + public void mergeModel(AttributeModel model) { + if (model.getNodeTable() != null) { + nodeTable.mergeTable(model.getNodeTable()); + } + if (model.getEdgeTable() != null) { + edgeTable.mergeTable(model.getEdgeTable()); + } + + for (AttributeTable table : model.getTables()) { + if (table != model.getNodeTable() && table != model.getEdgeTable()) { + AttributeTable existingTable = tableMap.get(table.getName()); + if (existingTable != null) { + ((AttributeTableImpl) existingTable).mergeTable(table); + } else { + AttributeTableImpl newTable = new AttributeTableImpl(this, table.getName()); + tableMap.put(newTable.getName(), newTable); + newTable.mergeTable(table); + } + } + } + } + + public Workspace getWorkspace(){ + return this.workspace; + } +} diff --git a/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/AttributeControllerImpl.java b/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/AttributeControllerImpl.java index e23d240ae..3dee13ae6 100644 --- a/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/AttributeControllerImpl.java +++ b/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/AttributeControllerImpl.java @@ -1,125 +1,125 @@ -/* -Copyright 2008-2010 Gephi -Authors : Mathieu Bastian -Website : http://www.gephi.org - -This file is part of Gephi. - -DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - -Copyright 2011 Gephi Consortium. All rights reserved. - -The contents of this file are subject to the terms of either the GNU -General Public License Version 3 only ("GPL") or the Common -Development and Distribution License("CDDL") (collectively, the -"License"). You may not use this file except in compliance with the -License. You can obtain a copy of the License at -http://gephi.org/about/legal/license-notice/ -or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the -specific language governing permissions and limitations under the -License. When distributing the software, include this License Header -Notice in each file and include the License files at -/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the -License Header, with the fields enclosed by brackets [] replaced by -your own identifying information: -"Portions Copyrighted [year] [name of copyright owner]" - -If you wish your version of this file to be governed by only the CDDL -or only the GPL Version 3, indicate your decision by adding -"[Contributor] elects to include this software in this distribution -under the [CDDL or GPL Version 3] license." If you do not indicate a -single choice of license, a recipient has the option to distribute -your version of this file under either the CDDL, the GPL Version 3 or -to extend the choice of license to its licensees as provided above. -However, if you add GPL Version 3 code and therefore, elected the GPL -Version 3 license, then the option applies only if the new code is -made subject to such option by the copyright holder. - -Contributor(s): - -Portions Copyrighted 2011 Gephi Consortium. - */ -package org.gephi.data.attributes; - -import org.gephi.data.attributes.api.AttributeController; -import org.gephi.data.attributes.api.AttributeModel; -import org.gephi.data.attributes.model.IndexedAttributeModel; -import org.gephi.data.attributes.model.TemporaryAttributeModel; -import org.gephi.project.api.ProjectController; -import org.gephi.project.api.WorkspaceProvider; -import org.gephi.project.api.Workspace; -import org.gephi.project.api.WorkspaceListener; -import org.openide.util.Lookup; -import org.openide.util.lookup.ServiceProvider; - -/** - * - * @author Mathieu Bastian - */ -@ServiceProvider(service = AttributeController.class) -public class AttributeControllerImpl implements AttributeController { - - private ProjectController projectController; - - public AttributeControllerImpl() { - projectController = Lookup.getDefault().lookup(ProjectController.class); - projectController.addWorkspaceListener(new WorkspaceListener() { - - public void initialize(Workspace workspace) { - AttributeModel m = workspace.getLookup().lookup(AttributeModel.class); - if (m == null) { - workspace.add(new IndexedAttributeModel()); - } - } - - public void select(Workspace workspace) { - } - - public void unselect(Workspace workspace) { - } - - public void close(Workspace workspace) { - } - - public void disable() { - } - }); - if (projectController.getCurrentProject() != null) { - for (Workspace workspace : projectController.getCurrentProject().getLookup().lookup(WorkspaceProvider.class).getWorkspaces()) { - AttributeModel m = workspace.getLookup().lookup(AttributeModel.class); - if (m == null) { - workspace.add(new IndexedAttributeModel()); - } - } - } - } - - public synchronized AttributeModel getModel() { - Workspace workspace = projectController.getCurrentWorkspace(); - if (workspace != null) { - AttributeModel model = workspace.getLookup().lookup(AttributeModel.class); - if (model != null) { - return model; - } - model = new IndexedAttributeModel(); - workspace.add(model); - return model; - } - return null; - } - - public synchronized AttributeModel getModel(Workspace workspace) { - AttributeModel model = workspace.getLookup().lookup(AttributeModel.class); - if (model != null) { - return model; - } - model = new IndexedAttributeModel(); - workspace.add(model); - return model; - } - - public AttributeModel newModel() { - TemporaryAttributeModel model = new TemporaryAttributeModel(); - return model; - } -} +/* +Copyright 2008-2010 Gephi +Authors : Mathieu Bastian +Website : http://www.gephi.org + +This file is part of Gephi. + +DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + +Copyright 2011 Gephi Consortium. All rights reserved. + +The contents of this file are subject to the terms of either the GNU +General Public License Version 3 only ("GPL") or the Common +Development and Distribution License("CDDL") (collectively, the +"License"). You may not use this file except in compliance with the +License. You can obtain a copy of the License at +http://gephi.org/about/legal/license-notice/ +or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the +specific language governing permissions and limitations under the +License. When distributing the software, include this License Header +Notice in each file and include the License files at +/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the +License Header, with the fields enclosed by brackets [] replaced by +your own identifying information: +"Portions Copyrighted [year] [name of copyright owner]" + +If you wish your version of this file to be governed by only the CDDL +or only the GPL Version 3, indicate your decision by adding +"[Contributor] elects to include this software in this distribution +under the [CDDL or GPL Version 3] license." If you do not indicate a +single choice of license, a recipient has the option to distribute +your version of this file under either the CDDL, the GPL Version 3 or +to extend the choice of license to its licensees as provided above. +However, if you add GPL Version 3 code and therefore, elected the GPL +Version 3 license, then the option applies only if the new code is +made subject to such option by the copyright holder. + +Contributor(s): + +Portions Copyrighted 2011 Gephi Consortium. + */ +package org.gephi.data.attributes; + +import org.gephi.data.attributes.api.AttributeController; +import org.gephi.data.attributes.api.AttributeModel; +import org.gephi.data.attributes.model.IndexedAttributeModel; +import org.gephi.data.attributes.model.TemporaryAttributeModel; +import org.gephi.project.api.ProjectController; +import org.gephi.project.api.Workspace; +import org.gephi.project.api.WorkspaceListener; +import org.gephi.project.api.WorkspaceProvider; +import org.openide.util.Lookup; +import org.openide.util.lookup.ServiceProvider; + +/** + * + * @author Mathieu Bastian + */ +@ServiceProvider(service = AttributeController.class) +public class AttributeControllerImpl implements AttributeController { + + private ProjectController projectController; + + public AttributeControllerImpl() { + projectController = Lookup.getDefault().lookup(ProjectController.class); + projectController.addWorkspaceListener(new WorkspaceListener() { + + public void initialize(Workspace workspace) { + AttributeModel m = workspace.getLookup().lookup(AttributeModel.class); + if (m == null) { + workspace.add(new IndexedAttributeModel(workspace)); + } + } + + public void select(Workspace workspace) { + } + + public void unselect(Workspace workspace) { + } + + public void close(Workspace workspace) { + } + + public void disable() { + } + }); + if (projectController.getCurrentProject() != null) { + for (Workspace workspace : projectController.getCurrentProject().getLookup().lookup(WorkspaceProvider.class).getWorkspaces()) { + AttributeModel m = workspace.getLookup().lookup(AttributeModel.class); + if (m == null) { + workspace.add(new IndexedAttributeModel(workspace)); + } + } + } + } + + public synchronized AttributeModel getModel() { + Workspace workspace = projectController.getCurrentWorkspace(); + if (workspace != null) { + AttributeModel model = workspace.getLookup().lookup(AttributeModel.class); + if (model != null) { + return model; + } + model = new IndexedAttributeModel(workspace); + workspace.add(model); + return model; + } + return null; + } + + public synchronized AttributeModel getModel(Workspace workspace) { + AttributeModel model = workspace.getLookup().lookup(AttributeModel.class); + if (model != null) { + return model; + } + model = new IndexedAttributeModel(workspace); + workspace.add(model); + return model; + } + + public AttributeModel newModel() { + TemporaryAttributeModel model = new TemporaryAttributeModel(null); + return model; + } +} diff --git a/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/AttributeRowImpl.java b/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/AttributeRowImpl.java index 4c3c6988a..0e9c3561a 100644 --- a/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/AttributeRowImpl.java +++ b/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/AttributeRowImpl.java @@ -70,11 +70,16 @@ public class AttributeRowImpl implements AttributeRow { public void reset() { rowVersion = attributeTable.getVersion(); int attSize = attributeTable.countColumns(); - AttributeValueImpl[] newValues = new AttributeValueImpl[attSize]; + + if (values == null) { + values = new AttributeValueImpl[attSize]; + } else { + updateColumns(); + } + for (int i = 0; i < attSize; i++) { - newValues[i] = attributeTable.getColumn(i).defaultValue; + setValue(i, attributeTable.getColumn(i).defaultValue, false); } - this.values = newValues; } public void setValues(AttributeRow attributeRow) { @@ -133,17 +138,19 @@ public class AttributeRowImpl implements AttributeRow { value = attributeTable.getFactory().newValue(column, value.getValue()); } - setValue(column.getIndex(), (AttributeValueImpl) value); + setValue(column.getIndex(), (AttributeValueImpl) value, true); } - private void setValue(int index, AttributeValueImpl value) { - updateColumns(); + private void setValue(int index, AttributeValueImpl value, boolean doUpdateColumns) { + if (doUpdateColumns) { + updateColumns(); + } AttributeValueImpl oldValue = this.values[index]; this.values[index] = value; - if (!((oldValue == null && value == null) || (oldValue != null && oldValue.equals(value))) + if (!(oldValue != null && oldValue.equals(value)) && index > 0 && !value.getColumn().getOrigin().equals(AttributeOrigin.COMPUTED)) { //0 is the index of node id and edge id cols, not useful to send these events if (oldValue != null) { attributeTable.model.fireAttributeEvent(new ValueEvent(EventType.UNSET_VALUE, attributeTable, object, oldValue)); @@ -211,27 +218,32 @@ public class AttributeRowImpl implements AttributeRow { } private void updateColumns() { - int tableVersion = attributeTable.getVersion(); if (rowVersion < tableVersion) { //Need to update AttributeColumnImpl[] columns = attributeTable.getColumns(); - AttributeValueImpl[] newValues = new AttributeValueImpl[columns.length]; + AttributeValueImpl[] oldValues = values; + + values = new AttributeValueImpl[columns.length]; for (int i = 0; i < columns.length; i++) { AttributeColumnImpl tableCol = columns[i]; - newValues[i] = tableCol.defaultValue; + boolean found = false; int j = 0; - while (j < values.length) { - AttributeValueImpl val = values[j++]; + while (j < oldValues.length) { + AttributeValueImpl val = oldValues[j++]; if (val.getColumn() == tableCol) { - newValues[i] = val; + values[i] = val; + found = true; break; } } + + if (!found) { + setValue(i, tableCol.defaultValue, false); + } } - values = newValues; //Upd version rowVersion = tableVersion; diff --git a/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/AttributeTableImpl.java b/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/AttributeTableImpl.java index 45c8a162f..bc50a9a4e 100644 --- a/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/AttributeTableImpl.java +++ b/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/AttributeTableImpl.java @@ -52,10 +52,17 @@ import org.gephi.data.attributes.api.AttributeEvent; 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.event.ColumnEvent; import org.gephi.data.attributes.spi.AttributeValueDelegateProvider; import org.gephi.data.attributes.type.TypeConvertor; import org.gephi.data.properties.PropertiesColumn; +import org.gephi.graph.api.Attributes; +import org.gephi.graph.api.Edge; +import org.gephi.graph.api.GraphController; +import org.gephi.graph.api.GraphModel; +import org.gephi.graph.api.Node; +import org.openide.util.Lookup; /** * @@ -115,11 +122,11 @@ public class AttributeTableImpl implements AttributeTable { if (id == null || id.isEmpty() || hasColumn(id)) { throw new IllegalArgumentException("The column id can't be null, empty or already existing in the table"); } - - if(title == null || title.isEmpty() || hasColumn(title)){ + + if (title == null || title.isEmpty() || hasColumn(title)) { //The id is correct, but the title may be invalid or repeated even when the id is valid //Use id as title as a compromise so the column can still be added: - + Logger.getLogger(AttributeTableImpl.class.getName()).log(Level.WARNING, "Invalid or repeated column title ({0}), used column id as its title instead", title); title = id; } @@ -151,11 +158,57 @@ public class AttributeTableImpl implements AttributeTable { return column; } + /** + * Sends unset events for all attribute rows of a column that is going to be removed. (This is basically necessary to correctly update Dynamic index of Dynamic API.) + * + * Events are only sent for node, edge and graph table columns. + * + * @param column Column that is being removed + */ + private boolean sendUnsetValueEventsForRemovedColumn(AttributeColumn column) { + if (this.model.getWorkspace() == null) { + return false; + } + + GraphModel graphModel = Lookup.getDefault().lookup(GraphController.class).getModel(this.model.getWorkspace()); + Attributes[] rows; + + if (AttributeUtils.getDefault().isNodeColumn(column)) { + Node[] nodes = graphModel.getGraph().getNodes().toArray(); + rows = new Attributes[nodes.length]; + + for (int i = 0; i < nodes.length; i++) { + rows[i] = nodes[i].getAttributes(); + } + } else if (AttributeUtils.getDefault().isEdgeColumn(column)) { + Edge[] edges = graphModel.getGraph().getEdges().toArray(); + rows = new Attributes[edges.length]; + + for (int i = 0; i < edges.length; i++) { + rows[i] = edges[i].getAttributes(); + } + } else if (AttributeUtils.getDefault().isGraphColumn(column)) { + rows = new Attributes[]{graphModel.getGraph().getAttributes()}; + } else { + return false; + } + + int columnIndex = column.getIndex(); + + for (Attributes row : rows) { + row.setValue(columnIndex, null); + } + + return true; + } + public synchronized void removeColumn(AttributeColumn column) { int index = columns.indexOf(column); if (index == -1) { return; } + + sendUnsetValueEventsForRemovedColumn(column); //update indexes of the next columns of the one to delete: AttributeColumnImpl c; @@ -183,6 +236,9 @@ public class AttributeTableImpl implements AttributeTable { if (index == -1) { return null; } + + sendUnsetValueEventsForRemovedColumn(source); + //Remove from collections columnsMap.remove(source.getId().toLowerCase()); if (source.getTitle() != null && !source.getTitle().equals(source.getId())) { diff --git a/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/AttributeUtilsImpl.java b/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/AttributeUtilsImpl.java index fab1f7522..d1377ac46 100644 --- a/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/AttributeUtilsImpl.java +++ b/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/AttributeUtilsImpl.java @@ -1,284 +1,297 @@ -/* -Copyright 2008-2010 Gephi -Authors : Mathieu Bastian , Martin Škurla -Website : http://www.gephi.org - -This file is part of Gephi. - -DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - -Copyright 2011 Gephi Consortium. All rights reserved. - -The contents of this file are subject to the terms of either the GNU -General Public License Version 3 only ("GPL") or the Common -Development and Distribution License("CDDL") (collectively, the -"License"). You may not use this file except in compliance with the -License. You can obtain a copy of the License at -http://gephi.org/about/legal/license-notice/ -or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the -specific language governing permissions and limitations under the -License. When distributing the software, include this License Header -Notice in each file and include the License files at -/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the -License Header, with the fields enclosed by brackets [] replaced by -your own identifying information: -"Portions Copyrighted [year] [name of copyright owner]" - -If you wish your version of this file to be governed by only the CDDL -or only the GPL Version 3, indicate your decision by adding -"[Contributor] elects to include this software in this distribution -under the [CDDL or GPL Version 3] license." If you do not indicate a -single choice of license, a recipient has the option to distribute -your version of this file under either the CDDL, the GPL Version 3 or -to extend the choice of license to its licensees as provided above. -However, if you add GPL Version 3 code and therefore, elected the GPL -Version 3 license, then the option applies only if the new code is -made subject to such option by the copyright holder. - -Contributor(s): - -Portions Copyrighted 2011 Gephi Consortium. - */ -package org.gephi.data.attributes; - -import java.util.ArrayList; -import java.util.List; -import org.gephi.data.attributes.api.AttributeColumn; -import org.gephi.data.attributes.api.AttributeModel; -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.NumberList; -import org.openide.util.lookup.ServiceProvider; - -/** - * - * @author Mathieu Bastian - * @author Martin Škurla - */ -@ServiceProvider(service = AttributeUtils.class) -public class AttributeUtilsImpl extends AttributeUtils { - - @Override - public boolean isColumnOfType(AttributeColumn column, AttributeType type) { - return column.getType() == type; - } - - @Override - public boolean areAllColumnsOfType(AttributeColumn[] columns, AttributeType type) { - for (AttributeColumn column : columns) { - if (!isColumnOfType(column, type)) { - return false; - } - } - return true; - } - - @Override - public boolean areAllColumnsOfSameType(AttributeColumn[] columns) { - if (columns.length == 0) { - return false; - } - AttributeType type = columns[0].getType(); - return areAllColumnsOfType(columns, type); - } - - @Override - public boolean isStringColumn(AttributeColumn column) { - return column.getType().equals(AttributeType.STRING) || column.getType().equals(AttributeType.LIST_STRING); - } - - @Override - public boolean areAllStringColumns(AttributeColumn[] columns) { - for (AttributeColumn column : columns) { - if (!isStringColumn(column)) { - return false; - } - } - return true; - } - - @Override - public boolean isNumberColumn(AttributeColumn column) { - AttributeType attributeType = column.getType(); - return Number.class.isAssignableFrom(attributeType.getType()); - } - - @Override - public boolean areAllNumberColumns(AttributeColumn[] columns) { - for (AttributeColumn column : columns) { - if (!isNumberColumn(column)) { - return false; - } - } - return true; - } - - @Override - public boolean isNumberListColumn(AttributeColumn column) { - AttributeType attributeType = column.getType(); - return NumberList.class.isAssignableFrom(attributeType.getType()); - } - - @Override - public boolean areAllNumberListColumns(AttributeColumn[] columns) { - for (AttributeColumn column : columns) { - if (!isNumberListColumn(column)) { - return false; - } - } - return true; - } - - @Override - public boolean isNumberOrNumberListColumn(AttributeColumn column) { - return isNumberColumn(column) || isNumberListColumn(column); - } - - @Override - public boolean areAllNumberOrNumberListColumns(AttributeColumn[] columns) { - for (AttributeColumn column : columns) { - if (!isNumberOrNumberListColumn(column)) { - return false; - } - } - return true; - } - - public boolean isDynamicNumberColumn(AttributeColumn column) { - switch (column.getType()) { - case DYNAMIC_BIGDECIMAL: - case DYNAMIC_BIGINTEGER: - case DYNAMIC_BYTE: - case DYNAMIC_DOUBLE: - case DYNAMIC_FLOAT: - case DYNAMIC_INT: - case DYNAMIC_LONG: - case DYNAMIC_SHORT: - return true; - default: - return false; - } - } - - public boolean areAllDynamicNumberColumns(AttributeColumn[] columns) { - for (AttributeColumn column : columns) { - if (!isDynamicNumberColumn(column)) { - return false; - } - } - return true; - } - - @Override - @SuppressWarnings({"rawtypes", "unchecked"}) - public Comparable getMin(AttributeColumn column, Comparable[] values) { - if (!isNumberColumn(column) && !isDynamicNumberColumn(column)) { - throw new IllegalArgumentException("Colun must be a number column"); - } - - switch (values.length) { - case 0: - return null; - case 1: - return values[0]; - // values.length > 1 - default: - Comparable min = values[0]; - - for (int index = 1; index < values.length; index++) { - Comparable o = values[index]; - if (o.compareTo(min) < 0) { - min = o; - } - } - - return min; - } - } - - @Override - @SuppressWarnings({"rawtypes", "unchecked"}) - public Comparable getMax(AttributeColumn column, Comparable[] values) { - if (!isNumberColumn(column) && !isDynamicNumberColumn(column)) { - throw new IllegalArgumentException("Colun must be a number column"); - } - - switch (values.length) { - case 0: - return null; - case 1: - return values[0]; - // values.length > 1 - default: - Comparable max = values[0]; - - for (int index = 1; index < values.length; index++) { - Comparable o = values[index]; - if (o.compareTo(max) > 0) { - max = o; - } - } - - return max; - } - } - - @Override - public boolean isNodeColumn(AttributeColumn column) { - if (column == null) { - throw new NullPointerException(); - } - AttributeColumnImpl columnImpl = (AttributeColumnImpl) column; - AttributeTableImpl table = columnImpl.getTable(); - if (table == table.getModel().getNodeTable()) { - return true; - } - return false; - } - - @Override - public boolean isEdgeColumn(AttributeColumn column) { - if (column == null) { - throw new NullPointerException(); - } - AttributeColumnImpl columnImpl = (AttributeColumnImpl) column; - AttributeTableImpl table = columnImpl.getTable(); - if (table == table.getModel().getEdgeTable()) { - return true; - } - return false; - } - - @Override - public AttributeColumn[] getNumberColumns(AttributeTable table) { - List res = new ArrayList(); - for (AttributeColumn c : table.getColumns()) { - if (isNumberColumn(c)) { - res.add(c); - } - } - return res.toArray(new AttributeColumn[0]); - } - - @Override - public AttributeColumn[] getStringColumns(AttributeTable table) { - List res = new ArrayList(); - for (AttributeColumn c : table.getColumns()) { - if (isStringColumn(c)) { - res.add(c); - } - } - return res.toArray(new AttributeColumn[0]); - } - - @Override - public AttributeColumn[] getAllCollums(AttributeModel model) { - List cols = new ArrayList(); - for (AttributeTable t : model.getTables()) { - AttributeTableImpl tableImpl = (AttributeTableImpl) t; - cols.addAll(tableImpl.columns); - } - return cols.toArray(new AttributeColumn[0]); - } -} +/* +Copyright 2008-2010 Gephi +Authors : Mathieu Bastian , Martin Škurla +Website : http://www.gephi.org + +This file is part of Gephi. + +DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + +Copyright 2011 Gephi Consortium. All rights reserved. + +The contents of this file are subject to the terms of either the GNU +General Public License Version 3 only ("GPL") or the Common +Development and Distribution License("CDDL") (collectively, the +"License"). You may not use this file except in compliance with the +License. You can obtain a copy of the License at +http://gephi.org/about/legal/license-notice/ +or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the +specific language governing permissions and limitations under the +License. When distributing the software, include this License Header +Notice in each file and include the License files at +/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the +License Header, with the fields enclosed by brackets [] replaced by +your own identifying information: +"Portions Copyrighted [year] [name of copyright owner]" + +If you wish your version of this file to be governed by only the CDDL +or only the GPL Version 3, indicate your decision by adding +"[Contributor] elects to include this software in this distribution +under the [CDDL or GPL Version 3] license." If you do not indicate a +single choice of license, a recipient has the option to distribute +your version of this file under either the CDDL, the GPL Version 3 or +to extend the choice of license to its licensees as provided above. +However, if you add GPL Version 3 code and therefore, elected the GPL +Version 3 license, then the option applies only if the new code is +made subject to such option by the copyright holder. + +Contributor(s): + +Portions Copyrighted 2011 Gephi Consortium. + */ +package org.gephi.data.attributes; + +import java.util.ArrayList; +import java.util.List; +import org.gephi.data.attributes.api.AttributeColumn; +import org.gephi.data.attributes.api.AttributeModel; +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.NumberList; +import org.openide.util.lookup.ServiceProvider; + +/** + * + * @author Mathieu Bastian + * @author Martin Škurla + */ +@ServiceProvider(service = AttributeUtils.class) +public class AttributeUtilsImpl extends AttributeUtils { + + @Override + public boolean isColumnOfType(AttributeColumn column, AttributeType type) { + return column.getType() == type; + } + + @Override + public boolean areAllColumnsOfType(AttributeColumn[] columns, AttributeType type) { + for (AttributeColumn column : columns) { + if (!isColumnOfType(column, type)) { + return false; + } + } + return true; + } + + @Override + public boolean areAllColumnsOfSameType(AttributeColumn[] columns) { + if (columns.length == 0) { + return false; + } + AttributeType type = columns[0].getType(); + return areAllColumnsOfType(columns, type); + } + + @Override + public boolean isStringColumn(AttributeColumn column) { + return column.getType().equals(AttributeType.STRING) || column.getType().equals(AttributeType.LIST_STRING); + } + + @Override + public boolean areAllStringColumns(AttributeColumn[] columns) { + for (AttributeColumn column : columns) { + if (!isStringColumn(column)) { + return false; + } + } + return true; + } + + @Override + public boolean isNumberColumn(AttributeColumn column) { + AttributeType attributeType = column.getType(); + return Number.class.isAssignableFrom(attributeType.getType()); + } + + @Override + public boolean areAllNumberColumns(AttributeColumn[] columns) { + for (AttributeColumn column : columns) { + if (!isNumberColumn(column)) { + return false; + } + } + return true; + } + + @Override + public boolean isNumberListColumn(AttributeColumn column) { + AttributeType attributeType = column.getType(); + return NumberList.class.isAssignableFrom(attributeType.getType()); + } + + @Override + public boolean areAllNumberListColumns(AttributeColumn[] columns) { + for (AttributeColumn column : columns) { + if (!isNumberListColumn(column)) { + return false; + } + } + return true; + } + + @Override + public boolean isNumberOrNumberListColumn(AttributeColumn column) { + return isNumberColumn(column) || isNumberListColumn(column); + } + + @Override + public boolean areAllNumberOrNumberListColumns(AttributeColumn[] columns) { + for (AttributeColumn column : columns) { + if (!isNumberOrNumberListColumn(column)) { + return false; + } + } + return true; + } + + public boolean isDynamicNumberColumn(AttributeColumn column) { + switch (column.getType()) { + case DYNAMIC_BIGDECIMAL: + case DYNAMIC_BIGINTEGER: + case DYNAMIC_BYTE: + case DYNAMIC_DOUBLE: + case DYNAMIC_FLOAT: + case DYNAMIC_INT: + case DYNAMIC_LONG: + case DYNAMIC_SHORT: + return true; + default: + return false; + } + } + + public boolean areAllDynamicNumberColumns(AttributeColumn[] columns) { + for (AttributeColumn column : columns) { + if (!isDynamicNumberColumn(column)) { + return false; + } + } + return true; + } + + @Override + @SuppressWarnings({"rawtypes", "unchecked"}) + public Comparable getMin(AttributeColumn column, Comparable[] values) { + if (!isNumberColumn(column) && !isDynamicNumberColumn(column)) { + throw new IllegalArgumentException("Colun must be a number column"); + } + + switch (values.length) { + case 0: + return null; + case 1: + return values[0]; + // values.length > 1 + default: + Comparable min = values[0]; + + for (int index = 1; index < values.length; index++) { + Comparable o = values[index]; + if (o.compareTo(min) < 0) { + min = o; + } + } + + return min; + } + } + + @Override + @SuppressWarnings({"rawtypes", "unchecked"}) + public Comparable getMax(AttributeColumn column, Comparable[] values) { + if (!isNumberColumn(column) && !isDynamicNumberColumn(column)) { + throw new IllegalArgumentException("Colun must be a number column"); + } + + switch (values.length) { + case 0: + return null; + case 1: + return values[0]; + // values.length > 1 + default: + Comparable max = values[0]; + + for (int index = 1; index < values.length; index++) { + Comparable o = values[index]; + if (o.compareTo(max) > 0) { + max = o; + } + } + + return max; + } + } + + @Override + public boolean isNodeColumn(AttributeColumn column) { + if (column == null) { + throw new NullPointerException(); + } + AttributeColumnImpl columnImpl = (AttributeColumnImpl) column; + AttributeTableImpl table = columnImpl.getTable(); + if (table == table.getModel().getNodeTable()) { + return true; + } + return false; + } + + @Override + public boolean isEdgeColumn(AttributeColumn column) { + if (column == null) { + throw new NullPointerException(); + } + AttributeColumnImpl columnImpl = (AttributeColumnImpl) column; + AttributeTableImpl table = columnImpl.getTable(); + if (table == table.getModel().getEdgeTable()) { + return true; + } + return false; + } + + @Override + public boolean isGraphColumn(AttributeColumn column) { + if (column == null) { + throw new NullPointerException(); + } + AttributeColumnImpl columnImpl = (AttributeColumnImpl) column; + AttributeTableImpl table = columnImpl.getTable(); + if (table == table.getModel().getGraphTable()) { + return true; + } + return false; + } + + @Override + public AttributeColumn[] getNumberColumns(AttributeTable table) { + List res = new ArrayList(); + for (AttributeColumn c : table.getColumns()) { + if (isNumberColumn(c)) { + res.add(c); + } + } + return res.toArray(new AttributeColumn[0]); + } + + @Override + public AttributeColumn[] getStringColumns(AttributeTable table) { + List res = new ArrayList(); + for (AttributeColumn c : table.getColumns()) { + if (isStringColumn(c)) { + res.add(c); + } + } + return res.toArray(new AttributeColumn[0]); + } + + @Override + public AttributeColumn[] getAllCollums(AttributeModel model) { + List cols = new ArrayList(); + for (AttributeTable t : model.getTables()) { + AttributeTableImpl tableImpl = (AttributeTableImpl) t; + cols.addAll(tableImpl.columns); + } + return cols.toArray(new AttributeColumn[0]); + } +} diff --git a/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/model/IndexedAttributeModel.java b/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/model/IndexedAttributeModel.java index ada88f763..a69ebf18a 100644 --- a/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/model/IndexedAttributeModel.java +++ b/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/model/IndexedAttributeModel.java @@ -1,75 +1,77 @@ -/* -Copyright 2008-2010 Gephi -Authors : Mathieu Bastian , Martin Škurla -Website : http://www.gephi.org - -This file is part of Gephi. - -DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - -Copyright 2011 Gephi Consortium. All rights reserved. - -The contents of this file are subject to the terms of either the GNU -General Public License Version 3 only ("GPL") or the Common -Development and Distribution License("CDDL") (collectively, the -"License"). You may not use this file except in compliance with the -License. You can obtain a copy of the License at -http://gephi.org/about/legal/license-notice/ -or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the -specific language governing permissions and limitations under the -License. When distributing the software, include this License Header -Notice in each file and include the License files at -/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the -License Header, with the fields enclosed by brackets [] replaced by -your own identifying information: -"Portions Copyrighted [year] [name of copyright owner]" - -If you wish your version of this file to be governed by only the CDDL -or only the GPL Version 3, indicate your decision by adding -"[Contributor] elects to include this software in this distribution -under the [CDDL or GPL Version 3] license." If you do not indicate a -single choice of license, a recipient has the option to distribute -your version of this file under either the CDDL, the GPL Version 3 or -to extend the choice of license to its licensees as provided above. -However, if you add GPL Version 3 code and therefore, elected the GPL -Version 3 license, then the option applies only if the new code is -made subject to such option by the copyright holder. - -Contributor(s): - -Portions Copyrighted 2011 Gephi Consortium. -*/ -package org.gephi.data.attributes.model; - -import org.gephi.data.attributes.AbstractAttributeModel; -import org.gephi.data.attributes.api.AttributeType; -import org.gephi.data.attributes.event.AttributeEventManager; - -/** - * - * @author Mathieu Bastian - * @author Martin Škurla - */ -public class IndexedAttributeModel extends AbstractAttributeModel { - - protected DataIndex dataIndex; - - public IndexedAttributeModel() { - dataIndex = new DataIndex(); - eventManager = new AttributeEventManager(this); - createPropertiesColumn(); - - eventManager.start(); - } - - @Override - public Object getManagedValue(Object obj, AttributeType attributeType) { - return dataIndex.pushData(obj); - } - - @Override - public void clear() { - super.clear(); - dataIndex.clear(); - } -} +/* +Copyright 2008-2010 Gephi +Authors : Mathieu Bastian , Martin Škurla +Website : http://www.gephi.org + +This file is part of Gephi. + +DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + +Copyright 2011 Gephi Consortium. All rights reserved. + +The contents of this file are subject to the terms of either the GNU +General Public License Version 3 only ("GPL") or the Common +Development and Distribution License("CDDL") (collectively, the +"License"). You may not use this file except in compliance with the +License. You can obtain a copy of the License at +http://gephi.org/about/legal/license-notice/ +or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the +specific language governing permissions and limitations under the +License. When distributing the software, include this License Header +Notice in each file and include the License files at +/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the +License Header, with the fields enclosed by brackets [] replaced by +your own identifying information: +"Portions Copyrighted [year] [name of copyright owner]" + +If you wish your version of this file to be governed by only the CDDL +or only the GPL Version 3, indicate your decision by adding +"[Contributor] elects to include this software in this distribution +under the [CDDL or GPL Version 3] license." If you do not indicate a +single choice of license, a recipient has the option to distribute +your version of this file under either the CDDL, the GPL Version 3 or +to extend the choice of license to its licensees as provided above. +However, if you add GPL Version 3 code and therefore, elected the GPL +Version 3 license, then the option applies only if the new code is +made subject to such option by the copyright holder. + +Contributor(s): + +Portions Copyrighted 2011 Gephi Consortium. +*/ +package org.gephi.data.attributes.model; + +import org.gephi.data.attributes.AbstractAttributeModel; +import org.gephi.data.attributes.api.AttributeType; +import org.gephi.data.attributes.event.AttributeEventManager; +import org.gephi.project.api.Workspace; + +/** + * + * @author Mathieu Bastian + * @author Martin Škurla + */ +public class IndexedAttributeModel extends AbstractAttributeModel { + + protected DataIndex dataIndex; + + public IndexedAttributeModel(Workspace workspace) { + super(workspace); + dataIndex = new DataIndex(); + eventManager = new AttributeEventManager(this); + createPropertiesColumn(); + + eventManager.start(); + } + + @Override + public Object getManagedValue(Object obj, AttributeType attributeType) { + return dataIndex.pushData(obj); + } + + @Override + public void clear() { + super.clear(); + dataIndex.clear(); + } +} diff --git a/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/model/TemporaryAttributeModel.java b/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/model/TemporaryAttributeModel.java index d75ae7bb7..727b989c6 100644 --- a/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/model/TemporaryAttributeModel.java +++ b/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/model/TemporaryAttributeModel.java @@ -1,81 +1,83 @@ -/* -Copyright 2008-2010 Gephi -Authors : Mathieu Bastian -Website : http://www.gephi.org - -This file is part of Gephi. - -DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - -Copyright 2011 Gephi Consortium. All rights reserved. - -The contents of this file are subject to the terms of either the GNU -General Public License Version 3 only ("GPL") or the Common -Development and Distribution License("CDDL") (collectively, the -"License"). You may not use this file except in compliance with the -License. You can obtain a copy of the License at -http://gephi.org/about/legal/license-notice/ -or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the -specific language governing permissions and limitations under the -License. When distributing the software, include this License Header -Notice in each file and include the License files at -/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the -License Header, with the fields enclosed by brackets [] replaced by -your own identifying information: -"Portions Copyrighted [year] [name of copyright owner]" - -If you wish your version of this file to be governed by only the CDDL -or only the GPL Version 3, indicate your decision by adding -"[Contributor] elects to include this software in this distribution -under the [CDDL or GPL Version 3] license." If you do not indicate a -single choice of license, a recipient has the option to distribute -your version of this file under either the CDDL, the GPL Version 3 or -to extend the choice of license to its licensees as provided above. -However, if you add GPL Version 3 code and therefore, elected the GPL -Version 3 license, then the option applies only if the new code is -made subject to such option by the copyright holder. - -Contributor(s): - -Portions Copyrighted 2011 Gephi Consortium. - */ -package org.gephi.data.attributes.model; - -import org.gephi.data.attributes.AbstractAttributeModel; -import org.gephi.data.attributes.api.AttributeListener; -import org.gephi.data.attributes.api.AttributeType; -import org.gephi.data.attributes.event.AbstractEvent; - -/** - * Specific manager for temporary storing of attributes. This is typically used when new attributes are - * imported in the system. No index system is required. - *

- * - * @author Mathieu Bastian - * @see IndexedAttributeManager - */ -public class TemporaryAttributeModel extends AbstractAttributeModel { - - public TemporaryAttributeModel() { - createPropertiesColumn(); - } - - @Override - public Object getManagedValue(Object obj, AttributeType attributeType) { - return obj; - } - - @Override - public void addAttributeListener(AttributeListener listener) { - throw new UnsupportedOperationException("Temporary Attribute Model doens't supper events"); - } - - @Override - public void removeAttributeListener(AttributeListener listener) { - throw new UnsupportedOperationException("Temporary Attribute Model doens't supper events"); - } - - @Override - public void fireAttributeEvent(AbstractEvent event) { - } -} +/* +Copyright 2008-2010 Gephi +Authors : Mathieu Bastian +Website : http://www.gephi.org + +This file is part of Gephi. + +DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + +Copyright 2011 Gephi Consortium. All rights reserved. + +The contents of this file are subject to the terms of either the GNU +General Public License Version 3 only ("GPL") or the Common +Development and Distribution License("CDDL") (collectively, the +"License"). You may not use this file except in compliance with the +License. You can obtain a copy of the License at +http://gephi.org/about/legal/license-notice/ +or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the +specific language governing permissions and limitations under the +License. When distributing the software, include this License Header +Notice in each file and include the License files at +/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the +License Header, with the fields enclosed by brackets [] replaced by +your own identifying information: +"Portions Copyrighted [year] [name of copyright owner]" + +If you wish your version of this file to be governed by only the CDDL +or only the GPL Version 3, indicate your decision by adding +"[Contributor] elects to include this software in this distribution +under the [CDDL or GPL Version 3] license." If you do not indicate a +single choice of license, a recipient has the option to distribute +your version of this file under either the CDDL, the GPL Version 3 or +to extend the choice of license to its licensees as provided above. +However, if you add GPL Version 3 code and therefore, elected the GPL +Version 3 license, then the option applies only if the new code is +made subject to such option by the copyright holder. + +Contributor(s): + +Portions Copyrighted 2011 Gephi Consortium. + */ +package org.gephi.data.attributes.model; + +import org.gephi.data.attributes.AbstractAttributeModel; +import org.gephi.data.attributes.api.AttributeListener; +import org.gephi.data.attributes.api.AttributeType; +import org.gephi.data.attributes.event.AbstractEvent; +import org.gephi.project.api.Workspace; + +/** + * Specific manager for temporary storing of attributes. This is typically used when new attributes are + * imported in the system. No index system is required. + *

+ * + * @author Mathieu Bastian + * @see IndexedAttributeManager + */ +public class TemporaryAttributeModel extends AbstractAttributeModel { + + public TemporaryAttributeModel(Workspace workspace) { + super(workspace); + createPropertiesColumn(); + } + + @Override + public Object getManagedValue(Object obj, AttributeType attributeType) { + return obj; + } + + @Override + public void addAttributeListener(AttributeListener listener) { + throw new UnsupportedOperationException("Temporary Attribute Model doens't supper events"); + } + + @Override + public void removeAttributeListener(AttributeListener listener) { + throw new UnsupportedOperationException("Temporary Attribute Model doens't supper events"); + } + + @Override + public void fireAttributeEvent(AbstractEvent event) { + } +} diff --git a/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/serialization/AttributeModelPersistenceProvider.java b/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/serialization/AttributeModelPersistenceProvider.java index 42b29ae62..2cb4dd45c 100644 --- a/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/serialization/AttributeModelPersistenceProvider.java +++ b/modules/AttributesImpl/src/main/java/org/gephi/data/attributes/serialization/AttributeModelPersistenceProvider.java @@ -1,90 +1,90 @@ -/* -Copyright 2008-2010 Gephi -Authors : Mathieu Bastian -Website : http://www.gephi.org - -This file is part of Gephi. - -DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - -Copyright 2011 Gephi Consortium. All rights reserved. - -The contents of this file are subject to the terms of either the GNU -General Public License Version 3 only ("GPL") or the Common -Development and Distribution License("CDDL") (collectively, the -"License"). You may not use this file except in compliance with the -License. You can obtain a copy of the License at -http://gephi.org/about/legal/license-notice/ -or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the -specific language governing permissions and limitations under the -License. When distributing the software, include this License Header -Notice in each file and include the License files at -/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the -License Header, with the fields enclosed by brackets [] replaced by -your own identifying information: -"Portions Copyrighted [year] [name of copyright owner]" - -If you wish your version of this file to be governed by only the CDDL -or only the GPL Version 3, indicate your decision by adding -"[Contributor] elects to include this software in this distribution -under the [CDDL or GPL Version 3] license." If you do not indicate a -single choice of license, a recipient has the option to distribute -your version of this file under either the CDDL, the GPL Version 3 or -to extend the choice of license to its licensees as provided above. -However, if you add GPL Version 3 code and therefore, elected the GPL -Version 3 license, then the option applies only if the new code is -made subject to such option by the copyright holder. - -Contributor(s): - -Portions Copyrighted 2011 Gephi Consortium. - */ -package org.gephi.data.attributes.serialization; - -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamReader; -import javax.xml.stream.XMLStreamWriter; -import org.gephi.data.attributes.AbstractAttributeModel; -import org.gephi.data.attributes.api.AttributeModel; -import org.gephi.data.attributes.model.IndexedAttributeModel; -import org.gephi.project.api.Workspace; -import org.gephi.project.spi.WorkspacePersistenceProvider; -import org.openide.util.lookup.ServiceProvider; - -/** - * - * @author Mathieu Bastian - */ -@ServiceProvider(service = WorkspacePersistenceProvider.class, position = 10) -public class AttributeModelPersistenceProvider implements WorkspacePersistenceProvider { - - public void writeXML(XMLStreamWriter writer, Workspace workspace) { - AttributeModel model = workspace.getLookup().lookup(AttributeModel.class); - AttributeModelSerializer serializer = new AttributeModelSerializer(); - if (model instanceof AbstractAttributeModel) { - try { - serializer.writeModel(writer, (AbstractAttributeModel) model); - } catch (XMLStreamException ex) { - throw new RuntimeException(ex); - } - } - } - - public void readXML(XMLStreamReader reader, Workspace workspace) { - IndexedAttributeModel model = workspace.getLookup().lookup(IndexedAttributeModel.class); - if (model == null) { - model = new IndexedAttributeModel(); - workspace.add(model); - } - AttributeModelSerializer serializer = new AttributeModelSerializer(); - try { - serializer.readModel(reader, model); - } catch (XMLStreamException ex) { - throw new RuntimeException(ex); - } - } - - public String getIdentifier() { - return "attributemodel"; - } -} +/* +Copyright 2008-2010 Gephi +Authors : Mathieu Bastian +Website : http://www.gephi.org + +This file is part of Gephi. + +DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + +Copyright 2011 Gephi Consortium. All rights reserved. + +The contents of this file are subject to the terms of either the GNU +General Public License Version 3 only ("GPL") or the Common +Development and Distribution License("CDDL") (collectively, the +"License"). You may not use this file except in compliance with the +License. You can obtain a copy of the License at +http://gephi.org/about/legal/license-notice/ +or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the +specific language governing permissions and limitations under the +License. When distributing the software, include this License Header +Notice in each file and include the License files at +/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the +License Header, with the fields enclosed by brackets [] replaced by +your own identifying information: +"Portions Copyrighted [year] [name of copyright owner]" + +If you wish your version of this file to be governed by only the CDDL +or only the GPL Version 3, indicate your decision by adding +"[Contributor] elects to include this software in this distribution +under the [CDDL or GPL Version 3] license." If you do not indicate a +single choice of license, a recipient has the option to distribute +your version of this file under either the CDDL, the GPL Version 3 or +to extend the choice of license to its licensees as provided above. +However, if you add GPL Version 3 code and therefore, elected the GPL +Version 3 license, then the option applies only if the new code is +made subject to such option by the copyright holder. + +Contributor(s): + +Portions Copyrighted 2011 Gephi Consortium. + */ +package org.gephi.data.attributes.serialization; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; +import org.gephi.data.attributes.AbstractAttributeModel; +import org.gephi.data.attributes.api.AttributeModel; +import org.gephi.data.attributes.model.IndexedAttributeModel; +import org.gephi.project.api.Workspace; +import org.gephi.project.spi.WorkspacePersistenceProvider; +import org.openide.util.lookup.ServiceProvider; + +/** + * + * @author Mathieu Bastian + */ +@ServiceProvider(service = WorkspacePersistenceProvider.class, position = 10) +public class AttributeModelPersistenceProvider implements WorkspacePersistenceProvider { + + public void writeXML(XMLStreamWriter writer, Workspace workspace) { + AttributeModel model = workspace.getLookup().lookup(AttributeModel.class); + AttributeModelSerializer serializer = new AttributeModelSerializer(); + if (model instanceof AbstractAttributeModel) { + try { + serializer.writeModel(writer, (AbstractAttributeModel) model); + } catch (XMLStreamException ex) { + throw new RuntimeException(ex); + } + } + } + + public void readXML(XMLStreamReader reader, Workspace workspace) { + IndexedAttributeModel model = workspace.getLookup().lookup(IndexedAttributeModel.class); + if (model == null) { + model = new IndexedAttributeModel(workspace); + workspace.add(model); + } + AttributeModelSerializer serializer = new AttributeModelSerializer(); + try { + serializer.readModel(reader, model); + } catch (XMLStreamException ex) { + throw new RuntimeException(ex); + } + } + + public String getIdentifier() { + return "attributemodel"; + } +} diff --git a/modules/DynamicImpl/src/main/java/org/gephi/dynamic/DynamicIndex.java b/modules/DynamicImpl/src/main/java/org/gephi/dynamic/DynamicIndex.java index 05e6e94d6..9cd696742 100644 --- a/modules/DynamicImpl/src/main/java/org/gephi/dynamic/DynamicIndex.java +++ b/modules/DynamicImpl/src/main/java/org/gephi/dynamic/DynamicIndex.java @@ -1,171 +1,174 @@ -/* - * Copyright 2008-2010 Gephi - * Authors : Cezary Bartosiak - * Website : http://www.gephi.org - * - * This file is part of Gephi. - * - DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - - Copyright 2011 Gephi Consortium. All rights reserved. - - The contents of this file are subject to the terms of either the GNU - General Public License Version 3 only ("GPL") or the Common - Development and Distribution License("CDDL") (collectively, the - "License"). You may not use this file except in compliance with the - License. You can obtain a copy of the License at - http://gephi.org/about/legal/license-notice/ - or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the - specific language governing permissions and limitations under the - License. When distributing the software, include this License Header - Notice in each file and include the License files at - /cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the - License Header, with the fields enclosed by brackets [] replaced by - your own identifying information: - "Portions Copyrighted [year] [name of copyright owner]" - - If you wish your version of this file to be governed by only the CDDL - or only the GPL Version 3, indicate your decision by adding - "[Contributor] elects to include this software in this distribution - under the [CDDL or GPL Version 3] license." If you do not indicate a - single choice of license, a recipient has the option to distribute - your version of this file under either the CDDL, the GPL Version 3 or - to extend the choice of license to its licensees as provided above. - However, if you add GPL Version 3 code and therefore, elected the GPL - Version 3 license, then the option applies only if the new code is - made subject to such option by the copyright holder. - - Contributor(s): - - Portions Copyrighted 2011 Gephi Consortium. - */ -package org.gephi.dynamic; - -import java.util.TreeMap; -import org.gephi.data.attributes.type.Interval; -import org.gephi.dynamic.api.DynamicModelEvent; - -/** - * - * @author Mathieu Bastian - */ -public class DynamicIndex { - - protected final TreeMap lowMap; - protected final TreeMap highMap; - protected final DynamicModelImpl model; - - public DynamicIndex(DynamicModelImpl model) { - this.model = model; - lowMap = new TreeMap(); - highMap = new TreeMap(); - } - - public synchronized void add(Interval interval) { - Double low = interval.getLow(); - Double high = interval.getHigh(); - boolean valid = (!lowMap.isEmpty() && !highMap.isEmpty()) || (lowMap.size() > 1 || highMap.size() > 1); - if (!valid) { - //Manually verify bounds - double min = getMin(); - double max = getMax(); - valid = !Double.isInfinite(min) && !Double.isInfinite(max); - } - boolean minChanged = false; - boolean maxChanged = false; - - if (!Double.isInfinite(low)) { - if (lowMap.get(low) != null) { - Integer counter = new Integer(lowMap.get(low) + 1); - lowMap.put(low, counter); - } else { - Double min = lowMap.isEmpty() ? Double.POSITIVE_INFINITY : lowMap.firstKey(); - lowMap.put(low, 1); - if (low < min) { - minChanged = true; - } - } - } - if (!Double.isInfinite(high)) { - if (highMap.get(high) != null) { - Integer counter = new Integer(highMap.get(high) + 1); - highMap.put(high, counter); - } else { - Double max = highMap.isEmpty() ? Double.NEGATIVE_INFINITY : highMap.lastKey(); - highMap.put(high, 1); - if (high > max) { - maxChanged = true; - } - } - } - - if (!valid && (minChanged || maxChanged)) { - //Look if valid now - double min = getMin(); - double max = getMax(); - valid = !Double.isInfinite(min) && !Double.isInfinite(max); - if (valid) { - fireEvent(new DynamicModelEvent(DynamicModelEvent.EventType.IS_DYNAMIC_GRAPH, model, Boolean.TRUE)); - } - } - - - if (minChanged && valid) { - fireEvent(new DynamicModelEvent(DynamicModelEvent.EventType.MIN_CHANGED, model, low)); - } - if (maxChanged && valid) { - fireEvent(new DynamicModelEvent(DynamicModelEvent.EventType.MAX_CHANGED, model, high)); - } - } - - public synchronized void remove(Interval interval) { - Double low = interval.getLow(); - Double high = interval.getHigh(); - if (!Double.isInfinite(low) && lowMap.get(low) != null) { - Integer counter = new Integer(lowMap.get(low) - 1); - if (counter == 0) { - Double min = lowMap.firstKey(); - lowMap.remove(low); - if (min.equals(low)) { - fireEvent(new DynamicModelEvent(DynamicModelEvent.EventType.MIN_CHANGED, model, getMin())); - } - } else { - lowMap.put(low, counter); - } - } - if (!Double.isInfinite(high) && highMap.get(high) != null) { - Integer counter = new Integer(highMap.get(high) - 1); - if (counter == 0) { - Double max = highMap.lastKey(); - highMap.remove(high); - if (max.equals(high)) { - fireEvent(new DynamicModelEvent(DynamicModelEvent.EventType.MAX_CHANGED, model, getMax())); - } - } else { - highMap.put(high, counter); - } - } - if (lowMap.isEmpty() && highMap.isEmpty()) { - fireEvent(new DynamicModelEvent(DynamicModelEvent.EventType.IS_DYNAMIC_GRAPH, model, Boolean.FALSE)); - } - } - - public synchronized void clear() { - lowMap.clear(); - highMap.clear(); - } - - public synchronized double getMin() { - return lowMap.isEmpty() ? (highMap.isEmpty() ? Double.NEGATIVE_INFINITY : highMap.firstKey()) : lowMap.firstKey(); - } - - public synchronized double getMax() { - return highMap.isEmpty() ? (lowMap.isEmpty() ? Double.POSITIVE_INFINITY : lowMap.lastKey()) : highMap.lastKey(); - } - - private void fireEvent(DynamicModelEvent event) { - if (model != null) { - model.controller.fireModelEvent(event); - } - } -} +/* + * Copyright 2008-2010 Gephi + * Authors : Cezary Bartosiak + * Website : http://www.gephi.org + * + * This file is part of Gephi. + * + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + + Copyright 2011 Gephi Consortium. All rights reserved. + + The contents of this file are subject to the terms of either the GNU + General Public License Version 3 only ("GPL") or the Common + Development and Distribution License("CDDL") (collectively, the + "License"). You may not use this file except in compliance with the + License. You can obtain a copy of the License at + http://gephi.org/about/legal/license-notice/ + or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the + specific language governing permissions and limitations under the + License. When distributing the software, include this License Header + Notice in each file and include the License files at + /cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the + License Header, with the fields enclosed by brackets [] replaced by + your own identifying information: + "Portions Copyrighted [year] [name of copyright owner]" + + If you wish your version of this file to be governed by only the CDDL + or only the GPL Version 3, indicate your decision by adding + "[Contributor] elects to include this software in this distribution + under the [CDDL or GPL Version 3] license." If you do not indicate a + single choice of license, a recipient has the option to distribute + your version of this file under either the CDDL, the GPL Version 3 or + to extend the choice of license to its licensees as provided above. + However, if you add GPL Version 3 code and therefore, elected the GPL + Version 3 license, then the option applies only if the new code is + made subject to such option by the copyright holder. + + Contributor(s): + + Portions Copyrighted 2011 Gephi Consortium. + */ +package org.gephi.dynamic; + +import java.util.TreeMap; +import org.gephi.data.attributes.type.Interval; +import org.gephi.dynamic.api.DynamicModelEvent; + +/** + * + * @author Mathieu Bastian + */ +public class DynamicIndex { + + protected final TreeMap lowMap; + protected final TreeMap highMap; + protected final DynamicModelImpl model; + + public DynamicIndex(DynamicModelImpl model) { + this.model = model; + lowMap = new TreeMap(); + highMap = new TreeMap(); + } + + public synchronized void add(Interval interval) { + Double low = interval.getLow(); + Double high = interval.getHigh(); + boolean valid = (!lowMap.isEmpty() && !highMap.isEmpty()) || (lowMap.size() > 1 || highMap.size() > 1); + if (!valid) { + //Manually verify bounds + double min = getMin(); + double max = getMax(); + valid = !Double.isInfinite(min) && !Double.isInfinite(max); + } + boolean minChanged = false; + boolean maxChanged = false; + + if (!Double.isInfinite(low)) { + if (lowMap.get(low) != null) { + Integer counter = new Integer(lowMap.get(low) + 1); + lowMap.put(low, counter); + } else { + Double min = lowMap.isEmpty() ? Double.POSITIVE_INFINITY : lowMap.firstKey(); + lowMap.put(low, 1); + if (low < min) { + minChanged = true; + } + } + } + if (!Double.isInfinite(high)) { + if (highMap.get(high) != null) { + Integer counter = new Integer(highMap.get(high) + 1); + highMap.put(high, counter); + } else { + Double max = highMap.isEmpty() ? Double.NEGATIVE_INFINITY : highMap.lastKey(); + highMap.put(high, 1); + if (high > max) { + maxChanged = true; + } + } + } + + if (!valid && (minChanged || maxChanged)) { + //Look if valid now + double min = getMin(); + double max = getMax(); + valid = !Double.isInfinite(min) && !Double.isInfinite(max); + if (valid) { + fireEvent(new DynamicModelEvent(DynamicModelEvent.EventType.IS_DYNAMIC_GRAPH, model, Boolean.TRUE)); + } + } + + + if (minChanged && valid) { + fireEvent(new DynamicModelEvent(DynamicModelEvent.EventType.MIN_CHANGED, model, low)); + } + if (maxChanged && valid) { + fireEvent(new DynamicModelEvent(DynamicModelEvent.EventType.MAX_CHANGED, model, high)); + } + } + + public synchronized void remove(Interval interval) { + Double low = interval.getLow(); + Double high = interval.getHigh(); + if (!Double.isInfinite(low) && lowMap.get(low) != null) { + Integer counter = new Integer(lowMap.get(low) - 1); + if (counter == 0) { + Double min = lowMap.firstKey(); + lowMap.remove(low); + if (min.equals(low)) { + fireEvent(new DynamicModelEvent(DynamicModelEvent.EventType.MIN_CHANGED, model, getMin())); + } + } else { + lowMap.put(low, counter); + } + } + if (!Double.isInfinite(high) && highMap.get(high) != null) { + Integer counter = new Integer(highMap.get(high) - 1); + if (counter == 0) { + Double max = highMap.lastKey(); + highMap.remove(high); + if (max.equals(high)) { + fireEvent(new DynamicModelEvent(DynamicModelEvent.EventType.MAX_CHANGED, model, getMax())); + } + } else { + highMap.put(high, counter); + } + } + if (lowMap.isEmpty() && highMap.isEmpty()) { + fireEvent(new DynamicModelEvent(DynamicModelEvent.EventType.IS_DYNAMIC_GRAPH, model, Boolean.FALSE)); + } + } + + public synchronized void clear() { + lowMap.clear(); + highMap.clear(); + fireEvent(new DynamicModelEvent(DynamicModelEvent.EventType.MIN_CHANGED, model, getMin())); + fireEvent(new DynamicModelEvent(DynamicModelEvent.EventType.MAX_CHANGED, model, getMax())); + fireEvent(new DynamicModelEvent(DynamicModelEvent.EventType.IS_DYNAMIC_GRAPH, model, Boolean.FALSE)); + } + + public synchronized double getMin() { + return lowMap.isEmpty() ? (highMap.isEmpty() ? Double.NEGATIVE_INFINITY : highMap.firstKey()) : lowMap.firstKey(); + } + + public synchronized double getMax() { + return highMap.isEmpty() ? (lowMap.isEmpty() ? Double.POSITIVE_INFINITY : lowMap.lastKey()) : highMap.lastKey(); + } + + private void fireEvent(DynamicModelEvent event) { + if (model != null) { + model.controller.fireModelEvent(event); + } + } +} diff --git a/modules/DynamicImpl/src/main/java/org/gephi/dynamic/DynamicModelImpl.java b/modules/DynamicImpl/src/main/java/org/gephi/dynamic/DynamicModelImpl.java index dcd0902b1..4284a6e58 100644 --- a/modules/DynamicImpl/src/main/java/org/gephi/dynamic/DynamicModelImpl.java +++ b/modules/DynamicImpl/src/main/java/org/gephi/dynamic/DynamicModelImpl.java @@ -270,48 +270,54 @@ public final class DynamicModelImpl implements DynamicModel { graphModel.addGraphListener(graphListener); } - private void refresh() { - timeIntervalIndex.clear(); - for (AttributeColumn col : attributeModel.getNodeTable().getColumns()) { - if (col.getType().isDynamicType()) { - nodeDynamicColumns.add(col); + private void indexNodeColumnsValues(AttributeColumn[] dynamicCols) { + Graph graph = graphModel.getGraph(); + for (Node n : graph.getNodes()) { + Attributes attributeRow = n.getNodeData().getAttributes(); + for (int i = 0; i < dynamicCols.length; i++) { + DynamicType ti = (DynamicType) attributeRow.getValue(dynamicCols[i].getIndex()); + if (ti != null) { + for (Interval interval : ti.getIntervals(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY)) { + timeIntervalIndex.add(interval); + } + } } } - AttributeColumn[] dynamicCols = nodeDynamicColumns.toArray(new AttributeColumn[0]); - if (dynamicCols.length > 0) { - Graph graph = graphModel.getGraph(); - for (Node n : graph.getNodes()) { - Attributes attributeRow = n.getNodeData().getAttributes(); - for (int i = 0; i < dynamicCols.length; i++) { - DynamicType ti = (DynamicType) attributeRow.getValue(dynamicCols[i].getIndex()); - if (ti != null) { - for (Interval interval : ti.getIntervals(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY)) { - timeIntervalIndex.add(interval); - } + } + + private void indexEdgeColumnsValues(AttributeColumn[] dynamicCols) { + Graph graph = graphModel.getGraph(); + for (Edge e : graph.getEdges()) { + Attributes attributeRow = e.getEdgeData().getAttributes(); + for (int i = 0; i < dynamicCols.length; i++) { + DynamicType ti = (DynamicType) attributeRow.getValue(dynamicCols[i].getIndex()); + if (ti != null) { + for (Interval interval : ti.getIntervals(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY)) { + timeIntervalIndex.add(interval); } } } } + } + + private void refresh() { + timeIntervalIndex.clear(); + nodeDynamicColumns.clear(); + edgeDynamicColumns.clear(); + for (AttributeColumn col : attributeModel.getNodeTable().getColumns()) { if (col.getType().isDynamicType()) { - edgeDynamicColumns.add(col); + nodeDynamicColumns.add(col); } } - dynamicCols = edgeDynamicColumns.toArray(new AttributeColumn[0]); - if (dynamicCols.length > 0) { - Graph graph = graphModel.getGraph(); - for (Edge e : graph.getEdges()) { - Attributes attributeRow = e.getEdgeData().getAttributes(); - for (int i = 0; i < dynamicCols.length; i++) { - DynamicType ti = (DynamicType) attributeRow.getValue(dynamicCols[i].getIndex()); - if (ti != null) { - for (Interval interval : ti.getIntervals(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY)) { - timeIntervalIndex.add(interval); - } - } - } + indexNodeColumnsValues(nodeDynamicColumns.toArray(new AttributeColumn[0])); + + for (AttributeColumn col : attributeModel.getNodeTable().getColumns()) { + if (col.getType().isDynamicType()) { + edgeDynamicColumns.add(col); } } + indexEdgeColumnsValues(edgeDynamicColumns.toArray(new AttributeColumn[0])); } @Override -- GitLab