/** * Loads group's children from given source DOM {@link Element}. * * <ul> * <li>Unsupported (unknown) children are skipped. * <li>Wrong order of children is ignored (children are loaded in correct order). * </ul> * * @param element source DOM {@link Element} * @param context current {@link LoadingContext} callback */ public void load(final Element element, final LoadingContext context) { for (final NodeGroup<?, ?> group : groups) { group.getChildren().clear(); } final NodeList childNodes = element.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { final Node childNode = childNodes.item(i); boolean childLoaded = false; for (final NodeGroup<?, ?> group : groups) { if (group.loadChildIfSupported(childNode, context)) { childLoaded = true; break; } } if (!childLoaded) { /* No NodeGroup supports this child */ if (childNode.getNodeType() == Node.TEXT_NODE && childNode.getNodeValue().trim().isEmpty()) { /* Whitespace node, so we'll ignore this */ } else { /* Register error */ final String childName = childNode.getNodeType() == Node.ELEMENT_NODE ? childNode.getLocalName() : "(text)"; context.modelBuildingError(new QtiIllegalChildException(parent, childName), childNode); } } } }
/** * Gets group supporting the given QTI class name. * * @param qtiClassName name of requested group * @return group with given name * @throws QtiNodeGroupException if group is not found */ public NodeGroup<?, ?> getGroupSupporting(final String qtiClassName) { for (final NodeGroup<?, ?> child : groups) { if (child.supportsQtiClass(qtiClassName)) { return child; } } throw new QtiNodeGroupException("Cannot find node group supporting " + qtiClassName); }
/** * Gets group with given name. * * @param name name of requested group * @return group with given name * @throws QtiNodeGroupException if group is not found */ public NodeGroup<?, ?> get(final String name) { for (final NodeGroup<?, ?> child : groups) { if (child.getName().equals(name) || child.supportsQtiClass(name)) { return child; } } throw new QtiNodeGroupException("Cannot find node group with name " + name); }
/** * SAFELY adds given group into this container, checking duplicities in group names. * * <p>This used to be the default in JQTI, but wastes processor cycles for the implementation of * the core QTI spec. I've kept it in in case it might be useful for someone adding a * (non-standard) extension to the spec. * * @param group given group * @throws QtiNodeGroupException if container already contains group with same name */ public void addSafe(final int index, final NodeGroup<?, ?> group) { for (final NodeGroup<?, ?> child : groups) { if (child.getName().equals(group.getName())) { throw new QtiNodeGroupException("Duplicate node group name: " + group.computeXPath()); } } groups.add(index, group); }
public NodeGroup getNodeGroupByName(String name) { int rank = 0; while (rank < this.nodeGroups.size()) { NodeGroup grp = this.nodeGroups.get(rank); if (grp.getId().equals(name)) { return grp; } else { rank++; } } return null; }
public NodeGroup unmarshall(StaxUnmarshallerContext context) throws Exception { NodeGroup nodeGroup = new NodeGroup(); int originalDepth = context.getCurrentDepth(); int targetDepth = originalDepth + 1; if (context.isStartOfDocument()) targetDepth += 1; while (true) { XMLEvent xmlEvent = context.nextEvent(); if (xmlEvent.isEndDocument()) return nodeGroup; if (xmlEvent.isAttribute() || xmlEvent.isStartElement()) { if (context.testExpression("NodeGroupId", targetDepth)) { nodeGroup.setNodeGroupId(StringStaxUnmarshaller.getInstance().unmarshall(context)); continue; } if (context.testExpression("Status", targetDepth)) { nodeGroup.setStatus(StringStaxUnmarshaller.getInstance().unmarshall(context)); continue; } if (context.testExpression("PrimaryEndpoint", targetDepth)) { nodeGroup.setPrimaryEndpoint(EndpointStaxUnmarshaller.getInstance().unmarshall(context)); continue; } if (context.testExpression("NodeGroupMembers/NodeGroupMember", targetDepth)) { nodeGroup.withNodeGroupMembers( NodeGroupMemberStaxUnmarshaller.getInstance().unmarshall(context)); continue; } } else if (xmlEvent.isEndElement()) { if (context.getCurrentDepth() < originalDepth) { return nodeGroup; } } } }