private static void writeProperties(Iterable<EdmProperty> properties, XMLWriter2 writer) { for (EdmProperty prop : properties) { writer.startElement(new QName2("Property")); writer.writeAttribute("Name", prop.getName()); writer.writeAttribute("Type", prop.getType().getFullyQualifiedTypeName()); writer.writeAttribute("Nullable", Boolean.toString(prop.isNullable())); if (prop.getMaxLength() != null) { writer.writeAttribute("MaxLength", Integer.toString(prop.getMaxLength())); } if (!prop.getCollectionKind().equals(CollectionKind.NONE)) { writer.writeAttribute("CollectionKind", prop.getCollectionKind().toString()); } if (prop.getDefaultValue() != null) { writer.writeAttribute("DefaultValue", prop.getDefaultValue()); } if (prop.getPrecision() != null) { writer.writeAttribute("Precision", Integer.toString(prop.getPrecision())); } if (prop.getScale() != null) { writer.writeAttribute("Scale", Integer.toString(prop.getPrecision())); } writeAnnotationAttributes(prop, writer); writeAnnotationElements(prop, writer); writer.endElement("Property"); } }
/** * adds the property. This property can be a navigation property too. In this case a link will be * added. If it's the meta data the information will be added to the entry too. * * @param entry JsonEntry * @param ees EdmEntitySet * @param name PropertyName * @param jsr JsonStreamReader * @return EdmEntitySet */ protected EdmEntitySet addProperty( JsonEntry entry, EdmEntitySet ees, String name, JsonStreamReader jsr) { JsonEvent event = jsr.nextEvent(); if (event.isEndProperty()) { // scalar property EdmProperty ep = entry.getEntityType().findProperty(name); if (ep == null) { // OpenEntityTypeの場合は、プロパティを追加する NamespacedAnnotation<?> openType = findAnnotation(ees.getType(), null, Edm.EntityType.OpenType); if (openType != null && openType.getValue() == "true") { Object propValue = null; try { propValue = event.asEndProperty().getObject(); } catch (NumberFormatException e) { throw DcCoreException.OData.REQUEST_FIELD_FORMAT_ERROR.params(name).reason(e); } // 型によって登録するEntityPropertyを変更する if (propValue instanceof Boolean) { entry.properties.add( JsonTypeConverter.parse( name, (EdmSimpleType<?>) EdmSimpleType.BOOLEAN, propValue.toString())); } else if (propValue instanceof Double) { entry.properties.add( JsonTypeConverter.parse( name, (EdmSimpleType<?>) EdmSimpleType.DOUBLE, propValue.toString())); } else { if (propValue == null) { entry.properties.add( JsonTypeConverter.parse(name, (EdmSimpleType<?>) EdmSimpleType.STRING, null)); } else { entry.properties.add( JsonTypeConverter.parse( name, (EdmSimpleType<?>) EdmSimpleType.STRING, propValue.toString())); } } } else { throw DcCoreException.OData.FIELED_INVALID_ERROR.params( "unknown property " + name + " for " + entry.getEntityType().getName()); } } else { // StaticPropertyの値チェック String propValue = event.asEndProperty().getValue(); if (propValue != null) { EdmType type = ep.getType(); if (type.equals(EdmSimpleType.BOOLEAN) && !ODataUtils.validateBoolean(propValue)) { throw DcCoreException.OData.REQUEST_FIELD_FORMAT_ERROR.params(name); } else if (type.equals(EdmSimpleType.STRING) && !ODataUtils.validateString(propValue)) { throw DcCoreException.OData.REQUEST_FIELD_FORMAT_ERROR.params(name); } else if (type.equals(EdmSimpleType.DATETIME)) { if (!ODataUtils.validateDateTime(propValue)) { throw DcCoreException.OData.REQUEST_FIELD_FORMAT_ERROR.params(name); } if (Common.SYSUTCDATETIME.equals(propValue)) { String crrTime = String.valueOf(getCurrentTimeMillis()); propValue = String.format("/Date(%s)/", crrTime); } } else if (type.equals(EdmSimpleType.SINGLE) && !ODataUtils.validateSingle(propValue)) { throw DcCoreException.OData.REQUEST_FIELD_FORMAT_ERROR.params(name); } else if (type.equals(EdmSimpleType.INT32) && !ODataUtils.validateInt32(propValue)) { throw DcCoreException.OData.REQUEST_FIELD_FORMAT_ERROR.params(name); } else if (type.equals(EdmSimpleType.DOUBLE) && !ODataUtils.validateDouble(propValue)) { throw DcCoreException.OData.REQUEST_FIELD_FORMAT_ERROR.params(name); } } if (ep.getType().isSimple()) { // シンプル型(文字列や数値など)であればプロパティに追加する entry.properties.add( JsonTypeConverter.parse(name, (EdmSimpleType<?>) ep.getType(), propValue)); } else { if (propValue == null) { // ComplexType型で、値がnullの場合はエラーにしない entry.properties.add( JsonTypeConverter.parse(name, (EdmSimpleType<?>) EdmSimpleType.STRING, null)); } else { // ComplexType型で、ComplexType型以外の値が指定された場合("aaa")はエラーとする throw DcCoreException.OData.REQUEST_FIELD_FORMAT_ERROR.params(name); } } } } else if (event.isStartObject()) { // JSONオブジェクトの場合は値を取得する JsonObjectPropertyValue val = getValue(event, ees, name, jsr, entry); if (val.complexObject != null) { // ComplexTypeデータであればプロパティに追加する entry.properties.add( OProperties.complex( name, (EdmComplexType) val.complexObject.getType(), val.complexObject.getProperties())); } else { // ComplexTypeデータ以外はエラーとする throw DcCoreException.OData.REQUEST_FIELD_FORMAT_ERROR.params(name); } } else if (event.isStartArray()) { // 配列オブジェクトの場合 JsonObjectPropertyValue val = new JsonObjectPropertyValue(); // スキーマ定義が存在してCollectionKindがNoneでなければ、配列としてパースする EdmProperty eprop = entry.getEntityType().findProperty(name); if (null != eprop && eprop.getCollectionKind() != CollectionKind.NONE) { val.collectionType = new EdmCollectionType(eprop.getCollectionKind(), eprop.getType()); DcJsonCollectionFormatParser cfp = new DcJsonCollectionFormatParser(val.collectionType, this.metadata, name); val.collection = cfp.parseCollection(jsr); } // パースに成功した場合は、プロパティに追加する if (val.collectionType != null && val.collection != null) { entry.properties.add(OProperties.collection(name, val.collectionType, val.collection)); } else { throw DcCoreException.OData.REQUEST_FIELD_FORMAT_ERROR.params(name); } } else { throw DcCoreException.OData.INVALID_TYPE_ERROR.params(name); } return ees; }