[OLINGO-66] First prototype with jackson library

This commit is contained in:
Christian Amend 2013-11-13 15:55:00 +01:00
parent 8c1316858c
commit eea0324dd2
35 changed files with 2118 additions and 0 deletions

View File

@ -0,0 +1,23 @@
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
package org.apache.olingo.consumer.api.deserializer;
public interface AnnotationProperty extends Property {
String getValue();
}

View File

@ -0,0 +1,35 @@
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
package org.apache.olingo.consumer.api.deserializer;
import java.util.List;
import java.util.Map;
public interface ComplexValue extends Value {
Value getValue(String name);
List<Property> getProperties();
Map<String, NavigationProperty> getNavigationProperties();
Map<String, AnnotationProperty> getAnnotationProperties();
Map<String, StructuralProperty> getStructuralProperties();
}

View File

@ -0,0 +1,36 @@
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
package org.apache.olingo.consumer.api.deserializer;
public class ConsumerException extends Exception {
private static final long serialVersionUID = 1L;
public ConsumerException() {
super();
}
public ConsumerException(final String message) {
super(message);
}
public ConsumerException(final String message, final Throwable cause) {
super(message, cause);
}
}

View File

@ -0,0 +1,59 @@
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
package org.apache.olingo.consumer.api.deserializer;
import java.util.List;
import java.util.Map;
public interface Entity {
String getODataContext();
String getODataMetaDataEtag();
String getODataType();
Long getODataCount();
String getODataNextLink();
String getODataDeltaLink();
String getODataId();
String getODataETag();
String getODataEditLink();
String getODataReadLink();
List<Property> getProperties();
Map<String, NavigationProperty> getNavigationProperties();
Map<String, AnnotationProperty> getAnnotationProperties();
Map<String, StructuralProperty> getStructuralProperties();
Property getProperty(String name);
<T extends Property> T getProperty(String name, Class<T> clazz);
Object getPropertyContent(String name);
}

View File

@ -0,0 +1,34 @@
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
package org.apache.olingo.consumer.api.deserializer;
import java.util.List;
public interface EntitySet extends Iterable<Entity> {
String getODataContext();
Long getODataCount();
String getODataNextLink();
String getODataDeltaLink();
List<Entity> getEntities();
}

View File

@ -0,0 +1,27 @@
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
package org.apache.olingo.consumer.api.deserializer;
public interface NavigationProperty extends Property {
public abstract String getAssociationLink();
public abstract String getNavigationLink();
}

View File

@ -0,0 +1,23 @@
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
package org.apache.olingo.consumer.api.deserializer;
public interface Property {
String getName();
}

View File

@ -0,0 +1,30 @@
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
package org.apache.olingo.consumer.api.deserializer;
import java.io.InputStream;
public interface Reader {
public abstract EntitySet readEntitySet(InputStream in) throws ConsumerException;
public abstract Entity readEntity(InputStream in) throws ConsumerException;
public abstract Property readProperty(InputStream in) throws ConsumerException;
}

View File

@ -0,0 +1,30 @@
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
package org.apache.olingo.consumer.api.deserializer;
import java.util.List;
public interface StructuralProperty extends Property {
boolean containsCollection();
Value getValue();
List<Value> getValues();
}

View File

@ -0,0 +1,27 @@
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
package org.apache.olingo.consumer.api.deserializer;
public interface Value {
boolean isComplex();
Object getContent();
<T> T getContentAs(T type);
}

View File

@ -42,6 +42,21 @@
<groupId>org.apache.olingo</groupId>
<artifactId>olingo-odata4-commons-core-incubating</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>

View File

@ -0,0 +1,52 @@
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
package org.apache.olingo.consumer.core.deserializer;
import org.apache.olingo.consumer.api.deserializer.AnnotationProperty;
public class AnnotationPropertyImpl implements AnnotationProperty {
private final String name;
private final String value;
public AnnotationPropertyImpl(final String name, final String value) {
this.name = name;
this.value = value;
}
@Override
public String getName() {
return name;
}
@Override
public String getValue() {
return value;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "AnnotationPropertyImpl [name=" + name + ", value=" + value + "]";
}
}

View File

@ -0,0 +1,80 @@
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
package org.apache.olingo.consumer.core.deserializer;
import java.util.Collections;
import java.util.Map;
import org.apache.olingo.consumer.api.deserializer.AnnotationProperty;
import org.apache.olingo.consumer.api.deserializer.ComplexValue;
import org.apache.olingo.consumer.api.deserializer.NavigationProperty;
import org.apache.olingo.consumer.api.deserializer.StructuralProperty;
import org.apache.olingo.consumer.api.deserializer.Value;
public class ComplexValueImpl extends PropertyCollection implements ComplexValue {
public ComplexValueImpl() {}
public ComplexValueImpl(final Map<String, AnnotationProperty> annotationProperties,
final Map<String, NavigationProperty> navigationProperties,
final Map<String, StructuralProperty> structuralProperties) {
super(annotationProperties, navigationProperties, structuralProperties);
}
@Override
public Value getValue(final String name) {
StructuralProperty property = structuralProperties.get(name);
if (property == null) {
return null;
}
return property.getValue();
}
@Override
public Map<String, AnnotationProperty> getAnnotationProperties() {
return Collections.unmodifiableMap(annotationProperties);
}
@Override
public Map<String, NavigationProperty> getNavigationProperties() {
return Collections.unmodifiableMap(navigationProperties);
}
@Override
public boolean isComplex() {
return true;
}
@Override
public Map<String, StructuralProperty> getContent() {
return Collections.unmodifiableMap(structuralProperties);
}
@SuppressWarnings("unchecked")
@Override
public <T> T getContentAs(final T type) {
return (T) getContent();
}
@Override
public String toString() {
return "ComplexValueImpl [annotations=" + annotationProperties + ", navigationProperties=" + navigationProperties
+ ", properties=" + structuralProperties + "]";
}
}

View File

@ -0,0 +1,124 @@
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
package org.apache.olingo.consumer.core.deserializer;
import java.util.Map;
import org.apache.olingo.consumer.api.deserializer.AnnotationProperty;
import org.apache.olingo.consumer.api.deserializer.Entity;
import org.apache.olingo.consumer.api.deserializer.NavigationProperty;
import org.apache.olingo.consumer.api.deserializer.Property;
import org.apache.olingo.consumer.api.deserializer.StructuralProperty;
public class EntityImpl extends PropertyCollection implements Entity {
public EntityImpl() {}
public EntityImpl(final Map<String, AnnotationProperty> annotationProperties,
final Map<String, NavigationProperty> navigationProperties,
final Map<String, StructuralProperty> structuralProperties) {
super(annotationProperties, navigationProperties, structuralProperties);
}
@Override
public String getODataMetaDataEtag() {
return getAnnotationValue("odata.metadataEtag");
}
@Override
public String getODataType() {
return getAnnotationValue("odata.type");
}
@Override
public Long getODataCount() {
return Long.valueOf(getAnnotationValue("odata.count"));
}
@Override
public String getODataNextLink() {
return getAnnotationValue("odata.nextLink");
}
@Override
public String getODataDeltaLink() {
return getAnnotationValue("odata.deltaLink");
}
@Override
public String getODataReadLink() {
return getAnnotationValue("odata.readLink");
}
@Override
public String getODataContext() {
return getAnnotationValue("odata.context");
}
@Override
public String getODataId() {
return getAnnotationValue("odata.id");
}
@Override
public String getODataETag() {
return getAnnotationValue("odata.etag");
}
@Override
public String getODataEditLink() {
return getAnnotationValue("odata.editLink");
}
@Override
public Object getPropertyContent(final String name) {
StructuralProperty property = structuralProperties.get(name);
if (property != null) {
return property.getValue().getContent();
}
return null;
}
@Override
public Property getProperty(final String name) {
Property p = structuralProperties.get(name);
if (p == null) {
p = annotationProperties.get(name);
}
if (p == null) {
p = navigationProperties.get(name);
}
return p;
}
@SuppressWarnings("unchecked")
@Override
public <T extends Property> T getProperty(final String name, final Class<T> clazz) {
Property p = getProperty(name);
return (T) p;
}
private String getAnnotationValue(final String key) {
AnnotationProperty prop = annotationProperties.get(key);
if (prop == null) {
return null;
}
return prop.getValue();
}
}

View File

@ -0,0 +1,68 @@
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
package org.apache.olingo.consumer.core.deserializer;
import java.io.IOException;
import org.apache.olingo.consumer.api.deserializer.EntitySet;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
public class EntitySetBuilder {
private final JsonParser parser;
public EntitySetBuilder(final JsonParser jp) {
parser = jp;
}
public EntitySet buildEntitySet() throws JsonParseException, IOException {
return parseEntitySet(parser);
}
private EntitySet parseEntitySet(final JsonParser jp) throws JsonParseException, IOException {
EntitySetImpl entitySet = new EntitySetImpl();
boolean arrayStarted = false;
while (jp.nextToken() != null) {
JsonToken token = jp.getCurrentToken();
switch (token) {
case START_ARRAY:
PropertyCollectionBuilder builder = new PropertyCollectionBuilder(jp, entitySet);
entitySet.setPropertyCollectionBuilder(builder);
arrayStarted = true;
break;
case START_OBJECT:
if (arrayStarted) {
return entitySet;
}
break;
case VALUE_NUMBER_INT:
case VALUE_STRING:
entitySet.addAnnotation(jp.getCurrentName(), jp.getValueAsString());
default:
break;
}
}
return entitySet;
}
}

View File

@ -0,0 +1,113 @@
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
package org.apache.olingo.consumer.core.deserializer;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.olingo.consumer.api.deserializer.Entity;
import org.apache.olingo.consumer.api.deserializer.EntitySet;
import com.fasterxml.jackson.core.JsonParseException;
public class EntitySetImpl implements EntitySet, Iterator<Entity> {
private String odataContext;
private Long odataCount;
private String odataNextLink;
private String odataDeltaLink;
private List<Entity> entities = null;
private PropertyCollectionBuilder propertyCollectionsBuilder;
@Override
public String getODataContext() {
return odataContext;
}
@Override
public Long getODataCount() {
return odataCount;
}
@Override
public String getODataNextLink() {
return odataNextLink;
}
@Override
public String getODataDeltaLink() {
return odataDeltaLink;
}
public void addAnnotation(final String name, final String value) {
if ("odata.context".equalsIgnoreCase(name)) {
odataContext = value;
} else if ("odata.deltaLink".equalsIgnoreCase(name)) {
odataDeltaLink = value;
} else if ("odata.count".equalsIgnoreCase(name)) {
odataCount = Long.parseLong(value);
} else if ("odata.nextLink".equalsIgnoreCase(name)) {
odataNextLink = value;
}
}
@Override
public List<Entity> getEntities() {
if (entities == null) {
entities = new ArrayList<Entity>();
while (propertyCollectionsBuilder.parseNext()) {
entities.add(propertyCollectionsBuilder.buildEntity());
}
}
return entities;
}
public void setPropertyCollectionBuilder(final PropertyCollectionBuilder builder) {
propertyCollectionsBuilder = builder;
}
@Override
public boolean hasNext() {
try {
return propertyCollectionsBuilder.hasNext();
} catch (JsonParseException e) {} catch (IOException e) {}
return false;
}
@Override
public Entity next() {
if (propertyCollectionsBuilder.parseNext()) {
return propertyCollectionsBuilder.buildEntity();
}
return null;
}
@Override
public void remove() {}
@Override
public Iterator<Entity> iterator() {
return this;
}
}

View File

@ -0,0 +1,89 @@
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
package org.apache.olingo.consumer.core.deserializer;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import org.apache.olingo.consumer.api.deserializer.ConsumerException;
import org.apache.olingo.consumer.api.deserializer.Entity;
import org.apache.olingo.consumer.api.deserializer.EntitySet;
import org.apache.olingo.consumer.api.deserializer.Property;
import org.apache.olingo.consumer.api.deserializer.Reader;
import org.apache.olingo.consumer.api.deserializer.StructuralProperty;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
public class JsonReader implements Reader {
@Override
public EntitySet readEntitySet(final InputStream in) throws ConsumerException {
JsonFactory jsonFactory = new JsonFactory();
// or, for data binding, org.codehaus.jackson.mapper.MappingJsonFactory
try {
JsonParser jp = jsonFactory.createParser(in);
EntitySetBuilder entitySet = new EntitySetBuilder(jp);
return entitySet.buildEntitySet();
} catch (JsonParseException e) {
throw new ConsumerException("JSON Parsing failed.", e);
} catch (IOException e) {
throw new ConsumerException("JSON Parsing failed.", e);
}
}
@Override
public Entity readEntity(final InputStream in) throws ConsumerException {
Entity entity = null;
JsonFactory jsonFactory = new JsonFactory();
// or, for data binding, org.codehaus.jackson.mapper.MappingJsonFactory
try {
JsonParser jp = jsonFactory.createParser(in);
PropertyCollectionBuilder builder = new PropertyCollectionBuilder(jp);
builder.parseNext();
entity = builder.buildEntity();
} catch (JsonParseException e) {
throw new ConsumerException("JSON Parsing failed.", e);
} catch (IOException e) {
throw new ConsumerException("JSON Parsing failed.", e);
}
return entity;
}
/*
* (non-Javadoc)
*
* @see org.apache.olingo.core.consumer.Reader#parseProperty(java.io.InputStream)
*/
@Override
public Property readProperty(final InputStream in) throws ConsumerException {
Entity entity = readEntity(in);
Map<String, StructuralProperty> properties = entity.getStructuralProperties();
if (properties.size() == 1) {
return properties.values().iterator().next();
}
return null;
}
}

View File

@ -0,0 +1,87 @@
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
package org.apache.olingo.consumer.core.deserializer;
import org.apache.olingo.consumer.api.deserializer.NavigationProperty;
public class NavigationPropertyImpl implements NavigationProperty {
private final String name;
private String associationLink;
private String navigationLink;
public NavigationPropertyImpl(final String name) {
this.name = parseName(name);
}
public NavigationPropertyImpl(final String name, final String link) {
this(name);
updateLink(name, link);
}
@Override
public String getName() {
return name;
}
@Override
public String getAssociationLink() {
return associationLink;
}
@Override
public String getNavigationLink() {
return navigationLink;
}
public void updateLink(final String name, final String link) {
String regexNavigationLink = ".*@odata.navigationLink$";
String regexAssociationLink = ".*@odata.associationLink$";
if (name.matches(regexNavigationLink)) {
navigationLink = link;
} else if (name.matches(regexAssociationLink)) {
associationLink = link;
}
}
private String parseName(final String nameToParse) {
String[] split = nameToParse.split("@");
if (split.length == 2) {
return split[0];
} else {
throw new IllegalArgumentException("Got OData Navigation with unparseable format '"
+ nameToParse + "'.");
}
}
public void updateLink(final NavigationProperty navigationProperty) {
if (navigationProperty.getAssociationLink() != null) {
associationLink = navigationProperty.getAssociationLink();
}
if (navigationProperty.getNavigationLink() != null) {
navigationLink = navigationProperty.getNavigationLink();
}
}
@Override
public String toString() {
return "NavigationPropertyImpl [name=" + name + ", associationLink=" + associationLink
+ ", navigationLink=" + navigationLink + "]";
}
}

View File

@ -0,0 +1,51 @@
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
package org.apache.olingo.consumer.core.deserializer;
import org.apache.olingo.consumer.api.deserializer.Value;
public class PrimitiveValue implements Value {
private final Object content;
public PrimitiveValue(final Object content) {
this.content = content;
}
@Override
public boolean isComplex() {
return false;
}
@Override
public Object getContent() {
return content;
}
@SuppressWarnings("unchecked")
@Override
public <T> T getContentAs(final T type) {
return (T) content;
}
@Override
public String toString() {
return String.valueOf(content);
}
}

View File

@ -0,0 +1,91 @@
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
package org.apache.olingo.consumer.core.deserializer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.olingo.consumer.api.deserializer.AnnotationProperty;
import org.apache.olingo.consumer.api.deserializer.NavigationProperty;
import org.apache.olingo.consumer.api.deserializer.Property;
import org.apache.olingo.consumer.api.deserializer.StructuralProperty;
abstract class PropertyCollection {
protected Map<String, AnnotationProperty> annotationProperties = new HashMap<String, AnnotationProperty>();
protected Map<String, NavigationProperty> navigationProperties = new HashMap<String, NavigationProperty>();
protected Map<String, StructuralProperty> structuralProperties = new HashMap<String, StructuralProperty>();
public PropertyCollection() {}
protected PropertyCollection(final Map<String, AnnotationProperty> annotationProperties,
final Map<String, NavigationProperty> navigationProperties,
final Map<String, StructuralProperty> structuralProperties) {
this.annotationProperties = annotationProperties;
this.navigationProperties = navigationProperties;
this.structuralProperties = structuralProperties;
}
public List<Property> getProperties() {
int initialCapacity = annotationProperties.size() + navigationProperties.size() + structuralProperties.size();
List<Property> properties = new ArrayList<Property>(initialCapacity);
properties.addAll(annotationProperties.values());
properties.addAll(navigationProperties.values());
properties.addAll(structuralProperties.values());
return properties;
}
public Map<String, AnnotationProperty> getAnnotationProperties() {
return Collections.unmodifiableMap(annotationProperties);
}
public Map<String, NavigationProperty> getNavigationProperties() {
return Collections.unmodifiableMap(navigationProperties);
}
public Map<String, StructuralProperty> getStructuralProperties() {
return Collections.unmodifiableMap(structuralProperties);
}
public void addProperty(final Property property) {
if (property == null) {
throw new IllegalArgumentException("Property parameter MUST NOT be NULL.");
}
if (property instanceof NavigationPropertyImpl) {
NavigationPropertyImpl navProperty = (NavigationPropertyImpl) navigationProperties.get(property.getName());
if (navProperty == null) {
navigationProperties.put(property.getName(), (NavigationPropertyImpl) property);
} else {
NavigationProperty temp = (NavigationProperty) property;
navProperty.updateLink(temp);
}
} else if (property instanceof AnnotationPropertyImpl) {
annotationProperties.put(property.getName(), (AnnotationPropertyImpl) property);
} else if (property instanceof StructuralProperty) {
structuralProperties.put(property.getName(), (StructuralProperty) property);
} else {
throw new IllegalArgumentException("Unknown class '" + property.getClass() + "'.");
}
}
}

View File

@ -0,0 +1,211 @@
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
package org.apache.olingo.consumer.core.deserializer;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.olingo.consumer.api.deserializer.AnnotationProperty;
import org.apache.olingo.consumer.api.deserializer.ComplexValue;
import org.apache.olingo.consumer.api.deserializer.Entity;
import org.apache.olingo.consumer.api.deserializer.NavigationProperty;
import org.apache.olingo.consumer.api.deserializer.Property;
import org.apache.olingo.consumer.api.deserializer.StructuralProperty;
import org.apache.olingo.consumer.api.deserializer.Value;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
public class PropertyCollectionBuilder extends PropertyCollection {
private JsonParser parser;
private EntitySetImpl enclosingEntitySet;
public PropertyCollectionBuilder(final JsonParser parser) {
this.parser = parser;
}
private PropertyCollectionBuilder() {};
public PropertyCollectionBuilder(final JsonParser jp, final EntitySetImpl entitySet) {
this(jp);
enclosingEntitySet = entitySet;
}
public Entity buildEntity() {
Entity v = new EntityImpl(annotationProperties, navigationProperties, structuralProperties);
resetProperties();
return v;
}
public ComplexValue buildComplexValue() {
ComplexValue v = new ComplexValueImpl(annotationProperties, navigationProperties, structuralProperties);
resetProperties();
return v;
}
private void resetProperties() {
annotationProperties = new HashMap<String, AnnotationProperty>();
navigationProperties = new HashMap<String, NavigationProperty>();
structuralProperties = new HashMap<String, StructuralProperty>();
}
private PropertyCollectionBuilder next = null;
public boolean hasNext() throws JsonParseException, IOException {
if (parser.isClosed()) {
return false;
}
next = parseNextObject(parser, this);
return (next != null);
}
public boolean parseNext() {
try {
if (hasNext()) {
if (next != null) {
return true;
}
if (next == null) {
parser.close();
return false;
}
return true;
}
} catch (JsonParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
/**
*
* @param jp
* @param builder
* @return
* @throws IOException
* @throws JsonParseException
*/
private PropertyCollectionBuilder parseNextObject(final JsonParser jp, final PropertyCollectionBuilder builder)
throws JsonParseException, IOException {
boolean endReached = readToStartObjectOrEnd(jp);
if (endReached) {
return null;
}
//
String currentFieldName = null;
List<Value> values = null;
while (jp.nextToken() != null) {
JsonToken token = jp.getCurrentToken();
switch (token) {
case START_OBJECT:
if (currentFieldName != null) {
ComplexValue cvp = parseNextObject(jp, new PropertyCollectionBuilder()).buildComplexValue();
if (values == null) {
builder.addProperty(new StructuralPropertyImpl(currentFieldName, cvp));
} else {
values.add(cvp);
}
}
break;
case END_OBJECT:
return builder;
case START_ARRAY:
values = new ArrayList<Value>();
break;
case END_ARRAY:
if (values != null) {
builder.addProperty(new StructuralPropertyImpl(currentFieldName, values));
values = null;
}
break;
case FIELD_NAME:
currentFieldName = jp.getCurrentName();
break;
case NOT_AVAILABLE:
break;
case VALUE_EMBEDDED_OBJECT:
break;
case VALUE_NULL:
Property nullProperty = createProperty(jp.getCurrentName(), null);
builder.addProperty(nullProperty);
break;
case VALUE_FALSE:
case VALUE_NUMBER_FLOAT:
case VALUE_NUMBER_INT:
case VALUE_STRING:
case VALUE_TRUE:
if (values == null) {
Property property = createProperty(jp.getCurrentName(), jp.getValueAsString());
builder.addProperty(property);
} else {
PrimitiveValue value = new PrimitiveValue(jp.getValueAsString());
values.add(value);
}
break;
default:
break;
}
}
return null;
}
private boolean readToStartObjectOrEnd(final JsonParser jp) throws IOException, JsonParseException {
JsonToken endToken = JsonToken.START_OBJECT;
JsonToken token = jp.getCurrentToken() == null ? jp.nextToken() : jp.getCurrentToken();
while (token != null && token != endToken) {
if (enclosingEntitySet != null) {
switch (token) {
case VALUE_FALSE:
case VALUE_NUMBER_FLOAT:
case VALUE_NUMBER_INT:
case VALUE_TRUE:
case VALUE_STRING:
enclosingEntitySet.addAnnotation(jp.getCurrentName(), jp.getValueAsString());
break;
default:
break;
}
}
//
token = jp.nextToken();
}
return token == null;
}
private Property createProperty(final String name, final String value) {
if (name.contains("@")) {
return new NavigationPropertyImpl(name, value);
} else if (name.contains(".")) {
return new AnnotationPropertyImpl(name, value);
} else {
return new StructuralPropertyImpl(name, new PrimitiveValue(value));
}
}
}

View File

@ -0,0 +1,81 @@
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
package org.apache.olingo.consumer.core.deserializer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.olingo.consumer.api.deserializer.StructuralProperty;
import org.apache.olingo.consumer.api.deserializer.Value;
public class StructuralPropertyImpl implements StructuralProperty {
private final List<Value> values;
private final String name;
private final boolean containsCollection;
public StructuralPropertyImpl(final String name, final Value value) {
this(name, false, value);
}
public StructuralPropertyImpl(final String name, final List<Value> values) {
// XXX: ugly -> refactore
this(name, true, values.toArray(new Value[0]));
}
public StructuralPropertyImpl(final String name, final boolean asCollection, final Value... value) {
if (value == null || value.length == 0) {
throw new IllegalArgumentException("Missing or NULL value argument.");
}
containsCollection = asCollection;
this.name = name;
values = new ArrayList<Value>(value.length);
for (Value v : value) {
values.add(v);
}
}
@Override
public Value getValue() {
return values.get(0);
}
@Override
public List<Value> getValues() {
return Collections.unmodifiableList(values);
}
@Override
public String getName() {
return name;
}
@Override
public boolean containsCollection() {
return containsCollection;
}
@Override
public String toString() {
return "StructuralPropertyImpl [name=" + name + ", containsCollection=" + containsCollection
+ ", values=" + values + "]";
}
}

View File

@ -0,0 +1,72 @@
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
package org.apache.olingo.consumer.core.deserializer;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.InputStream;
import org.apache.olingo.consumer.api.deserializer.ComplexValue;
import org.apache.olingo.consumer.api.deserializer.Property;
import org.apache.olingo.consumer.api.deserializer.StructuralProperty;
import org.apache.olingo.consumer.api.deserializer.Value;
import org.apache.olingo.consumer.core.testutil.StringHelper;
import org.junit.Test;
public class JsonReaderPerformance {
@Test
public void testComplexPropertyPerformance() throws Exception {
JsonReader consumer = new JsonReader();
int runs = 1000; // * 100;
InputStream in = JsonReaderPerformance.class.getResourceAsStream("/complexProperty.json");
String content = StringHelper.inputStreamToString(in);
// System.out.println("Started...");
ComplexValue complex = null;
// long startTime = System.currentTimeMillis();
for (int i = 0; i < runs; i++) {
Property property = consumer.readProperty(StringHelper.encapsulate(content));
complex = (ComplexValue) ((StructuralProperty) property).getValue();
}
// long endTime = System.currentTimeMillis();
// long duration = endTime - startTime;
// System.out.println("Duration: " + duration + " ms");
// System.out.println("Duration per run: " + (duration / (float) runs) + " ms");
testComplexProperty(complex);
}
private void testComplexProperty(final Value value) {
assertNotNull(value);
assertTrue(value.isComplex());
ComplexValue complex = (ComplexValue) value;
assertEquals("Obere Str. 57", complex.getValue("Street").getContent());
assertEquals("Berlin", complex.getValue("City").getContent());
assertNull(complex.getValue("Region").getContent());
assertEquals("D-12209", complex.getValue("PostalCode").getContent());
}
}

View File

@ -0,0 +1,373 @@
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
package org.apache.olingo.consumer.core.deserializer;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.InputStream;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import junit.framework.Assert;
import org.apache.olingo.consumer.api.deserializer.ComplexValue;
import org.apache.olingo.consumer.api.deserializer.Entity;
import org.apache.olingo.consumer.api.deserializer.EntitySet;
import org.apache.olingo.consumer.api.deserializer.Property;
import org.apache.olingo.consumer.api.deserializer.Reader;
import org.apache.olingo.consumer.api.deserializer.StructuralProperty;
import org.apache.olingo.consumer.api.deserializer.Value;
import org.junit.Test;
public class JsonReaderTest {
@Test
public void testEntitySet() throws Exception {
Reader consumer = new JsonReader();
EntitySet entitySet = consumer.readEntitySet(
JsonReaderTest.class.getResourceAsStream("/fullEntitySet.json"));
List<Entity> entities = entitySet.getEntities();
validateEntitySet(entitySet);
assertNotNull(entities);
Entity entity = entities.get(0);
assertNotNull(entity);
validateEntityAlfki(entity);
StructuralProperty structuralProperty = entity.getProperty("Address", StructuralProperty.class);
assertEquals("Address", structuralProperty.getName());
Value value = structuralProperty.getValue();
assertTrue(value.isComplex());
ComplexValue complexValue = (ComplexValue) value;
validateAddressBerlin(complexValue);
validateComplexValueNavigationLinks(complexValue);
}
@Test
public void testEntitySetWithTwoEntities() throws Exception {
Reader consumer = new JsonReader();
EntitySet entitySet = consumer.readEntitySet(getJson("/fullEntitySetWithTwoEntities.json"));
List<Entity> entities = entitySet.getEntities();
validateEntitySet(entitySet);
assertNotNull(entities);
assertEquals(2, entities.size());
//
Entity firstEntity = entities.get(0);
assertNotNull(firstEntity);
validateEntityAlfki(firstEntity);
StructuralProperty structuralProperty = firstEntity.getProperty("Address", StructuralProperty.class);
assertEquals("Address", structuralProperty.getName());
Value value = structuralProperty.getValue();
assertTrue(value.isComplex());
ComplexValue complexValue = (ComplexValue) value;
validateAddressBerlin(complexValue);
validateComplexValueNavigationLinks(complexValue);
//
Entity secondEntity = entities.get(1);
assertNotNull(secondEntity);
validateEntityMuski(secondEntity);
StructuralProperty addressMuster = secondEntity.getProperty("Address", StructuralProperty.class);
assertEquals("Address", addressMuster.getName());
validateAddressMuster((ComplexValue) addressMuster.getValue());
}
@Test
public void streamingTestForEntitySetWithTwoEntities() throws Exception {
Reader consumer = new JsonReader();
EntitySet entitySet = consumer.readEntitySet(getJson("/fullEntitySetWithTwoEntities.json"));
validateEntitySet(entitySet, false);
for (Entity entity : entitySet) {
if ("Customers('ALFKI')".equals(entity.getODataId())) {
validateEntityAlfki(entity);
StructuralProperty structuralProperty = entity.getProperty("Address", StructuralProperty.class);
assertEquals("Address", structuralProperty.getName());
Value value = structuralProperty.getValue();
assertTrue(value.isComplex());
ComplexValue complexValue = (ComplexValue) value;
validateAddressBerlin(complexValue);
validateComplexValueNavigationLinks(complexValue);
} else if ("Customers('MUSKI')".equals(entity.getODataId())) {
validateEntityMuski(entity);
StructuralProperty addressMuster = entity.getProperty("Address", StructuralProperty.class);
assertEquals("Address", addressMuster.getName());
validateAddressMuster((ComplexValue) addressMuster.getValue());
} else {
fail("Got unknown entity with id '" + entity.getODataId() + "'.");
}
}
validateEntitySet(entitySet, true);
}
@Test
public void iteratorTestForEntitySetWithTwoEntities() throws Exception {
Reader consumer = new JsonReader();
EntitySet entitySet = consumer.readEntitySet(getJson("/fullEntitySetWithTwoEntities.json"));
assertEquals(2, entitySet.getEntities().size());
validateEntitySet(entitySet, true);
for (Entity entity : entitySet) {
if ("Customers('ALFKI')".equals(entity.getODataId())) {
validateEntityAlfki(entity);
StructuralProperty structuralProperty = entity.getProperty("Address", StructuralProperty.class);
assertEquals("Address", structuralProperty.getName());
Value value = structuralProperty.getValue();
assertTrue(value.isComplex());
ComplexValue complexValue = (ComplexValue) value;
validateAddressBerlin(complexValue);
validateComplexValueNavigationLinks(complexValue);
} else if ("Customers('MUSKI')".equals(entity.getODataId())) {
validateEntityMuski(entity);
StructuralProperty addressMuster = entity.getProperty("Address", StructuralProperty.class);
assertEquals("Address", addressMuster.getName());
validateAddressMuster((ComplexValue) addressMuster.getValue());
} else {
fail("Got unknown entity with id '" + entity.getODataId() + "'.");
}
}
}
@Test
public void testEntity() throws Exception {
Reader consumer = new JsonReader();
Entity entity = consumer.readEntity(JsonReaderTest.class.getResourceAsStream("/fullEntity.json"));
validateEntityAlfki(entity);
StructuralProperty structuralProperty = entity.getProperty("Address", StructuralProperty.class);
assertEquals("Address", structuralProperty.getName());
Value value = structuralProperty.getValue();
assertTrue(value.isComplex());
ComplexValue complexValue = (ComplexValue) value;
validateAddressBerlin(complexValue);
validateComplexValueNavigationLinks(complexValue);
}
@Test
public void testComplexProperty() throws Exception {
Reader consumer = new JsonReader();
Property property = consumer.readProperty(getJson("/complexProperty.json"));
assertEquals("Address", property.getName());
assertTrue(property instanceof StructuralProperty);
StructuralProperty structuralProperty = (StructuralProperty) property;
Value value = structuralProperty.getValue();
assertTrue(value.isComplex());
ComplexValue complexValue = (ComplexValue) value;
validateAddressBerlin(complexValue);
validateAddressBerlin(complexValue);
}
@Test
public void testEntityWithCollectionOfComplexProperty() throws Exception {
Reader consumer = new JsonReader();
Entity entity = consumer.readEntity(getJson("/fullEntityWithCollectionOfComplexValues.json"));
StructuralProperty address = entity.getProperty("Address", StructuralProperty.class);
assertTrue(address.containsCollection());
assertEquals("Address", address.getName());
List<Value> values = address.getValues();
assertEquals(2, values.size());
Value value = values.get(0);
assertTrue(value.isComplex());
validateAddressBerlin((ComplexValue) value);
//
ComplexValue addressTwo = (ComplexValue) values.get(1);
validateAddressMuster(addressTwo);
}
@Test
public void testSetOfPrimitive() throws Exception {
Reader consumer = new JsonReader();
InputStream content = JsonReaderTest.class.getResourceAsStream("/setOfPrimitiveProperties.json");
Property property = consumer.readProperty(content);
assertEquals("EmailAddresses", property.getName());
assertTrue(property instanceof StructuralProperty);
StructuralProperty structuralProperty = (StructuralProperty) property;
assertTrue(structuralProperty.containsCollection());
Collection<Value> values = structuralProperty.getValues();
Iterator<Value> valueIt = values.iterator();
assertEquals("Julie@Swansworth.com", valueIt.next().getContent());
assertEquals("Julie.Swansworth@work.com", valueIt.next().getContent());
}
@Test
public void testSetOfComplex() throws Exception {
Reader consumer = new JsonReader();
InputStream content = JsonReaderTest.class.getResourceAsStream("/setOfComplexProperties.json");
Property property = consumer.readProperty(content);
Assert.assertEquals("PhoneNumbers", property.getName());
Assert.assertTrue(property instanceof StructuralProperty);
StructuralProperty structuralProperty = (StructuralProperty) property;
assertTrue(structuralProperty.containsCollection());
List<Value> values = structuralProperty.getValues();
assertEquals(2, values.size());
ComplexValue phoneNumberOne = (ComplexValue) values.get(0);
assertEquals("425-555-1212", phoneNumberOne.getValue("Number").getContent());
assertEquals("Home", phoneNumberOne.getValue("Type").getContent());
assertEquals(null, phoneNumberOne.getValue("Carrier"));
assertEquals(null, phoneNumberOne.getAnnotationProperties().get("odata.type"));
ComplexValue phoneNumberTwo = (ComplexValue) values.get(1);
assertEquals("425-555-0178", phoneNumberTwo.getValue("Number").getContent());
assertEquals("Cell", phoneNumberTwo.getValue("Type").getContent());
assertEquals("Sprint", phoneNumberTwo.getValue("Carrier").getContent());
assertEquals("#Model.CellPhoneNumber",
phoneNumberTwo.getAnnotationProperties().get("odata.type").getValue());
// ComplexValue complex = consumer.parseComplexValue(content);
//
// Value value = complex.getValue("PhoneNumbers");
// assertNotNull(value);
// assertTrue(value.isComplex());
// ComplexValue complexValue = (ComplexValue) value;
}
private void validateEntityAlfki(final Entity entity) {
assertNotNull(entity);
assertEquals("http://host/service/$metadata#Customers/$entity", entity.getODataContext());
assertEquals("Customers('ALFKI')", entity.getODataId());
assertEquals("W/\"MjAxMy0wNS0yN1QxMTo1OFo=\"", entity.getODataETag());
assertEquals("Customers('ALFKI')", entity.getODataEditLink());
assertNotNull(entity.getNavigationProperties());
assertTrue(entity.getNavigationProperties().containsKey("Orders"));
assertEquals("Customers('ALFKI')/Orders",
entity.getNavigationProperties().get("Orders").getNavigationLink());
assertNotNull(entity.getNavigationProperties());
assertTrue(entity.getNavigationProperties().containsKey("Orders"));
assertEquals("Customers('ALFKI')/Orders/$ref",
entity.getNavigationProperties().get("Orders").getAssociationLink());
assertNotNull(entity.getPropertyContent("ID"));
assertEquals("ALFKI", entity.getPropertyContent("ID"));
assertEquals("Alfreds Futterkiste", entity.getPropertyContent("CompanyName"));
assertEquals("Maria Anders", entity.getPropertyContent("ContactName"));
assertEquals("Sales Representative", entity.getPropertyContent("ContactTitle"));
assertEquals("030-0074321", entity.getPropertyContent("Phone"));
assertEquals("030-0076545", entity.getPropertyContent("Fax"));
}
private void validateEntityMuski(final Entity entity) {
assertNotNull(entity);
assertEquals("http://host/service/$metadata#Customers/$entity", entity.getODataContext());
assertEquals("Customers('MUSKI')", entity.getODataId());
assertEquals("W/\"MjAxMy0wNS0yN1QxMTo1OFo=\"", entity.getODataETag());
assertEquals("Customers('MUSKI')", entity.getODataEditLink());
assertNotNull(entity.getNavigationProperties());
assertTrue(entity.getNavigationProperties().containsKey("Orders"));
assertEquals("Customers('MUSKI')/Orders", entity.getNavigationProperties().get("Orders").getNavigationLink());
assertNotNull(entity.getNavigationProperties());
assertTrue(entity.getNavigationProperties().containsKey("Orders"));
assertEquals("Customers('MUSKI')/Orders/$ref",
entity.getNavigationProperties().get("Orders").getAssociationLink());
assertNotNull(entity.getPropertyContent("ID"));
assertEquals("MUSKI", entity.getPropertyContent("ID"));
assertEquals("Mustermanns Futterkiste", entity.getPropertyContent("CompanyName"));
assertEquals("Mustermann Max", entity.getPropertyContent("ContactName"));
assertEquals("Some Guy", entity.getPropertyContent("ContactTitle"));
assertEquals("030-002222", entity.getPropertyContent("Phone"));
assertEquals("030-004444", entity.getPropertyContent("Fax"));
}
private void validateAddressMuster(final ComplexValue addressTwo) {
assertEquals("Musterstrasse 42", addressTwo.getValue("Street").getContent());
assertEquals("Musterstadt", addressTwo.getValue("City").getContent());
assertEquals("SomeRegion", addressTwo.getValue("Region").getContent());
assertEquals("D-42042", addressTwo.getValue("PostalCode").getContent());
}
private void validateAddressBerlin(final ComplexValue complex) {
assertNotNull(complex);
assertEquals("Obere Str. 57", complex.getValue("Street").getContent());
assertEquals("Berlin", complex.getValue("City").getContent());
assertNull(complex.getValue("Region").getContent());
assertEquals("D-12209", complex.getValue("PostalCode").getContent());
}
private void validateComplexValueNavigationLinks(final ComplexValue complex) {
assertNotNull(complex.getNavigationProperties());
assertTrue(complex.getNavigationProperties().containsKey("Country"));
assertEquals("Customers('ALFKI')/Address/Country",
complex.getNavigationProperties().get("Country").getNavigationLink());
assertNotNull(complex.getNavigationProperties());
assertTrue(complex.getNavigationProperties().containsKey("Country"));
assertEquals("Customers('ALFKI')/Address/Country/$ref",
complex.getNavigationProperties().get("Country").getAssociationLink());
}
private void validateEntitySet(final EntitySet entitySet) {
validateEntitySet(entitySet, true);
}
private void validateEntitySet(final EntitySet entitySet, final boolean validateLinks) {
assertNotNull(entitySet);
assertEquals("http://host/service/$metadata#Customers/$entity", entitySet.getODataContext());
assertEquals(Long.valueOf(1), entitySet.getODataCount());
if (validateLinks) {
assertEquals("http://host/service/EntitySet?$skiptoken=342r89", entitySet.getODataNextLink());
assertNull(entitySet.getODataDeltaLink());
}
}
private InputStream getJson(final String filename) {
return JsonReaderTest.class.getResourceAsStream(filename);
}
}

View File

@ -0,0 +1,110 @@
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
package org.apache.olingo.consumer.core.testutil;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
/**
* @author SAP AG
*/
public class StringHelper {
public static String inputStreamToString(final InputStream in, final boolean preserveLineBreaks) throws IOException {
final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in, Charset.forName("UTF-8")));
final StringBuilder stringBuilder = new StringBuilder();
String line = null;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
if (preserveLineBreaks) {
stringBuilder.append("\n");
}
}
bufferedReader.close();
final String result = stringBuilder.toString();
return result;
}
public static String inputStreamToString(final InputStream in) throws IOException {
return inputStreamToString(in, false);
}
/**
* Encapsulate given content in an {@link InputStream} with charset <code>UTF-8</code>.
*
* @param content to encapsulate content
* @return content as stream
*/
public static InputStream encapsulate(final String content) {
try {
return encapsulate(content, "UTF-8");
} catch (UnsupportedEncodingException e) {
// we know that UTF-8 is supported
throw new RuntimeException("UTF-8 MUST be supported.", e);
}
}
/**
* Encapsulate given content in an {@link InputStream} with given charset.
*
* @param content to encapsulate content
* @param charset to be used charset
* @return content as stream
* @throws UnsupportedEncodingException if charset is not supported
*/
public static InputStream encapsulate(final String content, final String charset)
throws UnsupportedEncodingException {
return new ByteArrayInputStream(content.getBytes(charset));
}
/**
* Generate a string with given length containing random upper case characters ([A-Z]).
*
* @param len length of to generated string
* @return random upper case characters ([A-Z]).
*/
public static InputStream generateDataStream(final int len) {
return encapsulate(generateData(len));
}
/**
* Generate a string with given length containing random upper case characters ([A-Z]).
*
* @param len length of to generated string
* @return random upper case characters ([A-Z]).
*/
public static String generateData(final int len) {
StringBuilder b = new StringBuilder(len);
for (int j = 0; j < len; j++) {
char c = (char) (Math.random() * 26 + 65);
b.append(c);
}
return b.toString();
}
}

View File

@ -0,0 +1,8 @@
{
"Address": {
"Street": "Obere Str. 57",
"City": "Berlin",
"Region": null,
"PostalCode": "D-12209"
}
}

View File

@ -0,0 +1,22 @@
{
"odata.context": "http://host/service/$metadata#Customers/$entity",
"odata.id": "Customers('ALFKI')",
"odata.etag": "W/\"MjAxMy0wNS0yN1QxMTo1OFo=\"",
"odata.editLink": "Customers('ALFKI')",
"Orders@odata.navigationLink": "Customers('ALFKI')/Orders",
"Orders@odata.associationLink": "Customers('ALFKI')/Orders/$ref",
"ID": "ALFKI",
"CompanyName": "Alfreds Futterkiste",
"ContactName": "Maria Anders",
"ContactTitle": "Sales Representative",
"Phone": "030-0074321",
"Fax": "030-0076545",
"Address": {
"Street": "Obere Str. 57",
"City": "Berlin",
"Region": null,
"PostalCode": "D-12209",
"Country@odata.navigationLink": "Customers('ALFKI')/Address/Country",
"Country@odata.associationLink":"Customers('ALFKI')/Address/Country/$ref"
}
}

View File

@ -0,0 +1,29 @@
{
"odata.context": "http://host/service/$metadata#Customers/$entity",
"odata.count": 1,
"value": [
{
"odata.context": "http://host/service/$metadata#Customers/$entity",
"odata.id": "Customers('ALFKI')",
"odata.etag": "W/\"MjAxMy0wNS0yN1QxMTo1OFo=\"",
"odata.editLink": "Customers('ALFKI')",
"Orders@odata.navigationLink": "Customers('ALFKI')/Orders",
"Orders@odata.associationLink": "Customers('ALFKI')/Orders/$ref",
"ID": "ALFKI",
"CompanyName": "Alfreds Futterkiste",
"ContactName": "Maria Anders",
"ContactTitle": "Sales Representative",
"Phone": "030-0074321",
"Fax": "030-0076545",
"Address": {
"Street": "Obere Str. 57",
"City": "Berlin",
"Region": null,
"PostalCode": "D-12209",
"Country@odata.navigationLink": "Customers('ALFKI')/Address/Country",
"Country@odata.associationLink":"Customers('ALFKI')/Address/Country/$ref"
}
}
],
"odata.nextLink": "http://host/service/EntitySet?$skiptoken=342r89"
}

View File

@ -0,0 +1,49 @@
{
"odata.context": "http://host/service/$metadata#Customers/$entity",
"odata.count": 1,
"value": [
{
"odata.context": "http://host/service/$metadata#Customers/$entity",
"odata.id": "Customers('ALFKI')",
"odata.etag": "W/\"MjAxMy0wNS0yN1QxMTo1OFo=\"",
"odata.editLink": "Customers('ALFKI')",
"Orders@odata.navigationLink": "Customers('ALFKI')/Orders",
"Orders@odata.associationLink": "Customers('ALFKI')/Orders/$ref",
"ID": "ALFKI",
"CompanyName": "Alfreds Futterkiste",
"ContactName": "Maria Anders",
"ContactTitle": "Sales Representative",
"Phone": "030-0074321",
"Fax": "030-0076545",
"Address": {
"Street": "Obere Str. 57",
"City": "Berlin",
"Region": null,
"PostalCode": "D-12209",
"Country@odata.navigationLink": "Customers('ALFKI')/Address/Country",
"Country@odata.associationLink":"Customers('ALFKI')/Address/Country/$ref"
}
},
{
"odata.context": "http://host/service/$metadata#Customers/$entity",
"odata.id": "Customers('MUSKI')",
"odata.etag": "W/\"MjAxMy0wNS0yN1QxMTo1OFo=\"",
"odata.editLink": "Customers('MUSKI')",
"Orders@odata.navigationLink": "Customers('MUSKI')/Orders",
"Orders@odata.associationLink": "Customers('MUSKI')/Orders/$ref",
"ID": "MUSKI",
"CompanyName": "Mustermanns Futterkiste",
"ContactName": "Mustermann Max",
"ContactTitle": "Some Guy",
"Phone": "030-002222",
"Fax": "030-004444",
"Address": {
"Street": "Musterstrasse 42",
"City": "Musterstadt",
"Region": "SomeRegion",
"PostalCode": "D-42042"
}
}
],
"odata.nextLink": "http://host/service/EntitySet?$skiptoken=342r89"
}

View File

@ -0,0 +1,28 @@
{
"odata.context": "http://host/service/$metadata#Customers/$entity",
"odata.id": "Customers('ALFKI')",
"odata.etag": "W/\"MjAxMy0wNS0yN1QxMTo1OFo=\"",
"odata.editLink": "Customers('ALFKI')",
"Orders@odata.navigationLink": "Customers('ALFKI')/Orders",
"Orders@odata.associationLink": "Customers('ALFKI')/Orders/$ref",
"ID": "ALFKI",
"CompanyName": "Alfreds Futterkiste",
"ContactName": "Maria Anders",
"ContactTitle": "Sales Representative",
"Phone": "030-0074321",
"Fax": "030-0076545",
"Address": [ {
"Street": "Obere Str. 57",
"City": "Berlin",
"Region": null,
"PostalCode": "D-12209",
"Country@odata.navigationLink": "Customers('ALFKI')/Address/Country",
"Country@odata.associationLink":"Customers('ALFKI')/Address/Country/$ref"
}, {
"Street": "Musterstrasse 42",
"City": "Musterstadt",
"Region": "SomeRegion",
"PostalCode": "D-42042"
}
]
}

View File

@ -0,0 +1,16 @@
{
"odata.context": "http://host/service/$metadata#Customers/$entity", "odata.id": "Customers('ALFKI')",
"odata.etag": "W/\"MjAxMy0wNS0yN1QxMTo1OFo=\"",
"odata.editLink": "Customers('ALFKI')", "Orders@odata.navigationLink": "Customers('ALFKI')/Orders", "Orders@odata.associationLink": "Customers('ALFKI')/Orders/$ref", "ID": "ALFKI",
"CompanyName": "Alfreds Futterkiste",
"ContactName": "Maria Anders",
"ContactTitle": "Sales Representative",
"Phone": "030-0074321",
"Fax": "030-0076545",
"Address": {
"Street": "Obere Str. 57",
"City": "Berlin",
"Region": null,
"PostalCode": "D-12209",
"Country@odata.navigationLink": "Customers('ALFKI')/Address/Country", "Country@odata.associationLink":"Customers('ALFKI')/Address/Country/$ref",
} }

View File

@ -0,0 +1,3 @@
{
"NullValue" : null
}

View File

@ -0,0 +1,13 @@
{
"PhoneNumbers": [
{
"Number": "425-555-1212",
"Type": "Home"
}, {
"odata.type": "#Model.CellPhoneNumber",
"Number": "425-555-0178",
"Type": "Cell",
"Carrier": "Sprint"
}
]
}

View File

@ -0,0 +1,8 @@
{
"odata.context": "http://host/service/$metadata#Customers/$entity",
"EmailAddresses": [
"Julie@Swansworth.com",
"Julie.Swansworth@work.com"
]
}

View File

@ -53,6 +53,7 @@
<junit.version>4.10</junit.version>
<commonscodec.version>1.6</commonscodec.version>
<antlr.version>4.1</antlr.version>
<jackson.version>2.2.2</jackson.version>
</properties>
<dependencies>