/** * {@inheritDoc} This implementation calls {@code close()} if the * {@code untrackOnFinalize} flag was set when this instance was * constructed. While this is not 100 percent reliable, it is better than * keeping the tracked node hanging around. Note that it is not a problem if * {@code close()} already had been invoked manually because this method is * idempotent. * * @see #close() */ @Override protected void finalize() throws Throwable { if (isReleaseTrackedNodeOnFinalize()) { close(); } super.finalize(); } }
@Override public void addProperty(final String key, final Iterable<?> values, final NodeKeyResolver<ImmutableNode> resolver) { getParentModel().addProperty(key, getSelector(), values, resolver); }
/** * Creates a connected sub configuration based on a selector for a tracked * node. * * @param selector the {@code NodeSelector} * @param parentModelSupport the {@code InMemoryNodeModelSupport} object for * the parent node model * @return the newly created sub configuration * @since 2.0 */ protected SubnodeConfiguration createSubConfigurationForTrackedNode( final NodeSelector selector, final InMemoryNodeModelSupport parentModelSupport) { final SubnodeConfiguration subConfig = new SubnodeConfiguration(this, new TrackedNodeModel( parentModelSupport, selector, true)); initSubConfigurationForThisParent(subConfig); return subConfig; }
/** * {@inheritDoc} This implementation returns the tracked node instance * acting as root node of this model. */ @Override public ImmutableNode getInMemoryRepresentation() { return getNodeHandler().getRootNode(); }
/** * {@inheritDoc} This implementation returns the parent model of the * {@link TrackedNodeModel} used by this configuration. */ @Override protected InMemoryNodeModel getSubConfigurationParentModel() { return getTrackedModel().getParentModel(); }
/** * Closes this sub configuration. This method closes the underlying * {@link TrackedNodeModel}, thus causing the tracked node acting as root * node to be released. Per default, this happens automatically when the * model is claimed by the garbage collector. By calling this method * explicitly, it can be indicated that this configuration is no longer used * and that resources used by it can be freed immediately. */ public void close() { (getTrackedModel()).close(); }
/** * Returns the parent model. Operations on this model are delegated to this * parent model specifying the selector to the tracked node. * * @return the parent model */ public InMemoryNodeModel getParentModel() { return getParentModelSupport().getNodeModel(); }
/** * Creates a new instance of {@code SubnodeConfiguration} and initializes it * with all relevant properties. * * @param parent the parent configuration * @param model the {@code TrackedNodeModel} to be used for this configuration * @throws IllegalArgumentException if a required argument is missing */ public SubnodeConfiguration(final BaseHierarchicalConfiguration parent, final TrackedNodeModel model) { super(model); if (parent == null) { throw new IllegalArgumentException( "Parent configuration must not be null!"); } if (model == null) { throw new IllegalArgumentException("Node model must not be null!"); } this.parent = parent; rootSelector = model.getSelector(); }
/** * {@inheritDoc} This implementation returns a copy of the current node * model with the same settings. However, it has to be ensured that the * track count for the node selector is increased. * * @return the node model for the clone */ @Override protected NodeModel<ImmutableNode> cloneNodeModel() { final InMemoryNodeModel parentModel = (InMemoryNodeModel) getParent().getModel(); parentModel.trackNode(getRootSelector(), getParent()); return new TrackedNodeModel(getParent(), getRootSelector(), true); }
@Override public void addNodes(final String key, final Collection<? extends ImmutableNode> nodes, final NodeKeyResolver<ImmutableNode> resolver) { getParentModel().addNodes(key, getSelector(), nodes, resolver); }
@Override public void setProperty(final String key, final Object value, final NodeKeyResolver<ImmutableNode> resolver) { getParentModel().setProperty(key, getSelector(), value, resolver); }
@Override public List<QueryResult<ImmutableNode>> clearTree(final String key, final NodeKeyResolver<ImmutableNode> resolver) { return getParentModel().clearTree(key, getSelector(), resolver); }
@Override public void clearProperty(final String key, final NodeKeyResolver<ImmutableNode> resolver) { getParentModel().clearProperty(key, getSelector(), resolver); }
/** * {@inheritDoc} This implementation clears the sub tree spanned by the * associate tracked node. This has the side effect that this in any case * becomes detached. * * @param resolver */ @Override public void clear(final NodeKeyResolver<ImmutableNode> resolver) { getParentModel().clearTree(null, getSelector(), resolver); }
@Override public void setRootNode(final ImmutableNode newRoot) { getParentModel().replaceTrackedNode(getSelector(), newRoot); }
@Override public NodeHandler<ImmutableNode> getNodeHandler() { return getParentModel().getTrackedNodeHandler(getSelector()); }
/** * Closes this model. This causes the tracked node this model is based upon * to be released (i.e. {@link InMemoryNodeModel#untrackNode(NodeSelector)} * is called). This method should be called when this model is no longer * needed. This implementation is idempotent; it is safe to call * {@code close()} multiple times - only the first invocation has an effect. * After this method has been called this model can no longer be used * because there is no guarantee that the node can still be accessed from * the parent model. */ public void close() { if (closed.compareAndSet(false, true)) { getParentModel().untrackNode(getSelector()); } }