private static Fulfillment isPositionFulfilled()

in xmlschema-walker/src/main/java/org/apache/ws/commons/schema/docpath/XmlSchemaPathFinder.java [931:1097]


    private static <U, V> Fulfillment isPositionFulfilled(XmlSchemaPathNode<U, V> currentPath,
                                                          List<Integer> possiblePaths) {
        boolean completelyFulfilled = true;
        boolean partiallyFulfilled = true;

        final XmlSchemaStateMachineNode state = currentPath.getStateMachineNode();

        if (currentPath.getDocumentNode() == null) {
            // This is the root node. It is not fulfilled.
            partiallyFulfilled = false;
        } else if (currentPath.getDocIteration() >= state.getMinOccurs()) {
            partiallyFulfilled = true;
        } else {
            partiallyFulfilled = false;
        }

        if (currentPath.getDocumentNode() == null) {
            completelyFulfilled = false;
        } else if (currentPath.getDocIteration() == state.getMaxOccurs()) {
            completelyFulfilled = true;
        } else if (currentPath.getDocIteration() > state.getMaxOccurs()) {
            throw new IllegalStateException("Current path's document iteration of "
                                            + currentPath.getDocIteration()
                                            + " is greater than the maximum number of occurrences ("
                                            + state.getMaxOccurs() + ").");

        } else {
            completelyFulfilled = false;
        }

        final List<XmlSchemaStateMachineNode> nextStates = state.getPossibleNextStates();

        Map<Integer, XmlSchemaDocumentNode<U>> children = null;
        if (currentPath.getDocumentNode() != null) {
            children = currentPath.getDocumentNode().getChildren();
        }

        switch (state.getNodeType()) {
        case ELEMENT:
        case ANY:
            // We only needed to perform the occurrence check.
            break;
        case CHOICE:
        case SUBSTITUTION_GROUP: {
            /*
             * If any child meets the minimum number, we are partially
             * fulfilled. If all elements meet the maximum, we are completely
             * fulfilled.
             */
            boolean groupPartiallyFulfilled = false;
            boolean groupCompletelyFulfilled = false;
            for (int stateIndex = 0; stateIndex < nextStates.size(); ++stateIndex) {

                XmlSchemaStateMachineNode nextState = nextStates.get(stateIndex);

                if ((children != null) && children.containsKey(stateIndex)) {
                    final XmlSchemaDocumentNode<U> child = children.get(stateIndex);
                    final int iteration = child.getIteration();
                    if (iteration >= nextState.getMinOccurs()) {
                        groupPartiallyFulfilled = true;
                        if (possiblePaths != null) {
                            possiblePaths.clear();
                            if (iteration < nextState.getMaxOccurs()) {
                                possiblePaths.add(stateIndex);
                            } else {
                                groupCompletelyFulfilled = true;
                            }
                        }
                        break;
                    } else if (possiblePaths != null) {
                        possiblePaths.add(stateIndex);
                    }
                } else {
                    if (nextState.getMinOccurs() == 0) {
                        groupPartiallyFulfilled = true;
                    }
                    if (nextState.getMaxOccurs() == 0) {
                        groupCompletelyFulfilled = true;
                    } else if (possiblePaths != null) {
                        possiblePaths.add(stateIndex);
                    }
                }
            }
            partiallyFulfilled &= groupPartiallyFulfilled;
            completelyFulfilled &= groupCompletelyFulfilled;
            break;
        }
        case ALL: {
            // If all children meet the minimum number, we succeeded.
            for (int stateIndex = 0; stateIndex < nextStates.size(); ++stateIndex) {

                final XmlSchemaStateMachineNode nextState = nextStates.get(stateIndex);

                if ((children != null) && children.containsKey(stateIndex)) {
                    final XmlSchemaDocumentNode<U> child = children.get(stateIndex);
                    final int iteration = child.getIteration();
                    if (iteration < nextState.getMinOccurs()) {
                        partiallyFulfilled = false;
                    }
                    if (iteration < nextState.getMaxOccurs()) {
                        completelyFulfilled = false;
                        if (possiblePaths != null) {
                            possiblePaths.add(stateIndex);
                        }
                    }
                } else {
                    if (nextState.getMinOccurs() > 0) {
                        partiallyFulfilled = false;
                    }
                    if (nextState.getMaxOccurs() > 0) {
                        completelyFulfilled = false;
                        if (possiblePaths != null) {
                            possiblePaths.add(stateIndex);
                        }
                    }
                }
            }

            break;
        }
        case SEQUENCE: {
            // If the sequence is complete, we succeeded.
            int stateIndex = currentPath.getDocSequencePosition();
            if (stateIndex < 0) {
                stateIndex = 0;
            }
            for (; stateIndex < nextStates.size(); ++stateIndex) {
                final XmlSchemaStateMachineNode nextState = nextStates.get(stateIndex);

                if ((children != null) && children.containsKey(stateIndex)) {
                    final XmlSchemaDocumentNode<U> child = children.get(stateIndex);
                    if (child.getIteration() < nextState.getMinOccurs()) {
                        partiallyFulfilled = false;
                    }
                    if (child.getIteration() < nextState.getMaxOccurs()) {
                        completelyFulfilled = false;
                        if (possiblePaths != null) {
                            possiblePaths.add(stateIndex);
                        }
                    }
                } else {
                    if (nextState.getMinOccurs() > 0) {
                        partiallyFulfilled = false;
                    }
                    if (nextState.getMaxOccurs() > 0) {
                        completelyFulfilled = false;
                        if (possiblePaths != null) {
                            possiblePaths.add(stateIndex);
                        }
                    }
                }
            }
            break;
        }
        default:
            throw new IllegalStateException("Current position has a node of unrecognized type \""
                                            + currentPath.getStateMachineNode().getNodeType() + '\"');
        }

        Fulfillment fulfillment = Fulfillment.NOT;
        if (completelyFulfilled) {
            fulfillment = Fulfillment.COMPLETE;
        } else if (partiallyFulfilled) {
            fulfillment = Fulfillment.PARTIAL;
        }
        return fulfillment;
    }