phdmohans / odata4j

Automatically exported from code.google.com/p/odata4j
0 stars 0 forks source link

The complex collection type Bag() is not recognized by the reader #193

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Define an EdmCollectionType with CollectionKind.Bag.

edmType = EdmCollectionType.newBuilder()                                        
       .setKind(CollectionKind.Bag)                                             
  .setCollectionType(EdmSimpleType.newBuilder(EdmSimpleType.INT32))
                                               .build();
2. Use the created type in producing OData.  No Issue.
   XMLFormatWriter.java(69) writes the bag just fine.

3. Use the XML in a POST to update the entity and it does not
recognize the complex type. Bag(Edm.Int32) on return from EdmDataServices.java  
It only looks through metadata defined complex types where Bag and List are 
internal types.

What is the expected output? What do you see instead?
Processed correctly as a Bag or List of Integers

What version of the product are you using? On what operating system?
0.6.0

Please provide any additional information below.

For Example the "Version" property when processed by the AtomFeedFormatParser 
it throws 
throw new RuntimeException("unknown property type: " + type);

<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom"
    xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
    xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
    xml:base="https://localhost:8283/scc/o/">
    <category term="ManagedObject"
        scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
    <content type="application/xml">
        <m:properties>
            <d:Name>SCC Tester 10</d:Name>
            <d:MoType>SccTestMO</d:MoType>
            <d:Description>SCC Test Object 2 on oddjob</d:Description>
            <d:PmGuid>22D4B93F69054595A574889BEF479F71</d:PmGuid>
            <d:VersionedSdkObject m:type="VersionedSdkObject">
                <d:Version m:type="Bag(Edm.Int32)">
                    <d:element>11</d:element>
                    <d:element>0</d:element>
                    <d:element>0</d:element>
                    <d:element>0</d:element>
                </d:Version>
            </d:VersionedSdkObject>
        </m:properties>
    </content>
</entry>

Original issue reported on code.google.com by mij.nosr...@gmail.com on 27 Jul 2012 at 6:41

GoogleCodeExporter commented 9 years ago
I got the same issue with the error message "unknown property type: Bag ..."

The code looks like this:

        EdmComplexType ctDataItem = c.getMetadata().findEdmComplexType("abc.Item");

        Builder<OObject> builderDataItem = OCollections.newBuilderctDataItem);
        OComplexObject.Builder cb = OComplexObjects.newBuilder(ctDataItem);
        cb.add(OProperties.string("Type", "value"))
            .add(OProperties.string("Type2", "value2"))
        builderDataItem.add(cb.build());

        OProperty<?> dataItems = OProperties.collection("Items", 
                new EdmCollectionType(CollectionKind.List, ctDataItem), builderDataItem.build()); 

        c.createEntity("Products")
            .properties(OProperties.int32("code", 124))
            .properties(dataItems)
            .execute();

Original comment by daniel.t...@gmail.com on 6 Aug 2012 at 9:55

GoogleCodeExporter commented 9 years ago
OData 3.0 specification defines Collection Types (see 2.2.6.2.9 of OData V3 
Specification at http://www.odata.org/documentation)

Example:
<d:EmailAddresses m:type="Collection(Edm.String)">
  <d:element>altaddress1@company.com</d:element>
  <d:element>altaddress2@company.com</d:element>
</d:EmailAddresses>

So "Bag" should be renamed to "Collection" in $metadata for the definition of a 
Collection Type and the payload.

Original comment by jens.hue...@googlemail.com on 4 Sep 2012 at 7:26

GoogleCodeExporter commented 9 years ago
I too have run into this. I was only able to get around it by running the 
client using JSON.

Original comment by allancla...@gmail.com on 24 Oct 2012 at 4:25

GoogleCodeExporter commented 9 years ago
In the AtomFeedFormatParser I made the change below and it seems to work:

  public static Iterable<OProperty<?>> parseProperties(XMLEventReader2 reader, StartElement2 propertiesElement, EdmDataServices metadata, EdmStructuralType structuralType_ ) 
  {
    List<OProperty<?>> rt = new ArrayList<OProperty<?>>();

    while (reader.hasNext())
    {
      XMLEvent2 event = reader.nextEvent();

      if (event.isEndElement() && event.asEndElement().getName().equals( propertiesElement.getName()) )
      {
        return rt;
      }

      if (event.isStartElement() && event.asStartElement().getName().getNamespaceUri().equals(NS_DATASERVICES)) {

        String name = event.asStartElement().getName().getLocalPart();
        Attribute2 typeAttribute = event.asStartElement().getAttributeByName(M_TYPE);
        Attribute2 nullAttribute = event.asStartElement().getAttributeByName(M_NULL);
        boolean isNull = nullAttribute != null && "true".equals(nullAttribute.getValue());

        OProperty<?> op = null;

        EdmType et = null;
        boolean isCollection = false;
        if ( typeAttribute != null )
        {
          String type = typeAttribute.getValue();
          et = metadata.resolveType( type );
          if( et == null && type.startsWith( "Bag" ) )
          {
            isCollection = true;
            type = type.substring( 4, type.length() -1 );
            et = metadata.resolveType( type );
          }
          if (et == null)
          {
            // property arrived with an unknown type
            throw new RuntimeException("unknown property type: " + type);
          }
        }
        else if( structuralType_ instanceof EdmComplexType )
        {
          //
          //  Assume for now we're creating a bag
          //
          et = structuralType_;
        }
        else
        {
          EdmProperty property = (EdmProperty) structuralType_.findProperty(name);
          if (property != null)
          {
            et = property.getType();
          }
          else
          {
            et = EdmSimpleType.STRING; // we must support open types
          }
        }

        if( isCollection )
        {
          //
          //  So we're on the Segments element right now, which means the next event should be the first d:element
          //
          //  Thus loop on the d:element's and for each one recurse again to create the complex object
          //
          OCollection.Builder bagBuilder = OCollections.newBuilder( et );
          Enumerable<OProperty<?>> bagObjects = Enumerable.create(parseProperties(reader, event.asStartElement(), metadata, (EdmComplexType)et ) );

          for( OProperty<?> prop: bagObjects )
          {
            bagBuilder.add( (OObject) OComplexObjects.create( (EdmComplexType) prop.getType(),
                                                              (List<OProperty<?>>) prop.getValue() ) );
          }
          OCollection<? extends OObject> bag = bagBuilder.build();
          op = OProperties.collection( name, new EdmCollectionType( EdmProperty.CollectionKind.List, (EdmComplexType) et ),
                                                                    bag);
        }
        else if (et != null && (!et.isSimple()))
        {
          EdmStructuralType est = (EdmStructuralType) et;
          op = OProperties.complex(name, (EdmComplexType) et, isNull ? null : Enumerable.create(parseProperties(reader, event.asStartElement(), metadata, est)).toList());
        }
        else
        {
          op = OProperties.parseSimple(name, (EdmSimpleType<?>) et, isNull ? null : reader.getElementText());
        }
        rt.add(op);
      }
    }

    throw new RuntimeException();
  }

Original comment by david.be...@ca.com on 31 Oct 2012 at 2:51

GoogleCodeExporter commented 9 years ago
This is causing problem for me as well. Is it available or do we have to extend 
the functionality ourselves?

Original comment by junejo.s...@gmail.com on 2 Jul 2013 at 12:29

GoogleCodeExporter commented 9 years ago
Contributed the change to the project and its under review 
http://review.odata4j.org/#/c/13/

Original comment by junejo.s...@gmail.com on 29 Aug 2013 at 8:27