/* * Find the entity set name for this resource */ public String getEntitySet(ResourceState state) { String entitySetName = null; String fqTargetEntityName = metadata.getModelName() + Metadata.MODEL_SUFFIX + "." + state.getEntityName(); try { EdmEntityType targetEntityType = (EdmEntityType) getEdmDataService().findEdmEntityType(fqTargetEntityName); if (targetEntityType != null) { EdmEntitySet targetEntitySet = getEdmDataService().getEdmEntitySet(targetEntityType); if (targetEntitySet != null) entitySetName = targetEntitySet.getName(); } } catch (NotFoundException e) { } if (entitySetName == null) { try { entitySetName = getEdmEntitySet(state.getEntityName()).getName(); } catch (NotFoundException e) { logger.warn("Entity [" + fqTargetEntityName + "] is not an entity set."); } if (entitySetName == null) { entitySetName = state.getName(); } } return entitySetName; }
/** * 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; }
private EdmEntitySet.Builder parseEdmEntitySet( XMLEventReader2 reader, String schemaNamespace, StartElement2 entitySetStartElement) { List<EdmAnnotation<?>> annotElements = new ArrayList<EdmAnnotation<?>>(); String name = entitySetStartElement.getAttributeByName("Name").getValue(); String entityTypeName = getAttributeValueIfExists(entitySetStartElement, "EntityType"); while (reader.hasNext()) { XMLEvent2 event = reader.nextEvent(); if (event.isStartElement()) { EdmAnnotation<?> anElement = getAnnotationElements(event, reader); if (anElement != null) { annotElements.add(anElement); } } if (isEndElement(event, entitySetStartElement.getName())) { return EdmEntitySet.newBuilder() .setName(name) .setEntityTypeName(entityTypeName) .setAnnotations(getAnnotations(entitySetStartElement)) .setAnnotationElements(annotElements); } } throw new UnsupportedOperationException(); }
/** * 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 String getEntitySetName() { return entitySet.getName(); }
@Override public EdmEntityType getEntityType() { return entityType != null ? entityType : entitySet != null ? entitySet.getType() : null; }
protected String writeEntry( XMLWriter2 writer, OEntity oe, List<OProperty<?>> entityProperties, List<OLink> entityLinks, String baseUri, String updated, EdmEntitySet ees, boolean isResponse) { String relid = null; String absid = null; if (isResponse) { relid = InternalUtil.getEntityRelId(oe); absid = baseUri + relid; writeElement(writer, "id", absid); } OAtomEntity oae = getAtomInfo(oe); writeElement(writer, "title", oae.getAtomEntityTitle(), "type", "text"); String summary = oae.getAtomEntitySummary(); if (summary != null) { writeElement(writer, "summary", summary, "type", "text"); } LocalDateTime updatedTime = oae.getAtomEntityUpdated(); if (updatedTime != null) { updated = InternalUtil.toString(updatedTime.toDateTime(DateTimeZone.UTC)); } writeElement(writer, "updated", updated); writer.startElement("author"); writeElement(writer, "name", oae.getAtomEntityAuthor()); writer.endElement("author"); if (isResponse) { writeElement( writer, "link", null, "rel", "edit", "title", ees.getType().getName(), "href", relid); } if (entityLinks != null) { if (isResponse) { // the producer has populated the link collection, we just what he gave us. for (OLink link : entityLinks) { String rel = related + link.getTitle(); String type = (link.isCollection()) ? atom_feed_content_type : atom_entry_content_type; String href = relid + "/" + link.getTitle(); if (link.isInline()) { writer.startElement("link"); writer.writeAttribute("rel", rel); writer.writeAttribute("type", type); writer.writeAttribute("title", link.getTitle()); writer.writeAttribute("href", href); // write the inlined entities inside the link element writeLinkInline(writer, link, href, baseUri, updated, isResponse); writer.endElement("link"); } else { // deferred link. writeElement( writer, "link", null, "rel", rel, "type", type, "title", link.getTitle(), "href", href); } } } else { // for requests we include only the provided links // Note: It seems that OLinks for responses are only built using the // title and OLinks for requests have the additional info in them // alread. I'm leaving that inconsistency in place for now but this // else and its preceding if could probably be unified. for (OLink olink : entityLinks) { String type = olink.isCollection() ? atom_feed_content_type : atom_entry_content_type; writer.startElement("link"); writer.writeAttribute("rel", olink.getRelation()); writer.writeAttribute("type", type); writer.writeAttribute("title", olink.getTitle()); writer.writeAttribute("href", olink.getHref()); if (olink.isInline()) { // write the inlined entities inside the link element writeLinkInline(writer, olink, olink.getHref(), baseUri, updated, isResponse); } writer.endElement("link"); } } } // else entityLinks null writeElement( writer, "category", null, // oe is null for creates "term", oe == null ? ees.getType().getFullyQualifiedTypeName() : oe.getEntityType().getFullyQualifiedTypeName(), "scheme", scheme); boolean hasStream = false; if (oe != null) { OAtomStreamEntity stream = oe.findExtension(OAtomStreamEntity.class); if (stream != null) { hasStream = true; writer.startElement("content"); writer.writeAttribute("type", stream.getAtomEntityType()); writer.writeAttribute("src", baseUri + stream.getAtomEntitySource()); writer.endElement("content"); } } if (!hasStream) { writer.startElement("content"); writer.writeAttribute("type", MediaType.APPLICATION_XML); } writer.startElement(new QName2(m, "properties", "m")); writeProperties(writer, entityProperties); writer.endElement("properties"); if (!hasStream) { writer.endElement("content"); } return absid; }
private static void buildEntityTypes( MetadataStore metadataStore, List<EdmSchema.Builder> edmSchemas) { for (Schema schema : metadataStore.getSchemaList()) { List<EdmEntitySet.Builder> entitySets = new ArrayList<EdmEntitySet.Builder>(); List<EdmEntityType.Builder> entityTypes = new ArrayList<EdmEntityType.Builder>(); for (Table table : schema.getTables().values()) { KeyRecord primaryKey = table.getPrimaryKey(); List<KeyRecord> uniques = table.getUniqueKeys(); if (primaryKey == null && uniques.isEmpty()) { LogManager.logDetail( LogConstants.CTX_ODATA, ODataPlugin.Util.gs(ODataPlugin.Event.TEIID16002, table.getFullName())); continue; } EdmEntityType.Builder entityType = EdmEntityType.newBuilder().setName(table.getName()).setNamespace(schema.getName()); // adding key if (primaryKey != null) { for (Column c : primaryKey.getColumns()) { entityType.addKeys(c.getName()); } } else { for (Column c : uniques.get(0).getColumns()) { entityType.addKeys(c.getName()); } } // adding properties for (Column c : table.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); } entityType.addProperties(property); } // entity set one for one entity type EdmEntitySet.Builder entitySet = EdmEntitySet.newBuilder().setName(table.getName()).setEntityType(entityType); entityType.setNamespace(schema.getName()); entitySets.add(entitySet); // add enitity types for entity schema entityTypes.add(entityType); } // entity container is holder entity sets, association sets, function imports EdmEntityContainer.Builder entityContainer = EdmEntityContainer.newBuilder() .setName(schema.getName()) .setIsDefault(false) .addEntitySets(entitySets); // build entity schema EdmSchema.Builder modelSchema = EdmSchema.newBuilder() .setNamespace(schema.getName()) .addEntityTypes(entityTypes) .addEntityContainers(entityContainer); edmSchemas.add(modelSchema); } }
public static EdmEntitySet.Builder getBuilder(String namespace) { EdmEntityType.Builder modelBuilder = MdHierNodeWrapper.getEntityModel(namespace); EdmEntityType.Builder rowType = EdmEntityType.newBuilder().setNamespace(namespace).setName("Row"); EdmEntityType.Builder mdDataDimType = MdDataDimWrapper.getEntityModel(namespace); EdmEntityType.Builder mdHierarchyType = MdHierarchyWrapper.getEntityModel(namespace); EdmAssociationEnd.Builder mdHierNodeRowEnd = EdmAssociationEnd.newBuilder() .setRole("MdHierNode") .setType(modelBuilder) .setMultiplicity(EdmMultiplicity.ONE); EdmAssociationEnd.Builder rowMdHierNodeEnd = EdmAssociationEnd.newBuilder() .setRole("Rows") .setType(rowType) .setMultiplicity(EdmMultiplicity.MANY); EdmAssociation.Builder mdHierNodeRow = EdmAssociation.newBuilder() .setName("MdHierNode-Rows") .setEnds(mdHierNodeRowEnd, rowMdHierNodeEnd); EdmAssociationEnd.Builder mdHierNodeMdDataDimEnd = EdmAssociationEnd.newBuilder() .setRole("MdHierNode") .setType(modelBuilder) .setMultiplicity(EdmMultiplicity.ONE); EdmAssociationEnd.Builder mdDataDimMdHierNodeEnd = EdmAssociationEnd.newBuilder() .setRole("MdDataDim") .setType(mdDataDimType) .setMultiplicity(EdmMultiplicity.MANY); EdmAssociation.Builder mdHierNodeMdDataDim = EdmAssociation.newBuilder() .setName("MdHierNode-MdDataDim") .setEnds(mdHierNodeMdDataDimEnd, mdDataDimMdHierNodeEnd); EdmAssociationEnd.Builder mdHierarchyMdHierNodeEnd = EdmAssociationEnd.newBuilder() .setRole("MdHierarchy") .setType(mdHierarchyType) .setMultiplicity(EdmMultiplicity.ONE); EdmAssociationEnd.Builder mdHierNodeMdHierarchyEnd = EdmAssociationEnd.newBuilder() .setRole("MdHierNode") .setType(modelBuilder) .setMultiplicity(EdmMultiplicity.MANY); EdmAssociation.Builder mdHierNodeMdHierarchy = EdmAssociation.newBuilder() .setName("MdHierNode-MdHierarchy") .setEnds(mdHierNodeMdHierarchyEnd, mdHierarchyMdHierNodeEnd); EdmNavigationProperty.Builder nodeHierarchyNavigationProperty = EdmNavigationProperty.newBuilder("IdHierarchy") .setRelationship(mdHierNodeMdHierarchy) .setFromTo(mdHierNodeMdHierarchy.getEnd1(), mdHierNodeMdHierarchy.getEnd2()); modelBuilder.addNavigationProperties(nodeHierarchyNavigationProperty); EdmNavigationProperty.Builder nodeRowsNavigationProperty = EdmNavigationProperty.newBuilder("NodeRows") .setRelationship(mdHierNodeRow) .setFromTo(mdHierNodeRow.getEnd1(), mdHierNodeRow.getEnd2()); modelBuilder.addNavigationProperties(nodeRowsNavigationProperty); EdmNavigationProperty.Builder nodeDataNavigationProperty = EdmNavigationProperty.newBuilder("NodeData") .setRelationship(mdHierNodeMdDataDim) .setFromTo(mdHierNodeMdDataDim.getEnd1(), mdHierNodeMdDataDim.getEnd2()); modelBuilder.addNavigationProperties(nodeDataNavigationProperty); return EdmEntitySet.newBuilder().setName("MdHierNode").setEntityType(modelBuilder); }
public static void write(EdmDataServices services, Writer w) { XMLWriter2 writer = XMLFactoryProvider2.getInstance().newXMLWriterFactory2().createXMLWriter(w); writer.startDocument(); writer.startElement(new QName2(edmx, "Edmx", "edmx")); writer.writeAttribute("Version", "1.0"); writer.writeNamespace("edmx", edmx); writer.writeNamespace("d", d); writer.writeNamespace("m", m); writeExtensionNamespaces(services, writer); writer.startElement(new QName2(edmx, "DataServices", "edmx")); writer.writeAttribute(new QName2(m, "DataServiceVersion", "m"), "1.0"); // Schema for (EdmSchema schema : services.getSchemas()) { writer.startElement(new QName2("Schema"), edm); writer.writeAttribute("Namespace", schema.getNamespace()); writeAnnotationAttributes(schema, writer); writeDocumentation(schema, writer); // ComplexType for (EdmComplexType ect : schema.getComplexTypes()) { writer.startElement(new QName2("ComplexType")); writer.writeAttribute("Name", ect.getName()); if (null != ect.getIsAbstract()) { writer.writeAttribute("Abstract", ect.getIsAbstract().toString()); } writeAnnotationAttributes(ect, writer); writeDocumentation(ect, writer); writeProperties(ect.getProperties(), writer); writeAnnotationElements(ect, writer); writer.endElement("ComplexType"); } // EntityType for (EdmEntityType eet : schema.getEntityTypes()) { writer.startElement(new QName2("EntityType")); writer.writeAttribute("Name", eet.getName()); if (null != eet.getIsAbstract()) { writer.writeAttribute("Abstract", eet.getIsAbstract().toString()); } if (Boolean.TRUE.equals(eet.getHasStream())) { writer.writeAttribute(new QName2(m, "HasStream", "m"), "true"); } // keys only on base types if (eet.isRootType()) { writeAnnotationAttributes(eet, writer); writeDocumentation(eet, writer); writer.startElement(new QName2("Key")); for (String key : eet.getKeys()) { writer.startElement(new QName2("PropertyRef")); writer.writeAttribute("Name", key); writer.endElement("PropertyRef"); } writer.endElement("Key"); } else { writer.writeAttribute("BaseType", eet.getBaseType().getFullyQualifiedTypeName()); writeAnnotationAttributes(eet, writer); writeDocumentation(eet, writer); } writeProperties(eet.getDeclaredProperties(), writer); for (EdmNavigationProperty np : eet.getDeclaredNavigationProperties()) { writer.startElement(new QName2("NavigationProperty")); writer.writeAttribute("Name", np.getName()); writer.writeAttribute("Relationship", np.getRelationship().getFQNamespaceName()); writer.writeAttribute("FromRole", np.getFromRole().getRole()); writer.writeAttribute("ToRole", np.getToRole().getRole()); writeAnnotationAttributes(np, writer); writeDocumentation(np, writer); writeAnnotationElements(np, writer); writer.endElement("NavigationProperty"); } writeAnnotationElements(eet, writer); writer.endElement("EntityType"); } // Association for (EdmAssociation assoc : schema.getAssociations()) { writer.startElement(new QName2("Association")); writer.writeAttribute("Name", assoc.getName()); writeAnnotationAttributes(assoc, writer); writeDocumentation(assoc, writer); writer.startElement(new QName2("End")); writer.writeAttribute("Role", assoc.getEnd1().getRole()); writer.writeAttribute("Type", assoc.getEnd1().getType().getFullyQualifiedTypeName()); writer.writeAttribute("Multiplicity", assoc.getEnd1().getMultiplicity().getSymbolString()); writer.endElement("End"); writer.startElement(new QName2("End")); writer.writeAttribute("Role", assoc.getEnd2().getRole()); writer.writeAttribute("Type", assoc.getEnd2().getType().getFullyQualifiedTypeName()); writer.writeAttribute("Multiplicity", assoc.getEnd2().getMultiplicity().getSymbolString()); writer.endElement("End"); writeAnnotationElements(assoc, writer); writer.endElement("Association"); } // EntityContainer for (EdmEntityContainer container : schema.getEntityContainers()) { writer.startElement(new QName2("EntityContainer")); writer.writeAttribute("Name", container.getName()); writer.writeAttribute( new QName2(m, "IsDefaultEntityContainer", "m"), Boolean.toString(container.isDefault())); writeAnnotationAttributes(container, writer); writeDocumentation(container, writer); for (EdmEntitySet ees : container.getEntitySets()) { writer.startElement(new QName2("EntitySet")); writer.writeAttribute("Name", ees.getName()); writer.writeAttribute("EntityType", ees.getType().getFullyQualifiedTypeName()); writeAnnotationAttributes(ees, writer); writeDocumentation(ees, writer); writeAnnotationElements(ees, writer); writer.endElement("EntitySet"); } for (EdmFunctionImport fi : container.getFunctionImports()) { writer.startElement(new QName2("FunctionImport")); writer.writeAttribute("Name", fi.getName()); if (null != fi.getEntitySet()) { writer.writeAttribute("EntitySet", fi.getEntitySet().getName()); } if (fi.getReturnType() != null) { // TODO: how to differentiate inline ReturnType vs embedded ReturnType? writer.writeAttribute("ReturnType", fi.getReturnType().getFullyQualifiedTypeName()); } writer.writeAttribute(new QName2(m, "HttpMethod", "m"), fi.getHttpMethod()); writeAnnotationAttributes(fi, writer); writeDocumentation(fi, writer); for (EdmFunctionParameter param : fi.getParameters()) { writer.startElement(new QName2("Parameter")); writer.writeAttribute("Name", param.getName()); writer.writeAttribute("Type", param.getType().getFullyQualifiedTypeName()); if (param.getMode() != null) writer.writeAttribute("Mode", param.getMode().toString()); writeAnnotationAttributes(param, writer); writeDocumentation(param, writer); writeAnnotationElements(param, writer); writer.endElement("Parameter"); } writeAnnotationElements(fi, writer); writer.endElement("FunctionImport"); } for (EdmAssociationSet eas : container.getAssociationSets()) { writer.startElement(new QName2("AssociationSet")); writer.writeAttribute("Name", eas.getName()); writer.writeAttribute("Association", eas.getAssociation().getFQNamespaceName()); writeAnnotationAttributes(eas, writer); writeDocumentation(eas, writer); writer.startElement(new QName2("End")); writer.writeAttribute("Role", eas.getEnd1().getRole().getRole()); writer.writeAttribute("EntitySet", eas.getEnd1().getEntitySet().getName()); writer.endElement("End"); writer.startElement(new QName2("End")); writer.writeAttribute("Role", eas.getEnd2().getRole().getRole()); writer.writeAttribute("EntitySet", eas.getEnd2().getEntitySet().getName()); writer.endElement("End"); writeAnnotationElements(eas, writer); writer.endElement("AssociationSet"); } writeAnnotationElements(container, writer); writer.endElement("EntityContainer"); } writeAnnotationElements(schema, writer); writer.endElement("Schema"); } writer.endDocument(); }
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); } } } }
@Override public EntityList executeSQL( Query query, List<SQLParam> parameters, EdmEntitySet entitySet, LinkedHashMap<String, Boolean> projectedColumns, QueryInfo queryInfo) { ConnectionImpl connection = null; try { boolean cache = queryInfo != null && this.batchSize > 0; if (cache) { CacheHint hint = new CacheHint(); hint.setTtl(this.cacheTime); hint.setScope(CacheDirective.Scope.USER); hint.setMinRows(Long.valueOf(this.batchSize)); query.setCacheHint(hint); } boolean getCount = false; if (queryInfo != null) { getCount = queryInfo.inlineCount == InlineCount.ALLPAGES; if (!getCount && (queryInfo.top != null || queryInfo.skip != null)) { if (queryInfo.top != null && queryInfo.skip != null) { query.setLimit(new Limit(new Constant(queryInfo.skip), new Constant(queryInfo.top))); } else if (queryInfo.top != null) { query.setLimit(new Limit(new Constant(0), new Constant(queryInfo.top))); } } } connection = getConnection(); String sessionId = connection.getServerConnection().getLogonResult().getSessionID(); String skipToken = null; if (queryInfo != null && queryInfo.skipToken != null) { skipToken = queryInfo.skipToken; if (cache) { int idx = queryInfo.skipToken.indexOf(DELIMITER); sessionId = queryInfo.skipToken.substring(0, idx); skipToken = queryInfo.skipToken.substring(idx + 2); } } String sql = query.toString(); if (cache) { sql += " /* " + sessionId + " */"; // $NON-NLS-1$ //$NON-NLS-2$ } LogManager.logDetail(LogConstants.CTX_ODATA, "Teiid-Query:", sql); // $NON-NLS-1$ final PreparedStatement stmt = connection.prepareStatement( sql, cache ? ResultSet.TYPE_SCROLL_INSENSITIVE : ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); if (parameters != null && !parameters.isEmpty()) { for (int i = 0; i < parameters.size(); i++) { stmt.setObject(i + 1, parameters.get(i).value, parameters.get(i).sqlType); } } final ResultSet rs = stmt.executeQuery(); if (projectedColumns == null) { projectedColumns = new LinkedHashMap<String, Boolean>(); for (int i = 0; i < rs.getMetaData().getColumnCount(); i++) { projectedColumns.put(rs.getMetaData().getColumnLabel(i + 1), Boolean.TRUE); } } EntityList result = new EntityList(invalidCharacterReplacement); HashMap<String, EdmProperty> propertyTypes = new HashMap<String, EdmProperty>(); EdmEntityType entityType = entitySet.getType(); Iterator<EdmProperty> propIter = entityType.getProperties().iterator(); while (propIter.hasNext()) { EdmProperty prop = propIter.next(); propertyTypes.put(prop.getName(), prop); } // skip to the initial position int count = 0; int skipSize = 0; // skip based upon the skip value if (getCount && queryInfo.skip != null) { skipSize = queryInfo.skip; } // skip based upon the skipToken if (skipToken != null) { skipSize += Integer.parseInt(skipToken); } if (skipSize > 0) { count += skip(cache, rs, skipSize); } // determine the number of records to return int size = batchSize; int top = Integer.MAX_VALUE; if (getCount && queryInfo.top != null) { top = queryInfo.top; size = top; if (batchSize > 0) { size = Math.min(batchSize, size); } } else if (size < 1) { size = Integer.MAX_VALUE; } // build the results for (int i = 0; i < size; i++) { if (!rs.next()) { break; } count++; result.addEntity(rs, propertyTypes, projectedColumns, entitySet); } // set the count if (getCount) { if (!cache) { while (rs.next()) { count++; } } else { rs.last(); count = rs.getRow(); } } result.setCount(count); // set the skipToken if needed if (cache && result.size() == this.batchSize) { int end = skipSize + result.size(); if (getCount) { if (end < Math.min(top, count)) { result.setNextToken(nextToken(cache, sessionId, end)); } } else if (rs.next()) { result.setNextToken(nextToken(cache, sessionId, end)); // will force the entry to cache or is effectively a no-op when already cached rs.last(); } } return result; } catch (Exception e) { throw new ServerErrorException(e.getMessage(), e); } finally { if (connection != null) { try { connection.close(); } catch (SQLException e) { } } } }