Search in sources :

Example 6 with AssociationSchema

use of com.linkedin.restli.restspec.AssociationSchema in project rest.li by linkedin.

the class TestExamplesGenerator method findRestMethod.

private static RestMethodSchema findRestMethod(ResourceSchema resourceSchema, ResourceMethod method) {
    RestMethodSchemaArray methods = null;
    RestMethodSchema methodResult = null;
    final CollectionSchema collectionSchema = resourceSchema.getCollection();
    if (collectionSchema != null) {
        methods = collectionSchema.getMethods();
    }
    final AssociationSchema associationSchema = resourceSchema.getAssociation();
    if (associationSchema != null) {
        methods = associationSchema.getMethods();
    }
    final SimpleSchema simpleSchema = resourceSchema.getSimple();
    if (simpleSchema != null) {
        methods = simpleSchema.getMethods();
    }
    if (methods != null) {
        for (RestMethodSchema restMethodSchema : methods) {
            if (restMethodSchema.getMethod().equalsIgnoreCase(method.name())) {
                methodResult = restMethodSchema;
                break;
            }
        }
    }
    return methodResult;
}
Also used : AssociationSchema(com.linkedin.restli.restspec.AssociationSchema) RestMethodSchemaArray(com.linkedin.restli.restspec.RestMethodSchemaArray) CollectionSchema(com.linkedin.restli.restspec.CollectionSchema) SimpleSchema(com.linkedin.restli.restspec.SimpleSchema) RestMethodSchema(com.linkedin.restli.restspec.RestMethodSchema)

Example 7 with AssociationSchema

use of com.linkedin.restli.restspec.AssociationSchema in project rest.li by linkedin.

the class JavaRequestBuilderGenerator method generateResourceFacade.

private JDefinedClass generateResourceFacade(ResourceSchema resource, File sourceFile, Map<String, JClass> pathKeyTypes, Map<String, JClass> assocKeyTypes, Map<String, List<String>> pathToAssocKeys) throws JClassAlreadyExistsException, IOException {
    final ValidationResult validationResult = ValidateDataAgainstSchema.validate(resource.data(), resource.schema(), new ValidationOptions(RequiredMode.MUST_BE_PRESENT));
    if (!validationResult.isValid()) {
        throw new IllegalArgumentException(String.format("Resource validation error.  Resource File '%s', Error Details '%s'", sourceFile, validationResult.toString()));
    }
    final String packageName = resource.getNamespace();
    final JPackage clientPackage = (packageName == null || packageName.isEmpty()) ? getPackage() : getPackage(packageName);
    final String className;
    if (_version == RestliVersion.RESTLI_2_0_0) {
        className = getBuilderClassNameByVersion(RestliVersion.RESTLI_2_0_0, null, resource.getName(), true);
    } else {
        className = getBuilderClassNameByVersion(RestliVersion.RESTLI_1_0_0, null, resource.getName(), true);
    }
    final JDefinedClass facadeClass = clientPackage._class(className);
    annotate(facadeClass, sourceFile.getAbsolutePath());
    final JFieldVar baseUriField;
    final JFieldVar requestOptionsField;
    final JExpression baseUriGetter = JExpr.invoke("getBaseUriTemplate");
    final JExpression requestOptionsGetter = JExpr.invoke("getRequestOptions");
    if (_version == RestliVersion.RESTLI_2_0_0) {
        baseUriField = null;
        requestOptionsField = null;
        facadeClass._extends(BuilderBase.class);
    } else {
        // for old builder, instead of extending from RequestBuilderBase, add fields and getters in the class
        baseUriField = facadeClass.field(JMod.PRIVATE | JMod.FINAL, String.class, "_baseUriTemplate");
        requestOptionsField = facadeClass.field(JMod.PRIVATE, RestliRequestOptions.class, "_requestOptions");
        facadeClass.method(JMod.PRIVATE, String.class, "getBaseUriTemplate").body()._return(baseUriField);
        facadeClass.method(JMod.PUBLIC, RestliRequestOptions.class, "getRequestOptions").body()._return(requestOptionsField);
    }
    // make the original resource path available via a private final static variable.
    final JFieldVar originalResourceField = facadeClass.field(JMod.PRIVATE | JMod.STATIC | JMod.FINAL, String.class, "ORIGINAL_RESOURCE_PATH");
    final String resourcePath = getResourcePath(resource.getPath());
    originalResourceField.init(JExpr.lit(resourcePath));
    // create reference to RestliRequestOptions.DEFAULT_OPTIONS
    final JClass restliRequestOptionsClass = getCodeModel().ref(RestliRequestOptions.class);
    final JFieldRef defaultOptionsField = restliRequestOptionsClass.staticRef("DEFAULT_OPTIONS");
    if (_version == RestliVersion.RESTLI_1_0_0) {
        // same getPathComponents() logic as in RequestBuilderBase
        final JMethod pathComponentsGetter = facadeClass.method(JMod.PUBLIC, String[].class, "getPathComponents");
        pathComponentsGetter.body()._return(getCodeModel().ref(URIParamUtils.class).staticInvoke("extractPathComponentsFromUriTemplate").arg(baseUriField));
        // method that expresses the following logic
        //   (requestOptions == null) ? return RestliRequestOptions.DEFAULT_OPTIONS : requestOptions;
        final JMethod requestOptionsAssigner = facadeClass.method(JMod.PRIVATE | JMod.STATIC, RestliRequestOptions.class, "assignRequestOptions");
        final JVar requestOptionsAssignerParam = requestOptionsAssigner.param(RestliRequestOptions.class, "requestOptions");
        final JConditional requestNullCheck = requestOptionsAssigner.body()._if(requestOptionsAssignerParam.eq(JExpr._null()));
        requestNullCheck._then().block()._return(defaultOptionsField);
        requestNullCheck._else().block()._return(requestOptionsAssignerParam);
    }
    /*
    There will be 4 constructors:
      ()
      (RestliRequestOptions)
      (String)
      (String, RestliRequestOptions)
    */
    final JMethod noArgConstructor = facadeClass.constructor(JMod.PUBLIC);
    final JMethod requestOptionsOverrideConstructor = facadeClass.constructor(JMod.PUBLIC);
    final JMethod resourceNameOverrideConstructor = facadeClass.constructor(JMod.PUBLIC);
    final JMethod mainConstructor = facadeClass.constructor(JMod.PUBLIC);
    // no-argument constructor, delegates to the request options override constructor
    noArgConstructor.body().invoke(THIS).arg(defaultOptionsField);
    // request options override constructor
    final JVar requestOptionsOverrideOptionsParam = requestOptionsOverrideConstructor.param(RestliRequestOptions.class, "requestOptions");
    if (_version == RestliVersion.RESTLI_2_0_0) {
        requestOptionsOverrideConstructor.body().invoke(SUPER).arg(originalResourceField).arg(requestOptionsOverrideOptionsParam);
    } else {
        requestOptionsOverrideConstructor.body().assign(baseUriField, originalResourceField);
        final JInvocation requestOptionsOverrideAssignRequestOptions = new JBlock().invoke("assignRequestOptions").arg(requestOptionsOverrideOptionsParam);
        requestOptionsOverrideConstructor.body().assign(requestOptionsField, requestOptionsOverrideAssignRequestOptions);
    }
    // primary resource name override constructor, delegates to the main constructor
    final JVar resourceNameOverrideResourceNameParam = resourceNameOverrideConstructor.param(_stringClass, "primaryResourceName");
    resourceNameOverrideConstructor.body().invoke(THIS).arg(resourceNameOverrideResourceNameParam).arg(defaultOptionsField);
    // main constructor
    final JVar mainConsResourceNameParam = mainConstructor.param(_stringClass, "primaryResourceName");
    final JVar mainConsOptionsParam = mainConstructor.param(RestliRequestOptions.class, "requestOptions");
    final JExpression baseUriExpr;
    if (resourcePath.contains("/")) {
        baseUriExpr = originalResourceField.invoke("replaceFirst").arg(JExpr.lit("[^/]*/")).arg(mainConsResourceNameParam.plus(JExpr.lit("/")));
    } else {
        baseUriExpr = mainConsResourceNameParam;
    }
    if (_version == RestliVersion.RESTLI_2_0_0) {
        mainConstructor.body().invoke(SUPER).arg(baseUriExpr).arg(mainConsOptionsParam);
    } else {
        final JInvocation mainAssignRequestOptions = new JBlock().invoke("assignRequestOptions").arg(mainConsOptionsParam);
        mainConstructor.body().assign(baseUriField, baseUriExpr);
        mainConstructor.body().assign(requestOptionsField, mainAssignRequestOptions);
    }
    final String resourceName = CodeUtil.capitalize(resource.getName());
    final JMethod primaryResourceGetter = facadeClass.method(JMod.PUBLIC | JMod.STATIC, String.class, "getPrimaryResource");
    primaryResourceGetter.body()._return(originalResourceField);
    final List<String> pathKeys = getPathKeys(resourcePath, pathToAssocKeys);
    JClass keyTyperefClass = null;
    final JClass keyClass;
    JClass keyKeyClass = null;
    JClass keyParamsClass = null;
    final Class<?> resourceSchemaClass;
    Map<String, AssocKeyTypeInfo> assocKeyTypeInfos = Collections.emptyMap();
    StringArray supportsList = null;
    RestMethodSchemaArray restMethods = null;
    FinderSchemaArray finders = null;
    ResourceSchemaArray subresources = null;
    ActionSchemaArray resourceActions = null;
    ActionSchemaArray entityActions = null;
    if (resource.getCollection() != null) {
        resourceSchemaClass = CollectionSchema.class;
        final CollectionSchema collection = resource.getCollection();
        final String keyName = collection.getIdentifier().getName();
        // ComplexKeyResource parameterized by those two.
        if (collection.getIdentifier().getParams() == null) {
            keyClass = getJavaBindingType(collection.getIdentifier().getType(), facadeClass).valueClass;
            final JClass declaredClass = getClassRefForSchema(RestSpecCodec.textToSchema(collection.getIdentifier().getType(), _schemaResolver), facadeClass);
            if (!declaredClass.equals(keyClass)) {
                keyTyperefClass = declaredClass;
            }
        } else {
            keyKeyClass = getJavaBindingType(collection.getIdentifier().getType(), facadeClass).valueClass;
            keyParamsClass = getJavaBindingType(collection.getIdentifier().getParams(), facadeClass).valueClass;
            keyClass = getCodeModel().ref(ComplexResourceKey.class).narrow(keyKeyClass, keyParamsClass);
        }
        pathKeyTypes.put(keyName, keyClass);
        supportsList = collection.getSupports();
        restMethods = collection.getMethods();
        finders = collection.getFinders();
        subresources = collection.getEntity().getSubresources();
        resourceActions = collection.getActions();
        entityActions = collection.getEntity().getActions();
    } else if (resource.getAssociation() != null) {
        resourceSchemaClass = AssociationSchema.class;
        final AssociationSchema association = resource.getAssociation();
        keyClass = getCodeModel().ref(CompoundKey.class);
        supportsList = association.getSupports();
        restMethods = association.getMethods();
        finders = association.getFinders();
        subresources = association.getEntity().getSubresources();
        resourceActions = association.getActions();
        entityActions = association.getEntity().getActions();
        assocKeyTypeInfos = generateAssociationKey(facadeClass, association);
        final String keyName = getAssociationKey(resource, association);
        pathKeyTypes.put(keyName, keyClass);
        final List<String> assocKeys = new ArrayList<String>(4);
        for (Map.Entry<String, AssocKeyTypeInfo> entry : assocKeyTypeInfos.entrySet()) {
            assocKeys.add(entry.getKey());
            assocKeyTypes.put(entry.getKey(), entry.getValue().getBindingType());
        }
        pathToAssocKeys.put(keyName, assocKeys);
    } else if (resource.getSimple() != null) {
        resourceSchemaClass = SimpleSchema.class;
        final SimpleSchema simpleSchema = resource.getSimple();
        keyClass = _voidClass;
        supportsList = simpleSchema.getSupports();
        restMethods = simpleSchema.getMethods();
        subresources = simpleSchema.getEntity().getSubresources();
        resourceActions = simpleSchema.getActions();
    } else if (resource.getActionsSet() != null) {
        resourceSchemaClass = ActionsSetSchema.class;
        final ActionsSetSchema actionsSet = resource.getActionsSet();
        resourceActions = actionsSet.getActions();
        keyClass = _voidClass;
    } else {
        throw new IllegalArgumentException("unsupported resource type for resource: '" + resourceName + '\'');
    }
    generateOptions(facadeClass, baseUriGetter, requestOptionsGetter);
    final JFieldVar resourceSpecField = facadeClass.field(JMod.PRIVATE | JMod.STATIC | JMod.FINAL, _resourceSpecClass, "_resourceSpec");
    if (resourceSchemaClass == CollectionSchema.class || resourceSchemaClass == AssociationSchema.class || resourceSchemaClass == SimpleSchema.class) {
        final JClass schemaClass = getJavaBindingType(resource.getSchema(), null).schemaClass;
        final Set<ResourceMethod> supportedMethods = getSupportedMethods(supportsList);
        final JInvocation supportedMethodsExpr;
        if (supportedMethods.isEmpty()) {
            supportedMethodsExpr = _enumSetClass.staticInvoke("noneOf").arg(_resourceMethodClass.dotclass());
        } else {
            supportedMethodsExpr = _enumSetClass.staticInvoke("of");
            for (ResourceMethod resourceMethod : supportedMethods) {
                validateResourceMethod(resourceSchemaClass, resourceName, resourceMethod);
                supportedMethodsExpr.arg(_resourceMethodClass.staticRef(resourceMethod.name()));
            }
        }
        final JBlock staticInit = facadeClass.init();
        final JVar methodSchemaMap = methodMetadataMapInit(facadeClass, resourceActions, entityActions, staticInit);
        final JVar responseSchemaMap = responseMetadataMapInit(facadeClass, resourceActions, entityActions, staticInit);
        if (resourceSchemaClass == CollectionSchema.class || resourceSchemaClass == AssociationSchema.class) {
            final JClass assocKeyClass = getCodeModel().ref(TypeInfo.class);
            final JClass hashMapClass = getCodeModel().ref(HashMap.class).narrow(_stringClass, assocKeyClass);
            final JVar keyPartsVar = staticInit.decl(hashMapClass, "keyParts").init(JExpr._new(hashMapClass));
            for (Map.Entry<String, AssocKeyTypeInfo> typeInfoEntry : assocKeyTypeInfos.entrySet()) {
                final AssocKeyTypeInfo typeInfo = typeInfoEntry.getValue();
                final JInvocation typeArg = JExpr._new(assocKeyClass).arg(typeInfo.getBindingType().dotclass()).arg(typeInfo.getDeclaredType().dotclass());
                staticInit.add(keyPartsVar.invoke("put").arg(typeInfoEntry.getKey()).arg(typeArg));
            }
            staticInit.assign(resourceSpecField, JExpr._new(_resourceSpecImplClass).arg(supportedMethodsExpr).arg(methodSchemaMap).arg(responseSchemaMap).arg(keyTyperefClass == null ? keyClass.dotclass() : keyTyperefClass.dotclass()).arg(keyKeyClass == null ? JExpr._null() : keyKeyClass.dotclass()).arg(keyKeyClass == null ? JExpr._null() : keyParamsClass.dotclass()).arg(schemaClass.dotclass()).arg(keyPartsVar));
        } else //simple schema
        {
            staticInit.assign(resourceSpecField, JExpr._new(_resourceSpecImplClass).arg(supportedMethodsExpr).arg(methodSchemaMap).arg(responseSchemaMap).arg(schemaClass.dotclass()));
        }
        generateBasicMethods(facadeClass, baseUriGetter, keyClass, schemaClass, supportedMethods, restMethods, resourceSpecField, resourceName, pathKeys, pathKeyTypes, assocKeyTypes, pathToAssocKeys, requestOptionsGetter, resource.data().getDataMap("annotations"));
        if (resourceSchemaClass == CollectionSchema.class || resourceSchemaClass == AssociationSchema.class) {
            generateFinders(facadeClass, baseUriGetter, finders, keyClass, schemaClass, assocKeyTypeInfos, resourceSpecField, resourceName, pathKeys, pathKeyTypes, assocKeyTypes, pathToAssocKeys, requestOptionsGetter);
        }
        generateSubResources(sourceFile, subresources, pathKeyTypes, assocKeyTypes, pathToAssocKeys);
    } else //action set
    {
        final JBlock staticInit = facadeClass.init();
        final JInvocation supportedMethodsExpr = _enumSetClass.staticInvoke("noneOf").arg(_resourceMethodClass.dotclass());
        final JVar methodSchemaMap = methodMetadataMapInit(facadeClass, resourceActions, entityActions, staticInit);
        final JVar responseSchemaMap = responseMetadataMapInit(facadeClass, resourceActions, entityActions, staticInit);
        staticInit.assign(resourceSpecField, JExpr._new(_resourceSpecImplClass).arg(supportedMethodsExpr).arg(methodSchemaMap).arg(responseSchemaMap).arg(keyClass.dotclass()).arg(JExpr._null()).arg(JExpr._null()).arg(JExpr._null()).arg(getCodeModel().ref(Collections.class).staticInvoke("<String, Class<?>>emptyMap")));
    }
    generateActions(facadeClass, baseUriGetter, resourceActions, entityActions, keyClass, resourceSpecField, resourceName, pathKeys, pathKeyTypes, assocKeyTypes, pathToAssocKeys, requestOptionsGetter);
    generateClassJavadoc(facadeClass, resource);
    if (!checkVersionAndDeprecateBuilderClass(facadeClass, true)) {
        checkRestSpecAndDeprecateRootBuildersClass(facadeClass, resource);
    }
    return facadeClass;
}
Also used : HashMap(java.util.HashMap) ValidationResult(com.linkedin.data.schema.validation.ValidationResult) ValidationOptions(com.linkedin.data.schema.validation.ValidationOptions) ActionsSetSchema(com.linkedin.restli.restspec.ActionsSetSchema) StringArray(com.linkedin.data.template.StringArray) FinderSchemaArray(com.linkedin.restli.restspec.FinderSchemaArray) ActionSchemaArray(com.linkedin.restli.restspec.ActionSchemaArray) JConditional(com.sun.codemodel.JConditional) ArrayList(java.util.ArrayList) DataList(com.linkedin.data.DataList) List(java.util.List) Collections(java.util.Collections) JVar(com.sun.codemodel.JVar) AssociationSchema(com.linkedin.restli.restspec.AssociationSchema) JFieldRef(com.sun.codemodel.JFieldRef) RestMethodSchemaArray(com.linkedin.restli.restspec.RestMethodSchemaArray) CollectionSchema(com.linkedin.restli.restspec.CollectionSchema) RestliRequestOptions(com.linkedin.restli.client.RestliRequestOptions) JDefinedClass(com.sun.codemodel.JDefinedClass) SimpleSchema(com.linkedin.restli.restspec.SimpleSchema) JClass(com.sun.codemodel.JClass) JPackage(com.sun.codemodel.JPackage) ResourceSchemaArray(com.linkedin.restli.restspec.ResourceSchemaArray) JInvocation(com.sun.codemodel.JInvocation) JExpression(com.sun.codemodel.JExpression) JFieldVar(com.sun.codemodel.JFieldVar) URIParamUtils(com.linkedin.restli.internal.common.URIParamUtils) JBlock(com.sun.codemodel.JBlock) JMethod(com.sun.codemodel.JMethod) Map(java.util.Map) DataMap(com.linkedin.data.DataMap) HashMap(java.util.HashMap) ResourceMethod(com.linkedin.restli.common.ResourceMethod)

Example 8 with AssociationSchema

use of com.linkedin.restli.restspec.AssociationSchema in project rest.li by linkedin.

the class ResourceSchemaCollection method processResourceSchema.

private static void processResourceSchema(ResourceSchemaVisitior visitor, List<ResourceSchema> hierarchy, ResourceSchema resourceSchema) {
    hierarchy.add(resourceSchema);
    final ResourceSchemaVisitior.VisitContext context = buildContext(hierarchy);
    visitor.visitResourceSchema(context, resourceSchema);
    if (resourceSchema.hasCollection()) {
        final CollectionSchema collectionSchema = resourceSchema.getCollection();
        visitor.visitCollectionResource(context, collectionSchema);
        processRestMethods(visitor, context, collectionSchema, collectionSchema.getMethods());
        processFinders(visitor, context, collectionSchema, collectionSchema.getFinders());
        processActions(visitor, context, collectionSchema, collectionSchema.getActions());
        processEntitySchema(visitor, context, collectionSchema.getEntity());
    } else if (resourceSchema.hasAssociation()) {
        final AssociationSchema associationSchema = resourceSchema.getAssociation();
        visitor.visitAssociationResource(context, associationSchema);
        processRestMethods(visitor, context, associationSchema, associationSchema.getMethods());
        processFinders(visitor, context, associationSchema, associationSchema.getFinders());
        processActions(visitor, context, associationSchema, associationSchema.getActions());
        processEntitySchema(visitor, context, associationSchema.getEntity());
    } else if (resourceSchema.hasSimple()) {
        final SimpleSchema simpleSchema = resourceSchema.getSimple();
        visitor.visitSimpleResource(context, simpleSchema);
        processRestMethods(visitor, context, simpleSchema, simpleSchema.getMethods());
        processActions(visitor, context, simpleSchema, simpleSchema.getActions());
        processEntitySchema(visitor, context, simpleSchema.getEntity());
    } else if (resourceSchema.hasActionsSet()) {
        final ActionsSetSchema actionsSet = resourceSchema.getActionsSet();
        visitor.visitActionSetResource(context, actionsSet);
        processActions(visitor, context, actionsSet, actionsSet.getActions());
    }
    hierarchy.remove(hierarchy.size() - 1);
}
Also used : AssociationSchema(com.linkedin.restli.restspec.AssociationSchema) CollectionSchema(com.linkedin.restli.restspec.CollectionSchema) SimpleSchema(com.linkedin.restli.restspec.SimpleSchema) ActionsSetSchema(com.linkedin.restli.restspec.ActionsSetSchema)

Example 9 with AssociationSchema

use of com.linkedin.restli.restspec.AssociationSchema in project rest.li by linkedin.

the class RestLiResourceRelationship method findDataModels.

private void findDataModels() {
    final ResourceSchemaVisitior visitor = new BaseResourceSchemaVisitor() {

        @Override
        public void visitResourceSchema(VisitContext visitContext, ResourceSchema resourceSchema) {
            final String schema = resourceSchema.getSchema();
            // ActionSet resources do not have a schema
            if (schema != null) {
                final NamedDataSchema schemaSchema = extractSchema(schema);
                if (schemaSchema != null) {
                    connectSchemaToResource(visitContext, schemaSchema);
                }
            }
        }

        @Override
        public void visitCollectionResource(VisitContext visitContext, CollectionSchema collectionSchema) {
            final IdentifierSchema id = collectionSchema.getIdentifier();
            final NamedDataSchema typeSchema = extractSchema(id.getType());
            if (typeSchema != null) {
                connectSchemaToResource(visitContext, typeSchema);
            }
            final String params = id.getParams();
            if (params != null) {
                final NamedDataSchema paramsSchema = extractSchema(params);
                if (paramsSchema != null) {
                    connectSchemaToResource(visitContext, paramsSchema);
                }
            }
        }

        @Override
        public void visitAssociationResource(VisitContext visitContext, AssociationSchema associationSchema) {
            for (AssocKeySchema key : associationSchema.getAssocKeys()) {
                final NamedDataSchema keyTypeSchema = extractSchema(key.getType());
                if (keyTypeSchema != null) {
                    connectSchemaToResource(visitContext, keyTypeSchema);
                }
            }
        }

        @Override
        public void visitParameter(VisitContext visitContext, RecordTemplate parentResource, Object parentMethodSchema, ParameterSchema parameterSchema) {
            String parameterTypeString = parameterSchema.getType();
            if (// the parameter type field contains a inline schema, so we traverse into it
            isInlineSchema(parameterTypeString)) {
                visitInlineSchema(visitContext, parameterTypeString);
            } else {
                final NamedDataSchema schema;
                // grab the schema name from it
                if (parameterSchema.hasItems()) {
                    schema = extractSchema(parameterSchema.getItems());
                } else // the only remaining possibility is that the type field contains the name of a data schema
                {
                    schema = extractSchema(parameterTypeString);
                }
                if (schema != null) {
                    connectSchemaToResource(visitContext, schema);
                }
            }
        }

        @Override
        public void visitFinder(VisitContext visitContext, RecordTemplate parentResource, FinderSchema finderSchema) {
            final MetadataSchema metadata = finderSchema.getMetadata();
            if (metadata != null) {
                final NamedDataSchema metadataTypeSchema = extractSchema(metadata.getType());
                if (metadataTypeSchema != null) {
                    connectSchemaToResource(visitContext, metadataTypeSchema);
                }
            }
        }

        @Override
        public void visitAction(VisitContext visitContext, RecordTemplate parentResource, ResourceLevel resourceLevel, ActionSchema actionSchema) {
            final String returns = actionSchema.getReturns();
            if (returns != null) {
                if (// the parameter type field contains a inline schema, so we traverse into it
                isInlineSchema(returns)) {
                    visitInlineSchema(visitContext, returns);
                } else // otherwise the type field contains the name of a data schema
                {
                    final NamedDataSchema returnsSchema = extractSchema(returns);
                    if (returnsSchema != null) {
                        connectSchemaToResource(visitContext, returnsSchema);
                    }
                }
            }
            final StringArray throwsArray = actionSchema.getThrows();
            if (throwsArray != null) {
                for (String errorName : throwsArray) {
                    final NamedDataSchema errorSchema = extractSchema(errorName);
                    if (errorSchema != null) {
                        connectSchemaToResource(visitContext, errorSchema);
                    }
                }
            }
        }

        private boolean isInlineSchema(String schemaString) {
            return schemaString.startsWith("{");
        }

        private void visitInlineSchema(VisitContext visitContext, String schemaString) {
            DataSchema schema = DataTemplateUtil.parseSchema(schemaString, _schemaResolver);
            if (schema instanceof ArrayDataSchema) {
                DataSchema itemSchema = ((ArrayDataSchema) schema).getItems();
                if (itemSchema instanceof NamedDataSchema) {
                    connectSchemaToResource(visitContext, (NamedDataSchema) itemSchema);
                }
            }
            if (schema instanceof MapDataSchema) {
                DataSchema valueSchema = ((MapDataSchema) schema).getValues();
                if (valueSchema instanceof NamedDataSchema) {
                    connectSchemaToResource(visitContext, (NamedDataSchema) valueSchema);
                }
            }
        }

        private void connectSchemaToResource(VisitContext visitContext, final NamedDataSchema schema) {
            final Node<NamedDataSchema> schemaNode = _relationships.get(schema);
            _dataModels.put(schema.getFullName(), schema);
            final DataSchemaTraverse traveler = new DataSchemaTraverse();
            traveler.traverse(schema, new DataSchemaTraverse.Callback() {

                @Override
                public void callback(List<String> path, DataSchema nestedSchema) {
                    if (nestedSchema instanceof RecordDataSchema && nestedSchema != schema) {
                        final RecordDataSchema nestedRecordSchema = (RecordDataSchema) nestedSchema;
                        _dataModels.put(nestedRecordSchema.getFullName(), nestedRecordSchema);
                        final Node<RecordDataSchema> node = _relationships.get(nestedRecordSchema);
                        schemaNode.addAdjacentNode(node);
                    }
                }
            });
            final Node<ResourceSchema> resourceNode = _relationships.get(visitContext.getParentSchema());
            resourceNode.addAdjacentNode(schemaNode);
            schemaNode.addAdjacentNode(resourceNode);
        }
    };
    ResourceSchemaCollection.visitResources(_resourceSchemas.getResources().values(), visitor);
}
Also used : ResourceSchema(com.linkedin.restli.restspec.ResourceSchema) ResourceLevel(com.linkedin.restli.server.ResourceLevel) MapDataSchema(com.linkedin.data.schema.MapDataSchema) ParameterSchema(com.linkedin.restli.restspec.ParameterSchema) FinderSchema(com.linkedin.restli.restspec.FinderSchema) StringArray(com.linkedin.data.template.StringArray) IdentifierSchema(com.linkedin.restli.restspec.IdentifierSchema) RecordTemplate(com.linkedin.data.template.RecordTemplate) AssociationSchema(com.linkedin.restli.restspec.AssociationSchema) CollectionSchema(com.linkedin.restli.restspec.CollectionSchema) MetadataSchema(com.linkedin.restli.restspec.MetadataSchema) ActionSchema(com.linkedin.restli.restspec.ActionSchema) AssocKeySchema(com.linkedin.restli.restspec.AssocKeySchema) NamedDataSchema(com.linkedin.data.schema.NamedDataSchema) DataSchema(com.linkedin.data.schema.DataSchema) MapDataSchema(com.linkedin.data.schema.MapDataSchema) RecordDataSchema(com.linkedin.data.schema.RecordDataSchema) NamedDataSchema(com.linkedin.data.schema.NamedDataSchema) ArrayDataSchema(com.linkedin.data.schema.ArrayDataSchema) ArrayDataSchema(com.linkedin.data.schema.ArrayDataSchema) RecordDataSchema(com.linkedin.data.schema.RecordDataSchema) DataSchemaTraverse(com.linkedin.data.schema.DataSchemaTraverse)

Aggregations

AssociationSchema (com.linkedin.restli.restspec.AssociationSchema)9 CollectionSchema (com.linkedin.restli.restspec.CollectionSchema)8 ActionSchema (com.linkedin.restli.restspec.ActionSchema)4 ActionSchemaArray (com.linkedin.restli.restspec.ActionSchemaArray)3 FinderSchema (com.linkedin.restli.restspec.FinderSchema)3 FinderSchemaArray (com.linkedin.restli.restspec.FinderSchemaArray)3 SimpleSchema (com.linkedin.restli.restspec.SimpleSchema)3 StringArray (com.linkedin.data.template.StringArray)2 ActionsSetSchema (com.linkedin.restli.restspec.ActionsSetSchema)2 AssocKeySchema (com.linkedin.restli.restspec.AssocKeySchema)2 EntitySchema (com.linkedin.restli.restspec.EntitySchema)2 RestMethodSchema (com.linkedin.restli.restspec.RestMethodSchema)2 RestMethodSchemaArray (com.linkedin.restli.restspec.RestMethodSchemaArray)2 DataList (com.linkedin.data.DataList)1 DataMap (com.linkedin.data.DataMap)1 ArrayDataSchema (com.linkedin.data.schema.ArrayDataSchema)1 DataSchema (com.linkedin.data.schema.DataSchema)1 DataSchemaTraverse (com.linkedin.data.schema.DataSchemaTraverse)1 MapDataSchema (com.linkedin.data.schema.MapDataSchema)1 NamedDataSchema (com.linkedin.data.schema.NamedDataSchema)1