case SchemaBase.ALL_TYPE:
case SchemaBase.CHOICE_TYPE:
case SchemaBase.SEQUENCE_TYPE:
{
// child component is a compositor, so see if it can be deleted or replaced
CommonCompositorDefinition compositor = (CommonCompositorDefinition)childcomp;
int size = compositor.getParticleList().size();
if (size == 0) {
// empty compositor, just remove (always safe to do this)
childext.setRemoved(true);
modified = true;
if (s_logger.isDebugEnabled()) {
s_logger.debug(lead + "eliminated empty compositor " + path);
}
} else if (size == 1) {
// single component in compositor, first try to convert compositor to singleton
OpenAttrBase grandchild = (OpenAttrBase)compositor.getParticleList().get(0);
IArity particle = (IArity)grandchild;
if (SchemaUtils.isRepeated(compositor)) {
if (!SchemaUtils.isRepeated(particle)) {
// repeated compositor with non-repeated particle, so pass repeat to particle
if (s_logger.isDebugEnabled()) {
s_logger.debug(lead + "passing repeat from compositor " +
SchemaUtils.componentPath(childcomp) + " to only child " +
SchemaUtils.describeComponent(grandchild));
}
particle.setMaxOccurs(compositor.getMaxOccurs());
((ComponentExtension)grandchild.getExtension()).setRepeated(true);
compositor.setMaxOccurs(null);
((ComponentExtension)compositor.getExtension()).setRepeated(false);
} else if ((compositor.getMaxOccurs().isUnbounded() &&
particle.getMaxOccurs().isUnbounded())) {
// unbounded compositor with unbounded particle, just wipe repeat from compositor
if (s_logger.isDebugEnabled()) {
s_logger.debug(lead + "clearing unbounded from compositor " +
SchemaUtils.componentPath(childcomp) + " with unbounded only child " +
SchemaUtils.describeComponent(grandchild));
}
compositor.setMaxOccurs(null);
((ComponentExtension)compositor.getExtension()).setRepeated(false);
}
}
if (SchemaUtils.isOptional(compositor)) {
if (SchemaUtils.isOptional(particle)) {
// optional compositor with optional particle, just wipe optional from compositor
if (s_logger.isDebugEnabled()) {
s_logger.debug(lead + "clearing optional from compositor " +
SchemaUtils.componentPath(childcomp) + " with optional only child " +
SchemaUtils.describeComponent(grandchild));
}
compositor.setMinOccurs(null);
((ComponentExtension)compositor.getExtension()).setOptional(false);
} else if (Count.isCountEqual(1, particle.getMinOccurs())) {
// optional compositor with required particle, so pass optional to particle
if (s_logger.isDebugEnabled()) {
s_logger.debug(lead + "passing optional from compositor " +
SchemaUtils.componentPath(childcomp) + " to required only child " +
SchemaUtils.describeComponent(grandchild));
}
particle.setMinOccurs(Count.COUNT_ZERO);
((ComponentExtension)grandchild.getExtension()).setOptional(true);
compositor.setMinOccurs(null);
((ComponentExtension)compositor.getExtension()).setOptional(false);
}
}
// check if top component is also a compositor
if (topcomp instanceof CommonCompositorDefinition) {
// nested compositor, check if can be simplified
if (SchemaUtils.isSingleton(compositor)) {
// nested singleton compositor with only child, just replace with the child
topcomp.replaceChild(i, grandchild);
modified = true;
if (s_logger.isDebugEnabled()) {
s_logger.debug(lead + "replacing singleton compositor " +
SchemaUtils.componentPath(childcomp) + " with only child " +
SchemaUtils.describeComponent(grandchild));
}
} else if (compositor instanceof ChoiceElement) {
// replace choice with sequence to simplify handling, since just one particle
if (s_logger.isDebugEnabled()) {
s_logger.debug(lead + "substituting sequence for choice " +
SchemaUtils.componentPath(childcomp) + " with only one child");
}
SequenceElement sequence = new SequenceElement();
sequence.setAnnotation(compositor.getAnnotation());
sequence.setExtension(compositor.getExtension());
sequence.setMaxOccurs(compositor.getMaxOccurs());
sequence.setMinOccurs(compositor.getMinOccurs());
sequence.getParticleList().add(grandchild);
topcomp.replaceChild(i, sequence);
modified = true;
}