/* * NodeRuntimeConfiguration.java * * Created on Oct 21, 2011, 12:34:48 PM * * Description: Provides node runtime configuration. * * Copyright (C) Oct 21, 2011, Stephen L. Reed, Texai.org. * */ package org.texai.ahcsSupport.domainEntity; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Objects; import java.util.Set; import javax.persistence.Id; import net.jcip.annotations.ThreadSafe; import org.apache.log4j.Logger; import org.openrdf.model.URI; import org.texai.ahcsSupport.AHCSConstants; import org.texai.kb.persistence.CascadePersistence; import org.texai.kb.persistence.RDFEntity; import org.texai.kb.persistence.RDFEntityManager; import org.texai.kb.persistence.RDFPersistent; import org.texai.kb.persistence.RDFProperty; /** Provides node runtime configuration. * * @author reed */ @ThreadSafe @RDFEntity(context = "texai:AlbusHierarchicalControlSystemContext") public class NodeRuntimeConfiguration implements CascadePersistence { /** the logger */ private static final Logger LOGGER = Logger.getLogger(NodeRuntimeConfiguration.class); /** the serial version UID */ private static final long serialVersionUID = 1L; /** the id assigned by the persistence framework */ @Id private URI id; /** the node runtime id, which matches NodeRuntimeInfo.id */ @RDFProperty private final URI nodeRuntimeId; /** the node runtime key store entry alias */ @RDFProperty private String nodeRuntimeKeyStoreEntryAlias; /** the certificate signing key store entry alias */ @RDFProperty private String certificateSigningKeyStoreEntryAlias; /** the nodes */ @RDFProperty private final Set<Node> nodes = new HashSet<>(); // non-persistent fields ... /** the local node dictionary, nickname --> local node */ private Map<String, Node> localNodeDictionary; /** the local role dictionary, role id --> role */ private Map<URI, Role> localRoleDictionary; /** the local role dictionary lock */ private final Object localRoleDictionary_lock = new Object(); /** the top friendship role */ private Role topFriendshipRole; /** Constructs a new NodeRuntimeConfiguration instance. */ public NodeRuntimeConfiguration() { nodeRuntimeId = null; } /** Constructs a new NodeRuntimeConfiguration instance. * * @param nodeRuntimeId the node runtime id */ public NodeRuntimeConfiguration(final URI nodeRuntimeId) { //Preconditions assert nodeRuntimeId != null : "nodeRuntimeId must not be null"; this.nodeRuntimeId = nodeRuntimeId; } /** Gets the id assigned by the persistence framework. * * @return the id assigned by the persistence framework */ @Override public URI getId() { return id; } /** Gets the node runtime id. * * @return the nodeRuntimeId */ public URI getNodeRuntimeId() { return nodeRuntimeId; } /** Gets the node runtime key store entry alias. * * @return the node runtime key store entry alias */ public String getNodeRuntimeKeyStoreEntryAlias() { return nodeRuntimeKeyStoreEntryAlias; } /** Sets the node runtime key store entry alias. * * @param nodeRuntimeKeyStoreEntryAlias the node runtime key store entry alias */ public void setNodeRuntimeKeyStoreEntryAlias(final String nodeRuntimeKeyStoreEntryAlias) { //Preconditions assert nodeRuntimeKeyStoreEntryAlias != null : "nodeRuntimeKeyStoreEntryAlias must not be null"; assert !nodeRuntimeKeyStoreEntryAlias.isEmpty() : "nodeRuntimeKeyStoreEntryAlias must not be empty"; this.nodeRuntimeKeyStoreEntryAlias = nodeRuntimeKeyStoreEntryAlias; } /** Gets the certificate signing key store entry alias. * * @return the certificate signing key store entry alias */ public String getCertificateSigningKeyStoreEntryAlias() { return certificateSigningKeyStoreEntryAlias; } /** Sets the certificate signing key store entry alias. * * @param certificateSigningKeyStoreEntryAlias the certificate signing key store entry alias */ public void setCertificateSigningKeyStoreEntryAlias(final String certificateSigningKeyStoreEntryAlias) { //Preconditions assert certificateSigningKeyStoreEntryAlias != null : "nodeRuntimeKeyStoreEntryAlias must not be null"; assert !certificateSigningKeyStoreEntryAlias.isEmpty() : "nodeRuntimeKeyStoreEntryAlias must not be empty"; this.certificateSigningKeyStoreEntryAlias = certificateSigningKeyStoreEntryAlias; } /** Returns a string representation of this object. * * @return a string representation of this object */ @Override public String toString() { return (new StringBuilder()).append("[NodeRuntimeConfiguration ").append(nodeRuntimeId).append(']').toString(); } /** Returns whether some other object equals this one. * * @param obj the other object * @return whether some other object equals this one */ @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final NodeRuntimeConfiguration other = (NodeRuntimeConfiguration) obj; if (!Objects.equals(this.id, other.id)) { return false; } return Objects.equals(this.nodeRuntimeId, other.nodeRuntimeId); } /** Returns a hash code for this object. * * @return a hash code for this object */ @Override public int hashCode() { int hash = 3; hash = 37 * hash + Objects.hashCode(this.id); hash = 37 * hash + Objects.hashCode(this.nodeRuntimeId); return hash; } /** Gets an unmodifiable copy of the local nodes. * * @return the local nodes */ public Set<Node> getNodes() { synchronized (nodes) { return Collections.unmodifiableSet(nodes); } } /** Gets the local node dictionary, nickname --> local node. * * @return the local node dictionary */ private Map<String, Node> getLocalNodeDictionary() { if (localNodeDictionary == null) { // lazy initialization localNodeDictionary = new HashMap<>(); for (final Node node : nodes) { localNodeDictionary.put(node.getNodeNickname(), node); } } return localNodeDictionary; } /** Returns the node having the given nickname. * * @param nodeNickname the given nickname * @return the node having the given nickname, or null if not found */ public Node getNode(final String nodeNickname) { //Preconditions assert nodeNickname != null : "nodeNickname must not be null"; assert !nodeNickname.isEmpty() : "nodeNickname must not be empty"; synchronized (getLocalNodeDictionary()) { // force lazy initialization return localNodeDictionary.get(nodeNickname); } } /** Adds the given local node. * * @param node the local node to add */ public void addNode(final Node node) { //Preconditions assert node != null : "node must not be null"; assert node.getNodeNickname() != null : "node nickname must not be null " + node; assert !node.getNodeNickname().isEmpty() : "node nickname must not be empty"; synchronized (getLocalNodeDictionary()) { // force lazy initialization localNodeDictionary.put(node.getNodeNickname(), node); nodes.add(node); } LOGGER.info("addNode, nodeRuntimeId: " + nodeRuntimeId + ", nodes size: " + nodes.size()); } /** Removes the given local node. * * @param node the given local node to remove */ public void removeNode(final Node node) { //Preconditions assert node != null : "node must not be null"; assert node.getNodeNickname() != null : "node nickname must not be null"; assert !node.getNodeNickname().isEmpty() : "node nickname must not be empty"; synchronized (getLocalNodeDictionary()) { // force lazy initialization localNodeDictionary.remove(node.getNodeNickname()); nodes.remove(node); } } /** Gets the local role dictionary, role id --> role. * * @return the local role dictionary */ private Map<URI, Role> getLocalRoleDictionary() { synchronized (localRoleDictionary_lock) { if (localRoleDictionary == null) { // lazy initialization localRoleDictionary = new HashMap<>(); for (final Node node : nodes) { for (final Role role : node.getRoles()) { localRoleDictionary.put(role.getId(), role); } } } return localRoleDictionary; } } /** Returns whether the given role id belongs to a local role. * * @param roleId the given role id * @return whether the given role id belongs to a local role */ public boolean isLocalRole(final URI roleId) { //Preconditions assert roleId != null : "roleId must not be null"; synchronized (getLocalRoleDictionary()) { // force lazy initialization return localRoleDictionary.containsKey(roleId); } } /** Adds the given role to the local role dictionary. * * @param role the given role */ public void addRole(final Role role) { //Preconditions assert role != null : "role must not be null"; assert role.getId() != null : "role must have been persisted, and thus have an id"; synchronized (getLocalRoleDictionary()) { // force lazy initialization localRoleDictionary.put(role.getId(), role); } } /** Removes the given role from the local role dictionary. * * @param role the given role */ public void removeRole(final Role role) { //Preconditions assert role != null : "role must not be null"; assert role.getId() != null : "role must have been persisted, and thus have an id"; synchronized (getLocalRoleDictionary()) { // force lazy initialization assert localRoleDictionary.containsKey(role.getId()) : "role must be registered"; localRoleDictionary.remove(role.getId()); } } /** Gets the local role having the given id. * * @param roleId the role id * @return the local role having the given id, or null if not found */ public Role getLocalRole(final URI roleId) { //Preconditions assert roleId != null : "roleId must not be null"; synchronized (getLocalRoleDictionary()) { // force lazy initialization return localRoleDictionary.get(roleId); } } /** Gets the top friendship role. * * @return the top friendship role */ public Role getTopFriendshipRole() { if (topFriendshipRole == null) { synchronized (getLocalNodeDictionary()) { // force lazy initialization final Node topFriendshipNode = localNodeDictionary.get(AHCSConstants.NODE_NICKNAME_TOPPER); assert topFriendshipNode != null; topFriendshipRole = topFriendshipNode.getRoleForTypeName(AHCSConstants.TOP_FRIENDSHIP_ROLE_TYPE); } } //Postconditions assert topFriendshipRole != null : "topFriendshipRole must not be null"; return topFriendshipRole; } /** Ensures that this persistent object is fully instantiated. */ @Override public void instantiate() { for (final Node node : nodes) { node.instantiate(); } } /** Recursively persists this RDF entity and all its components. * * @param rdfEntityManager the RDF entity manager * @param overrideContext the user's belief context, or null to persist to each object's default context */ public void cascadePersist( final RDFEntityManager rdfEntityManager, final URI overrideContext) { //Preconditions assert rdfEntityManager != null : "rdfEntityManager must not be null"; cascadePersist(this, rdfEntityManager, overrideContext); } /** Recursively persists this RDF entity and all its components. * * @param rootRDFEntity the root RDF entity * @param rdfEntityManager the RDF entity manager * @param overrideContext the user's belief context, or null to persist to each object's default context */ @Override public void cascadePersist(RDFPersistent rootRDFEntity, RDFEntityManager rdfEntityManager, URI overrideContext) { //Preconditions assert rdfEntityManager != null : "rdfEntityManager must not be null"; for (final Node node : nodes) { node.cascadePersist( rootRDFEntity, rdfEntityManager, overrideContext); } rdfEntityManager.persist(this, overrideContext); } /** Recursively removes this RDF entity and all its unshared components. * * @param rootRDFEntity the root RDF entity * @param rdfEntityManager the RDF entity manager */ @Override public void cascadeRemove(RDFPersistent rootRDFEntity, RDFEntityManager rdfEntityManager) { //Preconditions assert rdfEntityManager != null : "rdfEntityManager must not be null"; for (final Node node : nodes) { node.cascadeRemove( rootRDFEntity, rdfEntityManager); } rdfEntityManager.remove(this); } }