protected void removeDeepBinding()

in xbean-naming/src/main/java/org/apache/xbean/naming/context/AbstractContext.java [377:441]


    protected void removeDeepBinding(Name name, boolean pruneEmptyContexts, boolean removeNotEmptyContext) throws NamingException {
        if (name == null) throw new NullPointerException("name is null");
        if (name.isEmpty()) {
            throw new InvalidNameException("Name is empty");
        }

        if (name.size() == 1) {
            removeBinding(name.get(0), removeNotEmptyContext);
            return;
        }

        if (!pruneEmptyContexts) {
            Context context = lookupFinalContext(name);
            context.unbind(name.getSuffix(name.size() - 1));
        } else {
            // we serch the tree for a target context and name to remove
            // this is normally the last context in the tree and the final name part, but
            // it may be farther up the path if the intervening nodes are empty
            Context targetContext = this;
            String targetName = name.get(0);

            Context currentContext = this;
            for (int i = 0; i < name.size(); i++) {
                String part = name.get(i);

                // empty path parts are not allowed
                if (part.length() == 0) {
                    throw new InvalidNameException("Name part " + i + " is empty: " + name);
                }

                // update targets
                if (getSize(currentContext) > 1) {
                    targetContext = currentContext;
                    targetName = part;
                }


                // Is this the last element in the name?
                if (i == name.size() - 1) {
                    // we're at the end... unbind value
                    unbind(targetContext, targetName, true);

                    // all done... this is redundant but makes the code more readable
                    break;
                } else {
                    Object currentValue = getBinding(currentContext, part);
                    if (currentValue == null) {
                        // path not found we are done, but first prune the empty contexts
                        if (targetContext != currentContext) {
                            unbind(targetContext, targetName, false);
                        }
                        break;
                    } else {
                        // the current value must be a context
                        if (!(currentValue instanceof Context)) {
                            throw new NotContextException("Expected an instance of context to be bound at " +
                                    part + " but found an instance of " + currentValue.getClass().getName());
                        }
                        currentContext = (Context) currentValue;
                        // now we recurse into the current context
                    }
                }
            }
        }
    }