/* * Copyright (C) 2011 Andrea Schweer * * This file is part of the Digital Parrot. * * The Digital Parrot is free software; you can redistribute it and/or modify * it under the terms of the Eclipse Public License as published by the Eclipse * Foundation or its Agreement Steward, either version 1.0 of the License, or * (at your option) any later version. * * The Digital Parrot 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 Eclipse Public License for * more details. * * You should have received a copy of the Eclipse Public License along with the * Digital Parrot. If not, see http://www.eclipse.org/legal/epl-v10.html. * */ package net.schweerelos.parrot.model; import java.util.ArrayList; import java.util.Collection; import java.util.EnumSet; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableModel; import net.schweerelos.parrot.model.filters.ChainLink; import net.schweerelos.parrot.util.QuadTree; import net.schweerelos.timeline.model.IntervalChain; import org.mindswap.pellet.jena.ModelExtractor; import org.mindswap.pellet.jena.ModelExtractor.StatementType; import com.hp.hpl.jena.ontology.Individual; import com.hp.hpl.jena.ontology.OntClass; import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntResource; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.Property; import com.hp.hpl.jena.rdf.model.RDFNode; import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.Statement; import com.hp.hpl.jena.rdf.model.StmtIterator; public class TableParrotModel extends AbstractTableModel implements TableModel, ParrotModel { private static final long serialVersionUID = 1L; private static final String[] COLUMN_NAMES = { "this", "is related to", "that" }; private ParrotModelHelper delegateModel; private List<NodeWrapper[]> data; private OntModel ontModel; public TableParrotModel(OntModel model) { ontModel = model; data = new ArrayList<NodeWrapper[]>(); } public TableModel asTableModel() { return this; } /* ParrotModel methods */ @Override public OntModel getOntModel() { return delegateModel.getOntModel(); } @Override public void loadData(String datafile) { if (delegateModel == null) { delegateModel = new ParrotModelHelper(ontModel, this); delegateModel.loadData(datafile); } populateTableModel(delegateModel.getOntModel()); } private void populateTableModel(OntModel model) { ModelExtractor extractor = new ModelExtractor(model); EnumSet<StatementType> selectors = StatementType.PROPERTY_VALUE; extractor.setSelector(selectors); Model eModel = extractor.extractModel(); StmtIterator statements = eModel.listStatements(); while (statements.hasNext()) { Statement stat = statements.nextStatement(); Resource subject = stat.getSubject(); if (subject.isURIResource()) { subject = model.getResource(subject.getURI()); } if (!(subject.canAs(Individual.class)) || !ParrotModelHelper.isPotentialNode(delegateModel, subject.as(Individual.class))) { continue; } Property predicate = stat.getPredicate(); if (predicate.isURIResource()) { predicate = model.getProperty(predicate.getURI()); } if (!ParrotModelHelper.isPotentialEdge(delegateModel, predicate)) { continue; } NodeWrapper[] row = new NodeWrapper[3]; NodeWrapper subjectWrapper = delegateModel.addSubject(subject.as(Individual.class)); row[0] = subjectWrapper; OntResource predicateResource = model.getOntResource(predicate); NodeWrapper predicateWrapper = delegateModel.addPredicate(predicateResource); row[1] = predicateWrapper; RDFNode object = stat.getObject(); if (object.isURIResource()) { object = model.getResource(object.as(Resource.class).getURI()); } NodeWrapper objectWrapper = delegateModel.addObject(object); row[2] = objectWrapper; if (objectWrapper != null) { data.add(row); } } } @Override public void saveData() { delegateModel.saveData(); } @Override public Set<NodeWrapper> getSubjectTypes() { return delegateModel.getSubjectTypes(); } @Override public Set<NodeWrapper> getAllPredicates() { return delegateModel.getAllPredicates(); } @Override public Set<NodeWrapper> getAllSubjects() { return delegateModel.getAllSubjects(); } @Override public Set<NodeWrapper> getPredicatesForSubject(NodeWrapper subjectType) { return delegateModel.getPredicatesForSubject(subjectType); } @Override public Set<NodeWrapper> getTypesForIndividual(NodeWrapper node) { return delegateModel.getTypesForIndividual(node); } @Override public Set<NodeWrapper> getIndividualsForType(NodeWrapper type) { return delegateModel.getIndividualsForType(type); } @Override public Set<NodeWrapper> getSuperPredicates(NodeWrapper node) { return delegateModel.getSuperPredicates(node); } @Override public void addFilter(Filter filter) { delegateModel.addFilter(filter); } @Override public void removeFilter(Filter filter) { delegateModel.removeFilter(filter); } @Override public void replaceFilter(Filter oldFilter, Filter newFilter) { delegateModel.replaceFilter(oldFilter, newFilter); } @Override public NodeWrapper getNodeWrapper(Individual instance) { return delegateModel.getNodeWrapper(instance); } @Override public Set<NodeWrapper> getNodeWrappers(OntClass ontClass) { return delegateModel.getNodeWrappers(ontClass); } @Override public Set<NodeWrapper> searchNodeWrappers(String query) throws SearchFailedException { return delegateModel.searchNodeWrappers(query); } @Override public IntervalChain<NodeWrapper> getTimedThings() { return delegateModel.getTimedThings(); } @Override public QuadTree<CenteredThing<NodeWrapper>> getLocatedThings() { return delegateModel.getLocatedThings(); } @Override public void deleteEdge(NodeWrapper edge) { delegateModel.deleteEdge(edge); } @Override public void deleteNode(NodeWrapper vertex) { delegateModel.deleteNode(vertex); } @Override public boolean isBusy() { return delegateModel.isBusy(); } @Override public Set<NodeWrapper> getNodeWrappersOnChain(List<ChainLink> chain) { return delegateModel.getNodeWrappersOnChain(chain); } @Override public List<List<NodeWrapper>> getChains(List<ChainLink> links) { // we need to make sure that the statements are being shown correctly return delegateModel.getChains(links); } @Override public boolean hasSuccessor(NodeWrapper node, NodeWrapper maybeSuccessor) { for (NodeWrapper[] row : data) { if (row[0] == node && row[2] == maybeSuccessor) { return true; } } return false; } @Override public Set<NodeWrapper> getSuccessorNodes(NodeWrapper node) { Set<NodeWrapper> result = new HashSet<NodeWrapper>(); for (NodeWrapper[] row : data) { // check if there is a node -> edge -> destination row if (row[0] == node) { result.add(row[2]); // add destination of edge } } return result; } @Override public Collection<NodeWrapper> getEdges(NodeWrapper from, NodeWrapper to) { Set<NodeWrapper> result = new HashSet<NodeWrapper>(); for (NodeWrapper[] row : data) { // if subject and object match if (row[0] == from && row[2] == to) { // add predicate result.add(row[1]); } } return result; } @Override public Set<NodeWrapper> getAllNodes() { return delegateModel.getAllNodes(); } @Override public void addParrotModelListener(ParrotModelListener pml) { delegateModel.addParrotModelListener(pml); } @Override public void removeParrotModelListener(ParrotModelListener pml) { delegateModel.removeParrotModelListener(pml); } @Override public Set<NodeWrapper> getAllNodeWrappers() { return delegateModel.getAllNodeWrappers(); } @Override public NodeWrapper getNodeWrapperForString(String url) throws NoSuchNodeWrapperException { return delegateModel.getNodeWrapperForString(url); } @Override public String getDataIdentifier() { return delegateModel.getDataIdentifier(); } @Override public GraphParrotModel asGraphModel() { throw new UnsupportedOperationException("can't make a graph model out of this"); } @Override public TableParrotModel asListModel() { return this; } public void setDelegate(ParrotModelHelper delegateModel) { this.delegateModel = delegateModel; } /* TableModel methods */ @Override public Class<?> getColumnClass(int columnIndex) { return NodeWrapper.class; } @Override public String getColumnName(int column) { return COLUMN_NAMES[column]; } @Override public int getColumnCount() { return COLUMN_NAMES.length; } @Override public int getRowCount() { return data.size(); } @Override public Object getValueAt(int rowIndex, int columnIndex) { return data.get(rowIndex)[columnIndex]; } public void addTriplet(NodeWrapper subjectWrapper, NodeWrapper predicateWrapper, NodeWrapper objectWrapper) { if (subjectWrapper == null || predicateWrapper == null || objectWrapper == null) { return; } NodeWrapper[] row = new NodeWrapper[3]; row[0] = subjectWrapper; row[1] = predicateWrapper; row[2] = objectWrapper; data.add(row); } }