Java tutorial
/** * Copyright (C) 2012 Red Hat, Inc. (jdcasey@commonjava.org) * * 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.commonjava.cartographer.graph.spi.neo4j.model; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import org.apache.commons.codec.digest.DigestUtils; import org.commonjava.cartographer.graph.model.GraphPath; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Path; import org.neo4j.graphdb.Relationship; public class Neo4jGraphPath implements GraphPath<Long> { private final long[] relationships; private final long startNode; private final long endNode; public Neo4jGraphPath(final Neo4jGraphPath parent, final Relationship... relationships) { if (parent == null) { throw new NullPointerException("Parent path cannot be null"); } this.startNode = parent.startNode; if (relationships.length > 0) { this.endNode = relationships[relationships.length - 1].getEndNode().getId(); } else { this.endNode = parent.endNode; } final int parentLen = parent.relationships.length; this.relationships = new long[parentLen + relationships.length]; if (parentLen > 0) { System.arraycopy(parent.relationships, 0, this.relationships, 0, parent.relationships.length); } if (this.relationships.length > 0) { for (int i = parentLen; i < this.relationships.length; i++) { this.relationships[i] = relationships[i - parentLen].getId(); } } } public Neo4jGraphPath(final Path path) { this.startNode = path.startNode().getId(); this.endNode = path.endNode().getId(); final List<Long> ids = new ArrayList<Long>(); for (final Relationship r : path.relationships()) { ids.add(r.getId()); } this.relationships = new long[ids.size()]; for (int i = 0; i < ids.size(); i++) { this.relationships[i] = ids.get(i); } } public Neo4jGraphPath(final Node start, final Node end, final long[] rids) { this.startNode = start.getId(); this.endNode = end.getId(); this.relationships = rids; } public Neo4jGraphPath(final Relationship[] relationships) { if (relationships.length > 0) { this.startNode = relationships[0].getStartNode().getId(); this.endNode = relationships[relationships.length - 1].getEndNode().getId(); } else { throw new IllegalArgumentException( "Cannot initialize path with zero relationships and no explicit start node!"); } this.relationships = new long[relationships.length]; final int i = 0; for (final Relationship relationship : relationships) { this.relationships[i] = relationship.getId(); } } private Neo4jGraphPath(final Neo4jGraphPath parent, final long endNode, final long[] newRelationships) { this.startNode = parent.startNode; this.endNode = endNode; final int parentLen = parent.relationships.length; this.relationships = new long[parentLen + newRelationships.length]; System.arraycopy(parent.relationships, 0, this.relationships, 0, parentLen); System.arraycopy(newRelationships, 0, this.relationships, parentLen, newRelationships.length); } public Neo4jGraphPath append(final Neo4jGraphPath childPath) { if (length() > 0 && getLastRelationshipId() != childPath.getFirstRelationshipId()) { throw new IllegalArgumentException("Cannot splice " + childPath + " onto " + this + ". They don't overlap on last/first relationshipId!"); } if (childPath.length() < 2) { return this; } final long[] ids = new long[childPath.length() - 1]; System.arraycopy(childPath.getRelationshipIds(), 1, ids, 0, ids.length); return new Neo4jGraphPath(this, childPath.endNode, ids); } public long getStartNodeId() { return startNode; } public long getEndNodeId() { return endNode; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + Long.valueOf(startNode).hashCode(); result = prime * result + Long.valueOf(endNode).hashCode(); result = prime * result + Arrays.hashCode(relationships); return result; } @Override public boolean equals(final Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final Neo4jGraphPath other = (Neo4jGraphPath) obj; if (startNode != other.startNode) { return false; } if (endNode != other.endNode) { return false; } return Arrays.equals(relationships, other.relationships); } @Override public Iterator<Long> iterator() { return new Iterator<Long>() { private int next = 0; @Override public boolean hasNext() { return relationships.length > next; } @Override public Long next() { return relationships[next++]; } @Override public void remove() { throw new UnsupportedOperationException( "Immutable array of relationship ID's. Remove not supported."); } }; } @Override public String toString() { return String.format("%s [relationships=%s, from=%s, to=%s]", getClass().getSimpleName(), Arrays.toString(relationships), startNode, endNode); } @Override public String getKey() { final StringBuilder sb = new StringBuilder(); for (final long id : relationships) { if (sb.length() > 0) { sb.append(','); } sb.append(id); } return DigestUtils.shaHex(sb.toString()); } public long getLastRelationshipId() { if (relationships.length < 1) { return -1; } return relationships[relationships.length - 1]; } public long getFirstRelationshipId() { if (relationships.length < 1) { return -1; } return relationships[0]; } public long[] getRelationshipIds() { return relationships; } public int length() { return relationships.length; } public boolean contains(final long id) { for (final long rid : relationships) { if (rid == id) { return true; } } return false; } }