Package org.gephi.io.importer.plugin.file

Source Code of org.gephi.io.importer.plugin.file.ImporterGML

/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org

This file is part of Gephi.

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

Gephi is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

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

import java.awt.Color;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.Reader;
import java.io.StreamTokenizer;
import java.util.ArrayList;
import org.gephi.data.attributes.api.AttributeTable;
import org.gephi.data.attributes.api.AttributeColumn;
import org.gephi.data.attributes.api.AttributeType;
import org.gephi.io.importer.api.ContainerLoader;
import org.gephi.io.importer.api.EdgeDefault;
import org.gephi.io.importer.api.EdgeDraft;
import org.gephi.io.importer.api.ImportUtils;
import org.gephi.io.importer.api.Issue;
import org.gephi.io.importer.api.NodeDraft;
import org.gephi.io.importer.api.Report;
import org.gephi.io.importer.spi.FileImporter;
import org.gephi.utils.longtask.spi.LongTask;
import org.gephi.utils.progress.Progress;
import org.gephi.utils.progress.ProgressTicket;
import org.openide.util.NbBundle;

//Inspired from infovis.graph.io;
//Original author Jean-Daniel Fekete
public class ImporterGML implements FileImporter, LongTask {

    //Architecture
    private Reader reader;
    private ContainerLoader container;
    private Report report;
    private ProgressTicket progressTicket;
    private boolean cancel = false;

    public boolean execute(ContainerLoader container) {
        this.container = container;
        this.report = new Report();
        LineNumberReader lineReader = ImportUtils.getTextReader(reader);
        try {
            importData(lineReader);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return !cancel;
    }

    private void importData(LineNumberReader reader) throws Exception {
        Progress.start(progressTicket);

        ArrayList list;
        StreamTokenizer tokenizer = new StreamTokenizer(reader);
        tokenizer.ordinaryChar('[');
        tokenizer.ordinaryChar(']');
        tokenizer.wordChars('_', '_');
        list = parseList(tokenizer);

        boolean ret = false;
        for (int i = 0; i < list.size(); i++) {
            if ("graph".equals(list.get(i)) && list.size() >= i + 2 && list.get(i + 1) instanceof ArrayList) {
                ret = parseGraph((ArrayList) list.get(i + 1));
            }
        }
        if (!ret) {
            report.logIssue(new Issue(NbBundle.getMessage(ImporterGML.class, "importerGML_error_badparsing"), Issue.Level.SEVERE));
        }

        Progress.finish(progressTicket);
    }

    private ArrayList parseList(StreamTokenizer tokenizer) throws IOException {
        ArrayList list = new ArrayList();
        loop:
        while (true) {
            int t = tokenizer.nextToken();
            if (t == ']' || t == StreamTokenizer.TT_EOF) {
                return list;
            } else if (t != StreamTokenizer.TT_WORD) {
                break;
            }
            String key = tokenizer.sval;
            list.add(key);
            t = tokenizer.nextToken();
            switch (t) {
                case '[':
                    list.add(parseList(tokenizer));
                    break;
                case StreamTokenizer.TT_NUMBER:
                    list.add(new Double(tokenizer.nval));
                    break;
                case StreamTokenizer.TT_WORD:
                case '"':
                    list.add(tokenizer.sval);
                    break;
                default:
                    break loop;
            }
        }
        report.logIssue(new Issue(NbBundle.getMessage(ImporterGML.class, "importerGML_error_listtoken", tokenizer.lineno()), Issue.Level.SEVERE));
        return list;
    }

    private boolean parseGraph(ArrayList list) {
        if ((list.size() & 1) != 0) {
            return false;
        }
        Progress.switchToDeterminate(progressTicket, list.size());

        boolean ret = true;
        for (int i = 0; i < list.size(); i += 2) {
            Object key = list.get(i);
            Object value = list.get(i + 1);
            if ("node".equals(key)) {
                ret = parseNode((ArrayList) value);
            } else if ("edge".equals(key)) {
                ret = parseEdge((ArrayList) value);
            } else if ("directed".equals(key)) {
                if (value instanceof Double) {
                    EdgeDefault edgeDefault = ((Double) value) == 1 ? EdgeDefault.DIRECTED : EdgeDefault.UNDIRECTED;
                    container.setEdgeDefault(edgeDefault);
                } else {
                    report.logIssue(new Issue(NbBundle.getMessage(ImporterGML.class, "importerGML_error_directedgraphparse"), Issue.Level.WARNING));
                }
            } else {
            }
            if (!ret) {
                break;
            }
            if (cancel) {
                break;
            }
            Progress.progress(progressTicket);
        }
        return ret;
    }

    private boolean parseNode(ArrayList list) {
        NodeDraft node = container.factory().newNodeDraft();
        String id = null;
        for (int i = 0; i < list.size(); i += 2) {
            String key = (String) list.get(i);
            Object value = list.get(i + 1);
            if ("id".equals(key)) {
                id = value.toString();
                node.setId(id);
            } else if ("label".equals(key)) {
                String label = value.toString();
                node.setLabel(label);
            }
        }
        if (id == null) {
            report.logIssue(new Issue(NbBundle.getMessage(ImporterGML.class, "importerGML_error_nodeidmissing"), Issue.Level.WARNING));
        }
        boolean ret = addNodeAttributes(node, "", list);
        container.addNode(node);
        return ret;
    }

    private boolean addNodeAttributes(NodeDraft node, String prefix, ArrayList list) {
        boolean ret = true;
        for (int i = 0; i < list.size(); i += 2) {
            String key = (String) list.get(i);
            Object value = list.get(i + 1);
            if ("id".equals(key) || "label".equals(key)) {
                continue; // already parsed
            }
            if (value instanceof ArrayList) {
                // keep the  hierarchy
                ret = addNodeAttributes(node, prefix + "." + key, (ArrayList) value);
                if (!ret) {
                    break;
                }
            } else if ("x".equals(key) && value instanceof Double) {
                node.setX(((Double) value).floatValue());
            } else if ("y".equals(key) && value instanceof Double) {
                node.setY(((Double) value).floatValue());
            } else if ("z".equals(key) && value instanceof Double) {
                node.setZ(((Double) value).floatValue());
            } else if ("w".equals(key) && value instanceof Double) {
                node.setSize(((Double) value).floatValue());
            } else if ("h".equals(key)) {
            } else if ("fill".equals(key)) {
                int colorHex = -1;
                if (value instanceof String) {
                    String str = ((String) value).trim().replace("#", "");
                    try {
                        colorHex = Integer.valueOf(str, 16).intValue();
                    } catch (Exception e) {
                    }
                }
                if (colorHex != -1) {
                    node.setColor(new Color(colorHex));
                }
            } else {
                AttributeTable nodeClass = container.getAttributeModel().getNodeTable();
                AttributeColumn column = null;
                if ((column = nodeClass.getColumn(key)) == null) {
                    column = nodeClass.addColumn(key, AttributeType.STRING);
                    report.log("Node attribute " + column.getTitle() + " (" + column.getType() + ")");
                }
                node.addAttributeValue(column, value.toString());
            }
        }
        return ret;
    }

    private boolean parseEdge(ArrayList list) {
        EdgeDraft edgeDraft = container.factory().newEdgeDraft();
        for (int i = 0; i < list.size(); i += 2) {
            String key = (String) list.get(i);
            Object value = list.get(i + 1);
            if ("source".equals(key)) {
                NodeDraft source = container.getNode(value.toString());
                edgeDraft.setSource(source);
            } else if ("target".equals(key)) {
                NodeDraft target = container.getNode(value.toString());
                edgeDraft.setTarget(target);
            } else if ("value".equals(key) || "weight".equals(key)) {
                if (value instanceof Double) {
                    edgeDraft.setWeight(((Double) value).floatValue());
                }
            } else if ("label".equals(key)) {
                edgeDraft.setLabel(value.toString());
            }
        }
        boolean ret = addEdgeAttributes(edgeDraft, "", list);
        container.addEdge(edgeDraft);
        return ret;
    }

    private boolean addEdgeAttributes(EdgeDraft edge, String prefix, ArrayList list) {
        boolean ret = true;
        for (int i = 0; i < list.size(); i += 2) {
            String key = (String) list.get(i);
            Object value = list.get(i + 1);
            if ("source".equals(key) || "target".equals(key) || "value".equals(key) || "weight".equals(key) || "label".equals(key)) {
                continue; // already parsed
            }
            if (value instanceof ArrayList) {
                // keep the hierarchy
                ret = addEdgeAttributes(edge, prefix + "." + key, (ArrayList) value);
                if (!ret) {
                    break;
                }
            } else if ("directed".equals(key)) {
                if (value instanceof Double) {
                    EdgeDraft.EdgeType type = ((Double) value) == 1 ? EdgeDraft.EdgeType.DIRECTED : EdgeDraft.EdgeType.UNDIRECTED;
                    edge.setType(type);
                } else {
                    report.logIssue(new Issue(NbBundle.getMessage(ImporterGML.class, "importerGML_error_directedparse", edge.toString()), Issue.Level.WARNING));
                }
            } else {
                AttributeTable edgeClass = container.getAttributeModel().getEdgeTable();
                AttributeColumn column = null;
                if ((column = edgeClass.getColumn(key)) == null) {
                    column = edgeClass.addColumn(key, AttributeType.STRING);
                    report.log("Edge attribute " + column.getTitle() + " (" + column.getType() + ")");
                }
                edge.addAttributeValue(column, value.toString());
            }
        }
        return ret;
    }

    public void setReader(Reader reader) {
        this.reader = reader;
    }

    public ContainerLoader getContainer() {
        return container;
    }

    public Report getReport() {
        return report;
    }

    public boolean cancel() {
        cancel = true;
        return true;
    }

    public void setProgressTicket(ProgressTicket progressTicket) {
        this.progressTicket = progressTicket;
    }
}
TOP

Related Classes of org.gephi.io.importer.plugin.file.ImporterGML

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.