/* * Copyright (C) 2013 lichtflut Forschungs- und Entwicklungsgesellschaft mbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.arastreju.sge.model; import org.arastreju.sge.SNOPS; import org.arastreju.sge.model.nodes.ResourceNode; import org.arastreju.sge.model.nodes.SemanticNode; import org.arastreju.sge.model.nodes.ValueNode; import org.arastreju.sge.naming.Namespace; import org.arastreju.sge.naming.SimpleNamespace; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import java.util.TreeSet; /** * <p> * Default implementation of a semantic graph. * </p> * * <p> * Created Jan 14, 2011 * </p> * * @author Oliver Tigges */ public class DefaultSemanticGraph implements SemanticGraph { private final Set<Statement> statements = new TreeSet<Statement>(new StmtComparator()); // ----------------------------------------------------- /** * Creates an empty graph. */ public DefaultSemanticGraph() { } /** * Constructor based on associations. */ public DefaultSemanticGraph(final Collection<Statement> stmts){ this.statements.addAll(stmts); } /** * Constructor based on a root node. */ public DefaultSemanticGraph(final ResourceNode root) { addCascading(root, new HashSet<ResourceNode>()); } // ----------------------------------------------------- /** * {@inheritDoc} */ public Set<Statement> getStatements() { return Collections.unmodifiableSet(statements); } /** * {@inheritDoc} */ @Override public Iterator<Statement> iterator() { return getStatements().iterator(); } /** * {@inheritDoc} */ public Set<SemanticNode> getNodes() { final Set<SemanticNode> nodes = new HashSet<SemanticNode>(); for(Statement assoc : statements){ nodes.add(assoc.getSubject()); nodes.add(assoc.getObject()); } return nodes; } /** * {@inheritDoc} */ public Set<ResourceNode> getSubjects() { final Set<ResourceNode> subjects = new HashSet<ResourceNode>(); for(Statement assoc : statements){ subjects.add(assoc.getSubject().asResource()); } return subjects; } /** * {@inheritDoc} */ public Collection<Namespace> getNamespaces() { final Set<Namespace> namespaces = new HashSet<Namespace>(); for (Statement assoc : statements) { addNamespace(assoc.getSubject(), namespaces); addNamespace(assoc.getPredicate(), namespaces); addNamespace(assoc.getObject(), namespaces); } return namespaces; } // ----------------------------------------------------- /** * {@inheritDoc} */ public void addStatements(final Collection<? extends Statement> stmts) { this.statements.addAll(stmts); } /** * {@inheritDoc} */ @Override public void addStatement(Statement stmt) { this.statements.add(stmt); } /** * {@inheritDoc} */ public void merge(final SemanticGraph graph) { addStatements(graph.getStatements()); } // ----------------------------------------------------- /** * {@inheritDoc} */ @Override public String toString() { final StringBuilder sb = new StringBuilder(); for (Statement assoc : statements) { sb.append(" -- " + assoc.toString() + "\n"); } return sb.toString(); } // ----------------------------------------------------- private void addNamespace(final SemanticNode node, final Set<Namespace> targetSet){ if (node.isResourceNode() && !node.asResource().isBlankNode()){ targetSet.add( new SimpleNamespace(node.asResource().getQualifiedName().getNamespace())); } } private void addCascading(final ResourceNode node, final Set<ResourceNode> visited) { visited.add(node); this.statements.addAll(node.getAssociations()); for (SemanticNode object : SNOPS.objects(node.getAssociations())) { if (object.isResourceNode() && !visited.contains(object)) { addCascading(object.asResource(), visited); } } } private static class StmtComparator implements Comparator<Statement> { /** * {@inheritDoc} */ public int compare(Statement stmt1, Statement stmt2) { int c = compare(stmt1.getSubject(), stmt2.getSubject()); if (c == 0) { c = compare(stmt1.getPredicate(), stmt2.getPredicate()); } if (c == 0) { c = compare(stmt1.getObject(), stmt2.getObject()); } return c; } private int compare(SemanticNode sn1, SemanticNode sn2) { if (sn1.isResourceNode()) { if (sn2.isResourceNode()) { return compare(sn1.asResource(), sn2.asResource()); } else { return -1; } } else { if (sn2.isResourceNode()) { return 1; } else { return compare(sn1.asValue(), sn2.asValue()); } } } private int compare(ResourceNode rn1, ResourceNode rn2) { return rn1.getQualifiedName().compareTo(rn2.getQualifiedName()); } private int compare(ValueNode v1, ValueNode v2) { return v1.getStringValue().compareTo(v2.getStringValue()); } } }