[OLINGO-784] Prevent NPE in combination with typeinfo objects

This commit is contained in:
Christian Amend 2015-10-22 16:51:07 +02:00
parent 46cad03fed
commit 17e4a3aeff
13 changed files with 172 additions and 66 deletions

View File

@ -33,7 +33,7 @@ public class CsdlParameter extends CsdlAbstractEdmItem implements CsdlNamed, Csd
private String name;
private FullQualifiedName type;
private String type;
private boolean isCollection;
@ -74,7 +74,7 @@ public class CsdlParameter extends CsdlAbstractEdmItem implements CsdlNamed, Csd
* @return the type
*/
public String getType() {
return type.getFullQualifiedNameAsString();
return type;
}
/**
@ -83,7 +83,7 @@ public class CsdlParameter extends CsdlAbstractEdmItem implements CsdlNamed, Csd
* @return the type fQN
*/
public FullQualifiedName getTypeFQN() {
return type;
return new FullQualifiedName(type);
}
/**
@ -93,7 +93,7 @@ public class CsdlParameter extends CsdlAbstractEdmItem implements CsdlNamed, Csd
* @return the type
*/
public CsdlParameter setType(final String type) {
this.type = new FullQualifiedName(type);
this.type = type;
return this;
}
@ -104,7 +104,7 @@ public class CsdlParameter extends CsdlAbstractEdmItem implements CsdlNamed, Csd
* @return the type
*/
public CsdlParameter setType(final FullQualifiedName type) {
this.type = type;
this.type = type.getFullQualifiedNameAsString();
return this;
}

View File

@ -28,7 +28,7 @@ public class CsdlReturnType extends CsdlAbstractEdmItem {
private static final long serialVersionUID = 4816954124986010965L;
private FullQualifiedName type;
private String type;
private boolean isCollection;
@ -49,7 +49,7 @@ public class CsdlReturnType extends CsdlAbstractEdmItem {
* @return the type
*/
public String getType() {
return type.getFullQualifiedNameAsString();
return type;
}
/**
@ -58,7 +58,7 @@ public class CsdlReturnType extends CsdlAbstractEdmItem {
* @return the type fQN
*/
public FullQualifiedName getTypeFQN() {
return type;
return new FullQualifiedName(type);
}
/**
@ -68,7 +68,7 @@ public class CsdlReturnType extends CsdlAbstractEdmItem {
* @return the type
*/
public CsdlReturnType setType(final String type) {
this.type = new FullQualifiedName(type);
this.type = type;
return this;
}
@ -79,7 +79,7 @@ public class CsdlReturnType extends CsdlAbstractEdmItem {
* @return the type
*/
public CsdlReturnType setType(final FullQualifiedName type) {
this.type = type;
this.type = type.getFullQualifiedNameAsString();
return this;
}

View File

@ -40,7 +40,6 @@ import org.apache.olingo.commons.api.edm.FullQualifiedName;
public abstract class AbstractEdm implements Edm {
protected Map<String, EdmSchema> schemas;
protected List<EdmSchema> schemaList;
private final Map<FullQualifiedName, EdmEntityContainer> entityContainers =
@ -79,8 +78,7 @@ public abstract class AbstractEdm implements Edm {
private final Map<TargetQualifierMapKey, EdmAnnotations> annotationGroups =
Collections.synchronizedMap(new HashMap<TargetQualifierMapKey, EdmAnnotations>());
private Map<String, String> aliasToNamespaceInfo = Collections.synchronizedMap(new HashMap<String, String>());
private boolean aliasToNamespaceInfoCreated = false;
private Map<String, String> aliasToNamespaceInfo = null;
@Override
public List<EdmSchema> getSchemas() {
@ -98,18 +96,15 @@ public abstract class AbstractEdm implements Edm {
EdmSchema schema = schemas.get(namespace);
if (schema == null) {
if (!aliasToNamespaceInfoCreated) {
aliasToNamespaceInfo = createAliasToNamespaceInfo();
}
schema = schemas.get(aliasToNamespaceInfo.get(namespace));
}
return schema;
}
private void initSchemas() {
schemas = createSchemas();
aliasToNamespaceInfoCreated = true;
loadAliasToNamespaceInfo();
Map<String, EdmSchema> localSchemas = createSchemas();
schemas = Collections.synchronizedMap(localSchemas);
if (schemas == null) {
schemas = Collections.emptyMap();
@ -117,6 +112,11 @@ public abstract class AbstractEdm implements Edm {
schemaList = Collections.unmodifiableList(new ArrayList<EdmSchema>(schemas.values()));
}
private void loadAliasToNamespaceInfo() {
Map<String, String> localAliasToNamespaceInfo = createAliasToNamespaceInfo();
aliasToNamespaceInfo = Collections.synchronizedMap(localAliasToNamespaceInfo);
}
@Override
public EdmEntityContainer getEntityContainer() {
return getEntityContainer(null);
@ -311,8 +311,8 @@ public abstract class AbstractEdm implements Edm {
}
private FullQualifiedName resolvePossibleAlias(final FullQualifiedName namespaceOrAliasFQN) {
if (!aliasToNamespaceInfoCreated) {
aliasToNamespaceInfo = createAliasToNamespaceInfo();
if (aliasToNamespaceInfo == null) {
loadAliasToNamespaceInfo();
}
FullQualifiedName finalFQN = null;
if (namespaceOrAliasFQN != null) {

View File

@ -30,13 +30,11 @@ import org.apache.olingo.commons.api.edm.provider.CsdlParameter;
public class EdmParameterImpl extends AbstractEdmNamed implements EdmParameter, EdmElement {
private final CsdlParameter parameter;
private final EdmTypeInfo typeInfo;
private EdmType typeImpl;
public EdmParameterImpl(final Edm edm, final CsdlParameter parameter) {
super(edm, parameter.getName(), parameter);
this.parameter = parameter;
typeInfo = new EdmTypeInfo.Builder().setEdm(edm).setTypeExpression(parameter.getType()).build();
}
@Override
@ -77,9 +75,12 @@ public class EdmParameterImpl extends AbstractEdmNamed implements EdmParameter,
@Override
public EdmType getType() {
if (typeImpl == null) {
typeImpl = typeInfo.getType();
if (parameter.getType() == null) {
throw new EdmException("Parameter " + parameter.getName() + " must hava a full qualified type.");
}
typeImpl = new EdmTypeInfo.Builder().setEdm(edm).setTypeExpression(parameter.getType()).build().getType();
if (typeImpl == null) {
throw new EdmException("Cannot find type with name: " + typeInfo.getFullQualifiedName());
throw new EdmException("Cannot find type with name: " + parameter.getTypeFQN());
}
}

View File

@ -30,19 +30,22 @@ import org.apache.olingo.commons.api.edm.provider.CsdlProperty;
public class EdmPropertyImpl extends AbstractEdmNamed implements EdmProperty, EdmElement {
private final CsdlProperty property;
private final EdmTypeInfo typeInfo;
private EdmTypeInfo typeInfo;
private EdmType propertyType;
public EdmPropertyImpl(final Edm edm, final CsdlProperty property) {
super(edm, property.getName(), property);
this.property = property;
typeInfo = new EdmTypeInfo.Builder().setEdm(edm).setTypeExpression(property.getType().toString()).build();
}
@Override
public EdmType getType() {
if (propertyType == null) {
if (typeInfo == null) {
buildTypeInfo();
}
propertyType = typeInfo.getType();
if (propertyType == null) {
throw new EdmException("Cannot find type with name: " + typeInfo.getFullQualifiedName());
@ -52,6 +55,13 @@ public class EdmPropertyImpl extends AbstractEdmNamed implements EdmProperty, Ed
return propertyType;
}
private void buildTypeInfo() {
if (property.getType() == null) {
throw new EdmException("Property " + property.getName() + " must hava a full qualified type.");
}
typeInfo = new EdmTypeInfo.Builder().setEdm(edm).setTypeExpression(property.getType().toString()).build();
}
@Override
public boolean isCollection() {
return property.isCollection();
@ -104,6 +114,9 @@ public class EdmPropertyImpl extends AbstractEdmNamed implements EdmProperty, Ed
@Override
public boolean isPrimitive() {
if (typeInfo == null) {
buildTypeInfo();
}
return typeInfo.isPrimitiveType();
}
}

View File

@ -28,12 +28,12 @@ import org.apache.olingo.commons.api.edm.provider.CsdlReturnType;
public class EdmReturnTypeImpl implements EdmReturnType {
private final CsdlReturnType returnType;
private final EdmTypeInfo typeInfo;
private final Edm edm;
private EdmType typeImpl;
public EdmReturnTypeImpl(final Edm edm, final CsdlReturnType returnType) {
this.edm = edm;
this.returnType = returnType;
typeInfo = new EdmTypeInfo.Builder().setEdm(edm).setTypeExpression(returnType.getType()).build();
}
@Override
@ -69,9 +69,12 @@ public class EdmReturnTypeImpl implements EdmReturnType {
@Override
public EdmType getType() {
if (typeImpl == null) {
typeImpl = typeInfo.getType();
if (returnType.getType() == null) {
throw new EdmException("Return types must hava a full qualified type.");
}
typeImpl = new EdmTypeInfo.Builder().setEdm(edm).setTypeExpression(returnType.getType()).build().getType();
if (typeImpl == null) {
throw new EdmException("Cannot find type with name: " + typeInfo.getFullQualifiedName());
throw new EdmException("Cannot find type with name: " + returnType.getType());
}
}

View File

@ -30,23 +30,19 @@ import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.TargetType;
import org.apache.olingo.commons.api.edm.geo.SRID;
import org.apache.olingo.commons.api.edm.provider.CsdlTerm;
import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
public class EdmTermImpl extends AbstractEdmNamed implements EdmTerm {
private final CsdlTerm term;
private final FullQualifiedName fqn;
private final EdmTypeInfo typeInfo;
private EdmType termType;
private EdmTerm baseTerm;
private List<TargetType> appliesTo;
public EdmTermImpl(final Edm edm, final String namespace, final CsdlTerm term) {
super(edm, term.getName(), term);
this.term = term;
fqn = new FullQualifiedName(namespace, term.getName());
typeInfo = new EdmTypeInfo.Builder().setEdm(edm).setTypeExpression(term.getType()).build();
}
@Override
@ -57,22 +53,14 @@ public class EdmTermImpl extends AbstractEdmNamed implements EdmTerm {
@Override
public EdmType getType() {
if (termType == null) {
termType = typeInfo.isPrimitiveType()
? EdmPrimitiveTypeFactory.getInstance(typeInfo.getPrimitiveTypeKind())
: typeInfo.isTypeDefinition()
? typeInfo.getTypeDefinition()
: typeInfo.isEnumType()
? typeInfo.getEnumType()
: typeInfo.isComplexType()
? typeInfo.getComplexType()
: typeInfo.isEntityType()
? typeInfo.getEntityType()
: null;
if (term.getType() == null) {
throw new EdmException("Terms must hava a full qualified type.");
}
termType = new EdmTypeInfo.Builder().setEdm(edm).setTypeExpression(term.getType()).build().getType();
if (termType == null) {
throw new EdmException("Cannot find type with name: " + typeInfo.getFullQualifiedName());
throw new EdmException("Cannot find type with name: " + term.getType());
}
}
return termType;
}

View File

@ -20,10 +20,14 @@ package org.apache.olingo.server.core.edm.provider;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
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 static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmException;
import org.apache.olingo.commons.api.edm.EdmParameter;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
@ -42,6 +46,29 @@ import org.junit.Test;
public class EdmParameterImplTest {
@Test
public void initialParameter() {
EdmParameterImpl parameter = new EdmParameterImpl(mock(Edm.class), new CsdlParameter());
assertTrue(parameter.isNullable());
assertFalse(parameter.isCollection());
assertNull(parameter.getName());
assertNull(parameter.getMapping());
assertNull(parameter.getMaxLength());
assertNull(parameter.getPrecision());
assertNull(parameter.getScale());
assertNull(parameter.getSrid());
assertNotNull(parameter.getAnnotations());
assertTrue(parameter.getAnnotations().isEmpty());
try {
parameter.getType();
fail("EdmException expected");
} catch (EdmException e) {
assertEquals("Parameter null must hava a full qualified type.", e.getMessage());
}
}
@Test
public void getTypeReturnsPrimitiveType() {
EdmProviderImpl edm = new EdmProviderImpl(mock(CsdlEdmProvider.class));

View File

@ -20,12 +20,14 @@ package org.apache.olingo.server.core.edm.provider;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
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 static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmException;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
@ -44,6 +46,36 @@ import org.junit.Test;
public class EdmPropertyImplTest {
@Test
public void initialProperty() {
EdmProperty property = new EdmPropertyImpl(mock(Edm.class), new CsdlProperty());
assertTrue(property.isNullable());
assertFalse(property.isCollection());
assertNull(property.getName());
assertNull(property.getMapping());
assertNull(property.getMaxLength());
assertNull(property.getPrecision());
assertNull(property.getScale());
assertNull(property.getSrid());
assertNotNull(property.getAnnotations());
assertTrue(property.getAnnotations().isEmpty());
try {
property.getType();
fail("EdmException expected");
} catch (EdmException e) {
assertEquals("Property null must hava a full qualified type.", e.getMessage());
}
try {
property.isPrimitive();
fail("EdmException expected");
} catch (EdmException e) {
assertEquals("Property null must hava a full qualified type.", e.getMessage());
}
}
@Test
public void getTypeReturnsPrimitiveType() {
EdmProviderImpl edm = new EdmProviderImpl(mock(CsdlEdmProvider.class));

View File

@ -22,9 +22,11 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmComplexType;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmEnumType;
@ -42,6 +44,24 @@ import org.junit.Test;
public class EdmReturnTypeImplTest {
@Test
public void initialReturnType() {
EdmReturnType returnType = new EdmReturnTypeImpl(mock(Edm.class), new CsdlReturnType());
assertTrue(returnType.isNullable());
assertNull(returnType.getMaxLength());
assertNull(returnType.getPrecision());
assertNull(returnType.getScale());
assertNull(returnType.getSrid());
try {
returnType.getType();
fail("EdmException expected");
} catch (EdmException e) {
assertEquals("Return types must hava a full qualified type.", e.getMessage());
}
}
@Test
public void primitiveReturnType() {
CsdlReturnType providerType = new CsdlReturnType().setType(new FullQualifiedName("Edm", "String"));

View File

@ -25,6 +25,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.olingo.commons.api.edm.Edm;
@ -193,7 +194,6 @@ public class EdmSchemaImplTest {
}
}
@Test
public void getContainer() {
EdmEntityContainer container = schema.getEntityContainer();
@ -301,7 +301,7 @@ public class EdmSchemaImplTest {
@Override
public List<CsdlAliasInfo> getAliasInfos() throws ODataException {
throw new RuntimeException("Provider must not be called in the schema case");
return Collections.emptyList();
}
@Override

View File

@ -54,6 +54,28 @@ public class EdmTermImplTest {
private EdmTerm initialTerm;
private EdmTerm derivedTerm;
@Test
public void initialTerm() {
EdmTerm term = new EdmTermImpl(mock(Edm.class), "namespace", new CsdlTerm());
assertTrue(term.isNullable());
assertNull(term.getName());
assertNull(term.getMaxLength());
assertNull(term.getPrecision());
assertNull(term.getScale());
assertNull(term.getSrid());
assertNotNull(term.getAnnotations());
assertTrue(term.getAnnotations().isEmpty());
assertNotNull(term.getFullQualifiedName());
try {
term.getType();
fail("EdmException expected");
} catch (EdmException e) {
assertEquals("Terms must hava a full qualified type.", e.getMessage());
}
}
@Before
public void setupTypes() throws Exception {
CsdlEdmProvider provider = mock(CsdlEdmProvider.class);

View File

@ -190,19 +190,19 @@ public class ContainerProvider {
Arrays
.asList(
new CsdlAnnotation()
.setTerm("Core.Description")
.setTerm("Org.OData.Core.V1.Description")
.setExpression(
new CsdlConstantExpression(CsdlConstantExpression.ConstantExpressionType.String)
.setValue("Contains entities with collection of each primitive type")),
new CsdlAnnotation()
.setTerm("Core.LongDescription")
.setTerm("Org.OData.Core.V1.LongDescription")
.setQualifier("EnabledForEntitySet")
.setExpression(
new CsdlConstantExpression(CsdlConstantExpression.ConstantExpressionType.String)
.setValue("System Query Options: $filter, $count, $orderby, "
+ "$skip, $top, $expand, $select, $format; Operations: Create, Read")),
new CsdlAnnotation()
.setTerm("Core.LongDescription")
.setTerm("Org.OData.Core.V1.LongDescription")
.setQualifier("EnabledForEntity")
.setExpression(
new CsdlConstantExpression(CsdlConstantExpression.ConstantExpressionType.String)