/** * JSONオブジェクトの値を取得する. * * @param event JsonEvent * @param ees エンティティセット型 * @param name プロパティ名 * @param jsr JsonStreamReader * @param entry JsonEntry * @return JsonObjectPropertyValue */ protected JsonObjectPropertyValue getValue( JsonEvent event, EdmEntitySet ees, String name, JsonStreamReader jsr, JsonEntry entry) { JsonObjectPropertyValue rt = new JsonObjectPropertyValue(); ensureStartObject(event); event = jsr.nextEvent(); ensureStartProperty(event); // ComplexObjectであればエンティティタイプ定義からプロパティ定義を取得する EdmProperty eprop = entry.getEntityType().findProperty(name); if (eprop == null) { // プロパティがスキーマ定義上に存在しなければエラーとする throw DcCoreException.OData.REQUEST_FIELD_FORMAT_ERROR.params(name); } else { // スキーマ定義からComplexType定義を取得する EdmComplexType ct = metadata.findEdmComplexType(eprop.getType().getFullyQualifiedTypeName()); if (null != ct) { // ComplexTypeが存在する場合は、パースを実施してComplexTypeObjectを取得する Settings s = new Settings(version, metadata, entitySetName, entityKey, null, false, ct); DcJsonComplexObjectFormatParser cofp = new DcJsonComplexObjectFormatParser(s); rt.complexObject = cofp.parseSingleObject(jsr, event); } else { // ComplexTypeがスキーマ定義上に存在しなければエラーとする throw DcCoreException.OData.REQUEST_FIELD_FORMAT_ERROR.params(name); } } ensureEndProperty(jsr.nextEvent()); return rt; }
/** * JsonEntryをパースする. * * @param ees EdmEntitySet * @param jsr JsonStreamReader * @return JsonEntry */ protected JsonEntry parseEntry(EdmEntitySet ees, JsonStreamReader jsr) { JsonEntry entry = new JsonEntry(ees); entry.properties = new ArrayList<OProperty<?>>(); entry.links = new ArrayList<OLink>(); String name = ""; while (jsr.hasNext()) { JsonEvent event = jsr.nextEvent(); if (event.isStartProperty()) { try { name = event.asStartProperty().getName(); ees = addProperty(entry, ees, name, jsr); } catch (IllegalArgumentException e) { throw DcCoreException.OData.REQUEST_FIELD_FORMAT_ERROR.params(name).reason(e); } } else if (event.isEndObject()) { break; } } entry.oentity = toOEntity(ees, entry.getEntityType(), entry.getEntityKey(), entry.properties, entry.links); return entry; }
/** * ensureNext. * * @param jsr JsonStreamReader */ protected void ensureNext(JsonStreamReader jsr) { if (!jsr.hasNext()) { throw new IllegalArgumentException("no valid JSON format exepected at least one more event"); } }
/** * 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; }