static OProperty<?> buildPropery( String propName, EdmType type, Object value, String invalidCharacterReplacement) throws TransformationException, SQLException, IOException { if (!(type instanceof EdmSimpleType)) { if (type instanceof EdmCollectionType) { EdmCollectionType collectionType = (EdmCollectionType) type; EdmType componentType = collectionType.getItemType(); Builder<OObject> b = OCollections.newBuilder(componentType); if (value instanceof Array) { value = ((Array) value).getArray(); } int length = java.lang.reflect.Array.getLength(value); for (int i = 0; i < length; i++) { Object o = java.lang.reflect.Array.get(value, i); OProperty p = buildPropery("x", componentType, o, invalidCharacterReplacement); if (componentType instanceof EdmSimpleType) { b.add(OSimpleObjects.create((EdmSimpleType) componentType, p.getValue())); } else { throw new AssertionError("Multi-dimensional arrays are not yet supported."); // b.add((OCollection)p.getValue()); } } return OProperties.collection(propName, collectionType, b.build()); } throw new AssertionError("non-simple types are not yet supported"); } EdmSimpleType expectedType = (EdmSimpleType) type; if (value == null) { return OProperties.null_(propName, expectedType); } Class<?> sourceType = DataTypeManager.getRuntimeType(value.getClass()); Class<?> targetType = DataTypeManager.getDataTypeClass( ODataTypeManager.teiidType(expectedType.getFullyQualifiedTypeName())); if (sourceType != targetType) { Transform t = DataTypeManager.getTransform(sourceType, targetType); if (t == null && BlobType.class == targetType) { if (sourceType == ClobType.class) { return OProperties.binary(propName, ClobType.getString((Clob) value).getBytes()); } if (sourceType == SQLXML.class) { return OProperties.binary(propName, ((SQLXML) value).getString().getBytes()); } } value = DataTypeManager.convertToRuntimeType(value, true); value = t != null ? t.transform(value, targetType) : value; value = replaceInvalidCharacters(expectedType, value, invalidCharacterReplacement); if (value instanceof BinaryType) { value = ((BinaryType) value).getBytesDirect(); } return OProperties.simple(propName, expectedType, value); } value = replaceInvalidCharacters(expectedType, value, invalidCharacterReplacement); return OProperties.simple(propName, expectedType, value); }
@SuppressWarnings("unchecked") protected void writeProperty( XMLWriter2 writer, String name, EdmType type, Object value, boolean isDocumentElement, boolean writeType) { writer.startElement(new QName2(d, name, "d")); if (isDocumentElement) { writer.writeNamespace("m", m); writer.writeNamespace("d", d); } String sValue = null; if (!type.isSimple()) { if (writeType) { String typename = type.getFullyQualifiedTypeName(); if (value instanceof OCollection) { EdmCollectionType collectionType = (EdmCollectionType) type; typename = "Bag(" + collectionType.getItemType().getFullyQualifiedTypeName() + ")"; } writer.writeAttribute(new QName2(m, "type", "m"), typename); } // complex or collection if (value instanceof OCollection) { writeCollection(writer, name, (OCollection<? extends OObject>) value); } else if (value instanceof OComplexObject) { writeProperties(writer, ((OComplexObject) value).getProperties()); } else { // deprecated form of a complex object. List<OProperty<?>> complexProperties = (List<OProperty<?>>) value; if (complexProperties != null) { writeProperties(writer, complexProperties); } } } else { // simple // write the type attribute if requested and not a string if (writeType && type != EdmSimpleType.STRING) { writer.writeAttribute(new QName2(m, "type", "m"), type.getFullyQualifiedTypeName()); } // now write the value if (type == EdmSimpleType.INT32) { if (value != null) { sValue = value.toString(); } } else if (type == EdmSimpleType.INT16) { if (value != null) { sValue = value.toString(); } } else if (type == EdmSimpleType.INT64) { if (value != null) { sValue = value.toString(); } } else if (type == EdmSimpleType.BOOLEAN) { if (value != null) { sValue = value.toString(); } } else if (type == EdmSimpleType.BYTE) { if (value != null) { sValue = value.toString(); } } else if (type == EdmSimpleType.SBYTE) { if (value != null) { sValue = value.toString(); } } else if (type == EdmSimpleType.DECIMAL) { if (value != null) { sValue = ((BigDecimal) value).toPlainString(); } } else if (type == EdmSimpleType.SINGLE) { if (value != null) { sValue = value.toString(); } } else if (type == EdmSimpleType.DOUBLE) { if (value != null) { sValue = value.toString(); } } else if (type == EdmSimpleType.STRING) { if (value != null) { sValue = value.toString(); } } else if (type == EdmSimpleType.DATETIME) { if (value != null) sValue = InternalUtil.formatDateTimeForXml((LocalDateTime) value); } else if (type == EdmSimpleType.BINARY) { byte[] bValue = (byte[]) value; if (value != null) { sValue = Base64.encodeBase64String(bValue); } } else if (type == EdmSimpleType.GUID) { if (value != null) { sValue = value.toString(); } } else if (type == EdmSimpleType.TIME) { if (value != null) { sValue = InternalUtil.formatTimeForXml((LocalTime) value); } } else if (type == EdmSimpleType.DATETIMEOFFSET) { // Edm.DateTimeOffset '-'? yyyy '-' mm '-' dd 'T' hh ':' mm // ':' ss ('.' s+)? (zzzzzz)? if (value != null) { sValue = InternalUtil.formatDateTimeOffsetForXml((DateTime) value); } } else { throw new UnsupportedOperationException("Implement " + type); } } if (value == null) { writer.writeAttribute(new QName2(m, "null", "m"), "true"); } else if (sValue != null) { writer.writeText(sValue); } writer.endElement(name); }
private static void buildFunctionImports(MetadataStore metadataStore, List<Builder> edmSchemas) { for (Schema schema : metadataStore.getSchemaList()) { EdmSchema.Builder odataSchema = findSchema(edmSchemas, schema.getName()); EdmEntityContainer.Builder entityContainer = findEntityContainer(edmSchemas, schema.getName()); // procedures for (Procedure proc : schema.getProcedures().values()) { EdmFunctionImport.Builder edmProcedure = EdmFunctionImport.newBuilder(); edmProcedure.setName(proc.getName()); String httpMethod = "POST"; for (ProcedureParameter pp : proc.getParameters()) { if (pp.getName().equals("return")) { httpMethod = "GET"; edmProcedure.setReturnType( ODataTypeManager.odataType(pp.getDatatype().getRuntimeTypeName())); continue; } EdmFunctionParameter.Builder param = EdmFunctionParameter.newBuilder(); param.setName(pp.getName()); param.setType(ODataTypeManager.odataType(pp.getDatatype().getRuntimeTypeName())); if (pp.getType() == ProcedureParameter.Type.In) { param.setMode(Mode.In); } else if (pp.getType() == ProcedureParameter.Type.InOut) { param.setMode(Mode.InOut); } else if (pp.getType() == ProcedureParameter.Type.Out) { param.setMode(Mode.Out); } param.setNullable(pp.getNullType() == NullType.Nullable); edmProcedure.addParameters(param); } // add a complex type for return resultset. ColumnSet<Procedure> returnColumns = proc.getResultSet(); if (returnColumns != null) { httpMethod = "GET"; EdmComplexType.Builder complexType = EdmComplexType.newBuilder(); complexType.setName(proc.getName() + "_" + returnColumns.getName()); complexType.setNamespace(schema.getName()); for (Column c : returnColumns.getColumns()) { EdmProperty.Builder property = EdmProperty.newBuilder(c.getName()) .setType(ODataTypeManager.odataType(c.getDatatype().getRuntimeTypeName())) .setNullable(c.getNullType() == NullType.Nullable); if (c.getDatatype() .getRuntimeTypeName() .equals(DataTypeManager.DefaultDataTypes.STRING)) { property .setFixedLength(c.isFixedLength()) .setMaxLength(c.getLength()) .setUnicode(true); } complexType.addProperties(property); } odataSchema.addComplexTypes(complexType); edmProcedure.setIsCollection(true); edmProcedure.setReturnType( EdmCollectionType.newBuilder() .setCollectionType(complexType) .setKind(CollectionKind.Collection)); } edmProcedure.setHttpMethod(httpMethod); entityContainer.addFunctionImports(edmProcedure); } } }
private void resolve() { final Map<String, EdmEntityType.Builder> allEetsByFQName = Enumerable.create(dataServices.getEntityTypes()) .toMap(EdmEntityType.Builder.func1_getFullyQualifiedTypeName()); final Map<String, EdmEntityType.Builder> allEetsByFQAliasName = Enumerable.create(dataServices.getEntityTypes()) .where(EdmEntityType.Builder.pred1_hasAlias()) .toMap(EdmEntityType.Builder.func1_getFQAliasName()); final Map<String, EdmAssociation.Builder> allEasByFQName = Enumerable.create(dataServices.getAssociations()) .toMap(EdmAssociation.Builder.func1_getFQNamespaceName()); for (EdmSchema.Builder edmSchema : dataServices.getSchemas()) { // resolve associations for (int i = 0; i < edmSchema.getAssociations().size(); i++) { EdmAssociation.Builder tmpAssociation = edmSchema.getAssociations().get(i); tmpAssociation .getEnd1() .setType(allEetsByFQName.get(tmpAssociation.getEnd1().getTypeName())); tmpAssociation .getEnd2() .setType(allEetsByFQName.get(tmpAssociation.getEnd2().getTypeName())); } // resolve navproperties for (EdmEntityType.Builder eet : edmSchema.getEntityTypes()) { List<EdmNavigationProperty.Builder> navProps = eet.getNavigationProperties(); for (int i = 0; i < navProps.size(); i++) { final EdmNavigationProperty.Builder tmp = navProps.get(i); final EdmAssociation.Builder ea = allEasByFQName.get(tmp.getRelationshipName()); if (ea == null) throw new IllegalArgumentException( "Invalid relationship name " + tmp.getRelationshipName()); List<EdmAssociationEnd.Builder> finalEnds = Enumerable.create(tmp.getFromRoleName(), tmp.getToRoleName()) .select( new Func1<String, EdmAssociationEnd.Builder>() { public EdmAssociationEnd.Builder apply(String input) { if (ea.getEnd1().getRole().equals(input)) return ea.getEnd1(); if (ea.getEnd2().getRole().equals(input)) return ea.getEnd2(); throw new IllegalArgumentException("Invalid role name " + input); } }) .toList(); tmp.setRelationship(ea).setFromTo(finalEnds.get(0), finalEnds.get(1)); } } // resolve entitysets for (EdmEntityContainer.Builder edmEntityContainer : edmSchema.getEntityContainers()) { for (int i = 0; i < edmEntityContainer.getEntitySets().size(); i++) { final EdmEntitySet.Builder tmpEes = edmEntityContainer.getEntitySets().get(i); EdmEntityType.Builder eet = allEetsByFQName.get(tmpEes.getEntityTypeName()); if (eet == null) eet = allEetsByFQAliasName.get(tmpEes.getEntityTypeName()); if (eet == null) throw new IllegalArgumentException("Invalid entity type " + tmpEes.getEntityTypeName()); edmEntityContainer .getEntitySets() .set( i, EdmEntitySet.newBuilder() .setName(tmpEes.getName()) .setEntityType(eet) .setAnnotationElements(tmpEes.getAnnotationElements()) .setAnnotations(tmpEes.getAnnotations())); } } // resolve associationsets for (final EdmEntityContainer.Builder edmEntityContainer : edmSchema.getEntityContainers()) { for (int i = 0; i < edmEntityContainer.getAssociationSets().size(); i++) { final EdmAssociationSet.Builder tmpEas = edmEntityContainer.getAssociationSets().get(i); final EdmAssociation.Builder ea = allEasByFQName.get(tmpEas.getAssociationName()); List<EdmAssociationSetEnd.Builder> finalEnds = Enumerable.create(tmpEas.getEnd1(), tmpEas.getEnd2()) .select( new Func1<EdmAssociationSetEnd.Builder, EdmAssociationSetEnd.Builder>() { public EdmAssociationSetEnd.Builder apply( final EdmAssociationSetEnd.Builder input) { EdmAssociationEnd.Builder eae = ea.getEnd1().getRole().equals(input.getRoleName()) ? ea.getEnd1() : ea.getEnd2().getRole().equals(input.getRoleName()) ? ea.getEnd2() : null; if (eae == null) throw new IllegalArgumentException( "Invalid role name " + input.getRoleName()); EdmEntitySet.Builder ees = Enumerable.create(edmEntityContainer.getEntitySets()) .first( OPredicates.nameEquals( EdmEntitySet.Builder.class, input.getEntitySetName())); return EdmAssociationSetEnd.newBuilder() .setRole(eae) .setEntitySet(ees) .setAnnotationElements(input.getAnnotationElements()) .setAnnotations(input.getAnnotations()); } }) .toList(); tmpEas.setAssociation(ea).setEnds(finalEnds.get(0), finalEnds.get(1)); } } // resolve functionimports for (final EdmEntityContainer.Builder edmEntityContainer : edmSchema.getEntityContainers()) { for (int i = 0; i < edmEntityContainer.getFunctionImports().size(); i++) { final EdmFunctionImport.Builder tmpEfi = edmEntityContainer.getFunctionImports().get(i); EdmEntitySet.Builder ees = Enumerable.create(edmEntityContainer.getEntitySets()) .firstOrNull( new Predicate1<EdmEntitySet.Builder>() { public boolean apply(EdmEntitySet.Builder input) { return input.getName().equals(tmpEfi.getEntitySetName()); } }); EdmType.Builder<?, ?> typeBuilder = null; if (tmpEfi.getReturnTypeName() != null) { typeBuilder = dataServices.resolveType(tmpEfi.getReturnTypeName()); if (typeBuilder == null) throw new RuntimeException("Edm-type not found: " + tmpEfi.getReturnTypeName()); if (tmpEfi.isCollection()) { typeBuilder = EdmCollectionType.newBuilder() .setKind(CollectionKind.Collection) .setCollectionType(typeBuilder); } } edmEntityContainer .getFunctionImports() .set( i, EdmFunctionImport.newBuilder() .setName(tmpEfi.getName()) .setEntitySet(ees) .setReturnType(typeBuilder) .setHttpMethod(tmpEfi.getHttpMethod()) .addParameters(tmpEfi.getParameters()) .setAnnotationElements(tmpEfi.getAnnotationElements()) .setAnnotations(tmpEfi.getAnnotations())); } } // resolve type hierarchy for (Entry<String, EdmEntityType.Builder> entry : allEetsByFQName.entrySet()) { String baseTypeName = entry.getValue().getFQBaseTypeName(); if (baseTypeName != null) { EdmEntityType.Builder baseType = allEetsByFQName.get(baseTypeName); if (baseType == null) { throw new IllegalArgumentException("Invalid baseType: " + baseTypeName); } entry.getValue().setBaseType(baseType); } } } }