Skip to content

Commit

Permalink
merge radu's change r149295 from trunk to 1.x branch
Browse files Browse the repository at this point in the history
  • Loading branch information
Kevin Krouse committed Feb 1, 2005
1 parent 2f12230 commit a86522c
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 4 deletions.
10 changes: 10 additions & 0 deletions src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeImpl.java
Expand Up @@ -65,6 +65,7 @@ public final class SchemaTypeImpl implements SchemaType, TypeStoreUserFactory
private volatile SchemaField _containerField;
private volatile int _containerFieldCode;
private volatile int _containerFieldIndex;
private volatile QName[] _groupReferenceContext;
private SchemaType.Ref[] _anonymousTyperefs;
private boolean _isDocumentType;
private boolean _isAttributeType;
Expand Down Expand Up @@ -476,6 +477,15 @@ public void setContainerFieldIndex(short code, int index)
_containerFieldIndex = index;
}

/* package */ void setGroupReferenceContext(QName[] groupNames)
{
assertUnresolved();
_groupReferenceContext = groupNames;
}

/* package */ QName[] getGroupReferenceContext()
{ return _groupReferenceContext; }

public SchemaType getOuterType()
{ return _outerSchemaTypeRef == null ? null : _outerSchemaTypeRef.get(); }

Expand Down
7 changes: 6 additions & 1 deletion src/typeimpl/org/apache/xmlbeans/impl/schema/StscState.java
Expand Up @@ -75,7 +75,7 @@ public class StscState
private Map _attributeTypes = new LinkedHashMap();
private Map _typesByClassname = new LinkedHashMap();
private Map _misspelledNames = new HashMap();
private Set _processingGroups = new HashSet();
private Set _processingGroups = new LinkedHashSet();
private Map _idConstraints = new LinkedHashMap();
private Set _namespaces = new HashSet();
private boolean _noUpa;
Expand Down Expand Up @@ -754,6 +754,11 @@ void finishProcessing(Object obj)
_processingGroups.remove(obj);
}

Object[] getCurrentProcessing()
{
return _processingGroups.toArray();
}

/* JAVAIZATION ====================================================*/

Map typesByClassname()
Expand Down
68 changes: 68 additions & 0 deletions src/typeimpl/org/apache/xmlbeans/impl/schema/StscTranslator.java
Expand Up @@ -617,14 +617,26 @@ else if (ds instanceof List)

if (typedef != null)
{
Object[] grps = state.getCurrentProcessing();
QName[] context = new QName[grps.length];
for (int i = 0; i < context.length; i++)
if (grps[i] instanceof SchemaModelGroupImpl)
context[i] = ((SchemaModelGroupImpl ) grps[i]).getName();
SchemaType repeat = checkRecursiveGroupReference(context, qname, (SchemaTypeImpl)outerType);
if (repeat != null)
sType = repeat;
else
{
SchemaTypeImpl sTypeImpl = new SchemaTypeImpl(state.sts());
sType = sTypeImpl;
sTypeImpl.setContainerField(impl);
sTypeImpl.setOuterSchemaTypeRef(outerType == null ? null : outerType.getRef());
sTypeImpl.setGroupReferenceContext(context);
// leave the anonymous type unresolved: it will be resolved later.
anonymousTypes.add(sType);
sTypeImpl.setSimpleType(simpleTypedef);
sTypeImpl.setParseContext(typedef, targetNamespace, chameleon, false);
}
}

if (sType == null)
Expand Down Expand Up @@ -744,6 +756,62 @@ else if (block instanceof List)
return impl;
}

/**
* We need to do this because of the following kind of Schemas:
* <xs:group name="e">
* <xs:sequence>
* <xs:element name="error">
* <xs:complexType>
* <xs:group ref="e"/>
* </xs:complexType>
* </xs:element>
* </xs:sequence>
* </xs:group>
* (see JIRA bug XMLBEANS-35)
* Even though this should not be allowed because it produces an infinite
* number of anonymous types and local elements nested within each other,
* the de facto consensus among Schema processors is that this should be
* valid, therefore we have to detect this situation and "patch up" the
* Schema object model so that instead of creating a new anonymous type,
* we refer to the one that was already created earlier.
* In order to accomplish that, we store inside every anonymous type the
* list of groups that were dereferenced at the moment the type was created
* and if the same pattern is about to repeat, it means that we are in a
* case similar to the above.
*/
private static SchemaType checkRecursiveGroupReference(QName[] context, QName containingElement, SchemaTypeImpl outerType)
{
if (context.length < 1)
return null;
SchemaTypeImpl type = outerType;

while (type != null)
{
if (type.getName() != null || type.isDocumentType())
return null; // not anonymous
if (containingElement.equals(type.getContainerField().getName()))
{
QName[] outerContext = type.getGroupReferenceContext();
if (outerContext != null && outerContext.length == context.length)
{
// Smells like trouble
boolean equal = true;
for (int i = 0; i < context.length; i++)
if (!(context[i] == null && outerContext[i] == null ||
context[i] != null && context[i].equals(outerContext[i])))
{
equal = false;
break;
}
if (equal)
return type;
}
}
type = (SchemaTypeImpl) type.getOuterType();
}
return null;
}

private static String removeWhitespace(String xpath)
{
StringBuffer sb = new StringBuffer();
Expand Down
Expand Up @@ -292,9 +292,10 @@ private static void tryToDelete(File dir)
{
if (dir.isDirectory())
{
String[] list = dir.list();
for (int i = 0; i < list.length; i++)
tryToDelete(new File(dir, list[i]));
String[] list = dir.list(); // can return null if I/O error
if (list != null)
for (int i = 0; i < list.length; i++)
tryToDelete(new File(dir, list[i]));
}
if (!dir.delete())
return; // don't try very hard, because we're just deleting tmp
Expand Down
56 changes: 56 additions & 0 deletions test/src/drt/drtcases/ValidationTests.java
Expand Up @@ -1599,4 +1599,60 @@ public void testValidate11() throws Exception {
doTest(schemas, null, valid, invalid);
}

public void testValidateNestedGroups ( )
throws Exception
{
// This is a weird Schema, inspired from JIRA bug XMLBEANS-35
// Make sure we compile it and then validate correctly
String schemas[] = {
"<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" targetNamespace=\"http://tempuri.org/f_up_groups\" xmlns:tns=\"http://tempuri.org/f_up_groups\">\n" +
"\n" +
"<xs:group name=\"d\">\n" +
" <xs:sequence>\n" +
" <xs:element name=\"error\">\n" +
" <xs:complexType>\n" +
" <xs:group ref=\"tns:e\"/>\n" +
" </xs:complexType>\n" +
" </xs:element>\n" +
" </xs:sequence>\n" +
"</xs:group>\n" +
"\n" +
"<xs:group name=\"e\">\n" +
" <xs:sequence>\n" +
" <xs:element name=\"error\" minOccurs=\"0\">\n" +
" <xs:complexType>\n" +
" <xs:group ref=\"tns:d\"/>\n" +
" </xs:complexType>\n" +
" </xs:element>\n" +
" </xs:sequence>\n" +
"</xs:group>\n" +
"\n" +
"<xs:element name=\"root\">\n" +
" <xs:complexType>\n" +
" <xs:group ref=\"tns:d\"/>\n" +
" </xs:complexType>\n" +
"</xs:element>\n" +
"\n" +
"</xs:schema>\n"};

String valid[] = {
"<ns:root xmlns:ns=\"http://tempuri.org/f_up_groups\">\n" +
" <error>\n" +
" <error>\n" +
" <error/>" +
" </error>\n" +
" </error>\n" +
"</ns:root>\n"};

String invalid[] = {
"<ns:root xmlns:ns=\"http://tempuri.org/f_up_groups\">\n" +
" <error>\n" +
" <error>\n" +
" </error>\n" +
" </error>\n" +
"</ns:root>\n"};

doTest(schemas, null, valid, invalid);
}

}

0 comments on commit a86522c

Please sign in to comment.