/** * Prunes dead branches from the specified configuration tree. * @param explorer used to backtrack through the configuration tree. */ private void prune(BufferedConfigurationExplorer explorer) { ConfigurationSection current; ConfigurationSection parent; // If we're at the root level, nothing to prune. if(!explorer.hasSections()) return; current = explorer.popSection(); // Look for branches to prune until we've either found a non-empty one // or reached the root of the three. while(current.isEmpty() && current != root) { // Gets the current section's parent and prune. parent = explorer.hasSections() ? explorer.popSection() : root; parent.removeSection(current); current = parent; } }
/** * Move to the specified section. * @param name name of the current section's subsection in which to move. * @param create if <code>true</code> and <code>name</code> doesn't exist, it will be created. * @return <code>true</code> if we could move to <code>name</code>, <code>false</code> otherwise. */ @Override public boolean moveTo(String name, boolean create) { if(super.moveTo(name, create)) { sections.push(getSection()); return true; } return false; } }
/** * Tests path bufferisation when the requested sections are not found but created. */ @Test public void testSectionNotFoundAndCreateBuffer() { BufferedConfigurationExplorer explorer; for(int i = 0; i < DEPTH; i++) { moveTo(explorer = (BufferedConfigurationExplorer)getExplorer(), i); // Creates the section, makes sure it was created and takes it off // the section stack. assert explorer.moveTo(FAKE_SECTION + i, true); assert explorer.hasSections(); assert explorer.popSection() != null; // Makes sure backtracking through history works. backtrack(explorer, i); } } }
/** * Deletes the specified variable from the configuration. * <p> * If the variable was set, a configuration {@link ConfigurationEvent event} will be passed to * all registered LISTENERS. * </p> * @param name name of the variable to remove. * @return the variable's old value, or <code>null</code> if it wasn't set. */ public synchronized String removeVariable(String name) { BufferedConfigurationExplorer explorer; // Used to navigate to the variable's parent section. String buffer; // Buffer for the variable's name trimmed of section information. // If the variable's 'path' doesn't exist, return null. if((buffer = moveToParent(explorer = new BufferedConfigurationExplorer(root), name, false)) == null) return null; // If the variable was actually set, triggers an event. if((buffer = explorer.getSection().removeVariable(buffer)) != null) { prune(explorer); triggerEvent(new ConfigurationEvent(this, name, null)); } return buffer; }
/** * Returns an instance of {@link BufferedConfigurationExplorer}. * @return an instance of {@link BufferedConfigurationExplorer}. */ @Override protected ConfigurationExplorer getExplorer() { return new BufferedConfigurationExplorer(conf.getRoot()); }
/** * Tests path bufferisation when the requested sections are not found. */ @Test public void testSectionNotFoundBuffer() { BufferedConfigurationExplorer explorer; for(int i = 0; i < DEPTH; i++) { moveTo(explorer = (BufferedConfigurationExplorer)getExplorer(), i); // Makes sure that a failed moveTo call doesn't corrupt section history. assert !explorer.moveTo(FAKE_SECTION + i, false); backtrack(explorer, i); } }
/** * Backtracks through the section history and makes sure it contains the correct values. */ private void backtrack(BufferedConfigurationExplorer explorer, int depth) { for(int i = depth; i > 0; i--) { assert explorer.hasSections(); assert (VARIABLE_VALUE + i).equals(explorer.popSection().getVariable(VARIABLE_NAME + i)); } assert !explorer.hasSections(); }