@Override public void write(final Writer out) throws ConfigurationException, IOException { this.mapper.writer().writeValue(out, constructMap( this.getNodeModel().getNodeHandler().getRootNode())); }
/** * Loads this configuration from the content of the specified map. The data * in the map is transformed into a hierarchy of {@link ImmutableNode} * objects. * * @param map the map to be processed */ protected void load(final Map<String, Object> map) { final List<ImmutableNode> roots = constructHierarchy("", map); getNodeModel().setRootNode(roots.get(0)); }
/** * Creates a new instance of {@code XMLPropertyConfiguration} with the given * root node. * * @param root the root node */ XMLPropertyListConfiguration(final ImmutableNode root) { super(new InMemoryNodeModel(root)); }
/** * Handles an add property operation if the property to be added is a node. * * @param tx the transaction * @param addData the {@code NodeAddData} * @param values the collection with node values */ private static void addNodeProperty(final ModelTransaction tx, final NodeAddData<ImmutableNode> addData, final Iterable<?> values) { final Collection<ImmutableNode> newNodes = createNodesToAdd(addData.getNewNodeName(), values); addNodesByAddData(tx, addData, newNodes); }
/** * {@inheritDoc} This implementation returns a newly created node model * with the correct root node set. Note that this model is not used for * property access, but only made available to clients that need to * operate on the node structure of this {@code SubnodeConfiguration}. * Be aware that the implementation of this method is not very efficient. */ @Override public InMemoryNodeModel getNodeModel() { final ImmutableNode root = getParent().getNodeModel().getTrackedNode(getRootSelector()); return new InMemoryNodeModel(root); }
new ImmutableNode.Builder().name(key) .value(config.getProperty(key)).create(); final InMemoryNodeModel tempModel = new InMemoryNodeModel(node); printNode(out, indentLevel + 1, node, tempModel.getNodeHandler()); out.println(";");
/** * {@inheritDoc} A new empty root node is created with the same name as the * current root node. Implementation note: Because this is a hard reset the * usual dance for dealing with concurrent updates is not required here. * * @param resolver the {@code NodeKeyResolver} */ @Override public void clear(final NodeKeyResolver<ImmutableNode> resolver) { final ImmutableNode newRoot = new ImmutableNode.Builder().name(getRootNode().getNodeName()) .create(); setRootNode(newRoot); }
/** * Initializes a transaction for an add operation. * * @param tx the transaction to be initialized * @param key the key * @param values the collection with node values * @param resolver the {@code NodeKeyResolver} */ private void initializeAddTransaction(final ModelTransaction tx, final String key, final Iterable<?> values, final NodeKeyResolver<ImmutableNode> resolver) { final NodeAddData<ImmutableNode> addData = resolver.resolveAddKey(tx.getQueryRoot(), key, tx.getCurrentData()); if (addData.isAttribute()) { addAttributeProperty(tx, addData, values); } else { addNodeProperty(tx, addData, values); } }
@Override public void addProperty(final String key, final Iterable<?> values, final NodeKeyResolver<ImmutableNode> resolver) { addProperty(key, null, values, resolver); }
@Override public void addNodes(final String key, final Collection<? extends ImmutableNode> nodes, final NodeKeyResolver<ImmutableNode> resolver) { addNodes(key, null, nodes, resolver); }
/** * Propagates the changes on the target node to the next level above of * the hierarchy. If the updated node is no longer defined, it can even * be removed from its parent. Otherwise, it is just replaced. * * @param target the target node for this operation * @param node the resulting node after applying all operations * @param level the level of the target node */ private void propagateChange(final ImmutableNode target, final ImmutableNode node, final int level) { final ImmutableNode parent = getParent(target); final ChildrenUpdateOperation co = new ChildrenUpdateOperation(); if (InMemoryNodeModel.checkIfNodeDefined(node)) { co.addNodeToReplace(target, node); } else { co.addNodeToRemove(target); } fetchOperations(parent, level - 1).addChildrenOperation(co); }
@Override public void addProperty(final String key, final Iterable<?> values, final NodeKeyResolver<ImmutableNode> resolver) { getParentModel().addProperty(key, getSelector(), values, resolver); }
@Override public void addNodes(final String key, final Collection<? extends ImmutableNode> nodes, final NodeKeyResolver<ImmutableNode> resolver) { getParentModel().addNodes(key, getSelector(), nodes, resolver); }
public void dump(final Writer out, final DumperOptions options) throws ConfigurationException, IOException { final Yaml yaml = new Yaml(options); yaml.dump(constructMap(getNodeModel().getNodeHandler().getRootNode()), out); }
/** * Replaces a tracked node if it is already detached. * * @param currentData the current data of the model * @param selector the {@code NodeSelector} defining the tracked node * @param newNode the node replacing the tracked node * @return a flag whether the operation was successful */ private boolean replaceDetachedTrackedNode(final TreeData currentData, final NodeSelector selector, final ImmutableNode newNode) { final InMemoryNodeModel detachedNodeModel = currentData.getNodeTracker().getDetachedNodeModel(selector); if (detachedNodeModel != null) { detachedNodeModel.setRootNode(newNode); return true; } return false; }
/** * Creates a new instance of {@code PropertyListConfiguration} with the * given root node. * * @param root the root node */ PropertyListConfiguration(final ImmutableNode root) { super(new InMemoryNodeModel(root)); }
@Override public void write(final Writer out) throws ConfigurationException { if (locator == null) { throw new ConfigurationException("Save operation not properly " + "initialized! Do not call write(Writer) directly," + " but use a FileHandler to save a configuration."); } final PrintWriter writer = new PrintWriter(out); if (locator.getEncoding() != null) { writer.println("<?xml version=\"1.0\" encoding=\"" + locator.getEncoding() + "\"?>"); } else { writer.println("<?xml version=\"1.0\"?>"); } writer.println("<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">"); writer.println("<plist version=\"1.0\">"); printNode(writer, 1, getNodeModel().getNodeHandler().getRootNode()); writer.println("</plist>"); writer.flush(); }
/** * Returns a configuration with the same content as this configuration, but * with all variables replaced by their actual values. This implementation * is specific for hierarchical configurations. It clones the current * configuration and runs a specialized visitor on the clone, which performs * interpolation on the single configuration nodes. * * @return a configuration with all variables interpolated * @since 1.5 */ @Override public Configuration interpolatedConfiguration() { final InterpolatedVisitor visitor = new InterpolatedVisitor(); final NodeHandler<ImmutableNode> handler = getModel().getNodeHandler(); NodeTreeWalker.INSTANCE .walkDFS(handler.getRootNode(), visitor, handler); final BaseHierarchicalConfiguration c = (BaseHierarchicalConfiguration) clone(); c.getNodeModel().setRootNode(visitor.getInterpolatedRoot()); return c; }
/** * Returns an instance with the detached flag set to true. This method * is called if the selector of a tracked node does not match a single * node any more. It is possible to pass in a new node instance which * becomes the current tracked node. If this is <b>null</b>, the * previous node instance is used. * * @param newNode the new tracked node instance (may be <b>null</b>) * @return the updated instance */ public TrackedNodeData detach(final ImmutableNode newNode) { final ImmutableNode newTrackedNode = (newNode != null) ? newNode : getNode(); return new TrackedNodeData(newTrackedNode, observerCount, new InMemoryNodeModel(newTrackedNode)); } }
/** * Returns a {@code NodeHandler} for a tracked node. Such a handler may be * required for operations on a sub tree of the model. The handler to be * returned depends on the current state of the tracked node. If it is still * active, a handler is used which shares some data (especially the parent * mapping) with this model. Detached track nodes in contrast have their own * separate model; in this case a handler associated with this model is * returned. * * @param selector the {@code NodeSelector} defining the tracked node * @return a {@code NodeHandler} for this tracked node * @throws ConfigurationRuntimeException if the selector is unknown */ public NodeHandler<ImmutableNode> getTrackedNodeHandler( final NodeSelector selector) { final TreeData currentData = structure.get(); final InMemoryNodeModel detachedNodeModel = currentData.getNodeTracker().getDetachedNodeModel(selector); return (detachedNodeModel != null) ? detachedNodeModel.getNodeHandler() : new TrackedNodeHandler(currentData.getNodeTracker() .getTrackedNode(selector), currentData); }