/** * Create an OEntityKey instance for the specified entity id * * @param edmDataServices edmDataServices * @param entity Entity set name * @param id Id * @return An OEntityKey instance * @throws Exception Error creating key */ public static OEntityKey createEntityKey( EdmDataServices edmDataServices, String entitySetName, String id) throws Exception { // Lookup type of entity key (simple keys only) String keyType = null; EdmEntitySet entitySet = edmDataServices.getEdmEntitySet(entitySetName); if (entitySet != null) { EdmEntityType entityType = entitySet.getType(); List<String> keys = entityType.getKeys(); if (keys.size() == 1) { EdmProperty prop = entityType.findDeclaredProperty(keys.get(0)); if (prop != null && prop.getType() != null) { keyType = prop.getType().getFullyQualifiedTypeName(); } } } assert (keyType != null) : "Should not be possible to get this far and find no key type"; // Create an entity key OEntityKey key = null; try { if (keyType.equals("Edm.Int64")) { key = OEntityKey.parse(id); } else if (keyType.equals("Edm.Int32")) { key = OEntityKey.parse(id); } else if (keyType.equals("Edm.DateTime")) { key = OEntityKey.parse(id); } else if (keyType.equals("Edm.Time")) { key = OEntityKey.parse(id); } else if (keyType.equals("Edm.String")) { key = OEntityKey.parse(id); } } catch (Exception e) { logger.warn( "Entity key type " + keyType + " is not supported by CommandHelper, trying OEntityKey.parse"); } // could not parse the key, have one last attempt with OEntityKey create if (key == null) { try { if (keyType.equals("Edm.Int64")) { key = OEntityKey.create(Long.parseLong(id)); } else if (keyType.equals("Edm.Int32")) { key = OEntityKey.create(Integer.parseInt(id)); } else { key = OEntityKey.create(id); } } catch (Exception e) { logger.error("OEntityKey.parse failed to parse id [" + id + "]"); } } if (key == null) throw new Exception("Entity key type " + id + " is not supported."); return key; }
/** * 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; }
/* * Create a property with vocabulary term from the Edmx property */ public static EMProperty createEMProperty(EdmProperty property) { EMProperty emProperty = new EMProperty(property.getName()); if (property.isNullable()) { emProperty.addVocabularyTerm(new EMTerm(TermMandatory.TERM_NAME, "true")); } // Set the value type vocabulary term EdmType type = property.getType(); if (type.equals(EdmSimpleType.DATETIME)) { emProperty.addVocabularyTerm(new EMTerm(TermValueType.TERM_NAME, TermValueType.TIMESTAMP)); } else if (type.equals(EdmSimpleType.TIME)) { emProperty.addVocabularyTerm(new EMTerm(TermValueType.TERM_NAME, TermValueType.TIME)); } else if (type.equals(EdmSimpleType.INT64) || type.equals(EdmSimpleType.INT32) || type.equals(EdmSimpleType.INT16)) { emProperty.addVocabularyTerm( new EMTerm(TermValueType.TERM_NAME, TermValueType.INTEGER_NUMBER)); } else if (type.equals(EdmSimpleType.SINGLE) || type.equals(EdmSimpleType.DOUBLE) || type.equals(EdmSimpleType.DECIMAL)) { emProperty.addVocabularyTerm(new EMTerm(TermValueType.TERM_NAME, TermValueType.NUMBER)); } else if (type.equals(EdmSimpleType.BOOLEAN)) { emProperty.addVocabularyTerm(new EMTerm(TermValueType.TERM_NAME, TermValueType.BOOLEAN)); } return emProperty; }
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; }
@Override public BaseResponse executeCall(String sql, List<SQLParam> parameters, EdmType returnType) { ConnectionImpl connection = null; try { LogManager.logDetail(LogConstants.CTX_ODATA, "Teiid-Query:", sql); // $NON-NLS-1$ connection = getConnection(); final CallableStatementImpl stmt = connection.prepareCall(sql); int i = 1; if (returnType != null && returnType.isSimple()) { stmt.registerOutParameter( i++, JDBCSQLTypeInfo.getSQLType( ODataTypeManager.teiidType(returnType.getFullyQualifiedTypeName()))); } if (!parameters.isEmpty()) { for (SQLParam param : parameters) { stmt.setObject(i++, param.value, param.sqlType); } } boolean results = stmt.execute(); if (results) { final ResultSet rs = stmt.getResultSet(); OCollection.Builder resultRows = OCollections.newBuilder( (EdmComplexType) ((EdmCollectionType) returnType).getItemType()); while (rs.next()) { int idx = 1; List<OProperty<?>> row = new ArrayList<OProperty<?>>(); Iterator<EdmProperty> props = ((EdmComplexType) ((EdmCollectionType) returnType).getItemType()) .getProperties() .iterator(); while (props.hasNext()) { EdmProperty prop = props.next(); row.add( buildPropery( prop.getName(), prop.getType(), rs.getObject(idx++), invalidCharacterReplacement)); } OComplexObject erow = OComplexObjects.create( (EdmComplexType) ((EdmCollectionType) returnType).getItemType(), row); resultRows.add(erow); } String collectionName = returnType.getFullyQualifiedTypeName(); collectionName = collectionName.replace("(", "_"); // $NON-NLS-1$ //$NON-NLS-2$ collectionName = collectionName.replace(")", "_"); // $NON-NLS-1$ //$NON-NLS-2$ return Responses.collection(resultRows.build(), null, null, null, collectionName); } if (returnType != null) { Object result = stmt.getObject(1); OProperty prop = buildPropery("return", returnType, result, invalidCharacterReplacement); // $NON-NLS-1$ return Responses.property(prop); } return null; } catch (Exception e) { throw new ServerErrorException(e.getMessage(), e); } finally { if (connection != null) { try { connection.close(); } catch (SQLException e) { } } } }