private void Process(IReflector reflector, Type methodReturnType, ISpecification holder)
        {
            if (!CollectionUtils.IsCollection(methodReturnType))
            {
                return;
            }

            if (methodReturnType.IsArray)
            {
                Type elementType = methodReturnType.GetElementType();
                IObjectSpecBuilder elementSpec = reflector.LoadSpecification(elementType);
                FacetUtils.AddFacet(new ElementTypeFacet(holder, elementType, elementSpec));
                FacetUtils.AddFacet(new TypeOfFacetInferredFromArray(holder));
            }
            else if (methodReturnType.IsGenericType)
            {
                Type[] actualTypeArguments = methodReturnType.GetGenericArguments();
                if (actualTypeArguments.Any())
                {
                    Type elementType = actualTypeArguments.First();
                    IObjectSpecBuilder elementSpec = reflector.LoadSpecification(elementType);
                    FacetUtils.AddFacet(new ElementTypeFacet(holder, elementType, elementSpec));
                    FacetUtils.AddFacet(new TypeOfFacetInferredFromGenerics(holder));
                }
            }
        }
예제 #2
0
        private IObjectSpecBuilder LoadSpecificationAndCache(Type type)
        {
            Type actualType = classStrategy.GetType(type);

            if (actualType == null)
            {
                throw new ReflectionException("Attempting to introspect a non-introspectable type " + type.FullName + " ");
            }

            IObjectSpecBuilder specification = CreateSpecification(actualType);

            if (specification == null)
            {
                throw new ReflectionException("unrecognised type " + actualType.FullName);
            }

            // We need the specification available in cache even though not yet fully introspected
            metamodel.Add(actualType, specification);

            specification.Introspect(facetDecoratorSet, new Introspector(this, metamodel));

            //if (actualType.IsGenericType && actualType.IsConstructedGenericType) {
            //    // introspect any generic type parameters
            //    actualType.GetGenericArguments().ForEach(t => LoadSpecificationAndCache(t));
            //}

            return(specification);
        }
예제 #3
0
        private void PopulateContributedActions(IObjectSpecBuilder spec, Type[] services, IMetamodel metamodel)
        {
            var result = services.
                         AsParallel().
                         Select(serviceType => {
                var serviceSpecification = (IServiceSpecImmutable)metamodel.GetSpecification(serviceType);
                IActionSpecImmutable[] serviceActions = serviceSpecification.ObjectActions.Where(sa => sa != null).ToArray();

                var matchingActionsForObject     = serviceType != spec.Type ? serviceActions.Where(sa => sa.IsContributedTo(spec)).ToList() : new List <IActionSpecImmutable>();
                var matchingActionsForCollection = serviceType != spec.Type ? serviceActions.Where(sa => sa.IsContributedToCollectionOf(spec)).ToList() : new List <IActionSpecImmutable>();
                var finderActions = serviceActions.Where(sa => sa.IsFinderMethodFor(spec)).ToList();

                if (finderActions.Any())
                {
                    finderActions.Sort(new MemberOrderComparator <IActionSpecImmutable>());
                }

                return(new Tuple <List <IActionSpecImmutable>, List <IActionSpecImmutable>, List <IActionSpecImmutable> >(matchingActionsForObject, matchingActionsForCollection, finderActions));
            }).
                         Aggregate(new Tuple <List <IActionSpecImmutable>, List <IActionSpecImmutable>, List <IActionSpecImmutable> >(new List <IActionSpecImmutable>(), new List <IActionSpecImmutable>(), new List <IActionSpecImmutable>()),
                                   (a, t) => {
                a.Item1.AddRange(t.Item1);
                a.Item2.AddRange(t.Item2);
                a.Item3.AddRange(t.Item3);
                return(a);
            });

            spec.AddContributedActions(result.Item1);
            spec.AddCollectionContributedActions(result.Item2);
            spec.AddFinderActions(result.Item3);
        }
        private void PopulateContributedActions(IObjectSpecBuilder spec, Type[] services)
        {
            IList <IActionSpecImmutable> contributedActions       = new List <IActionSpecImmutable>();
            IList <IActionSpecImmutable> collectionContribActions = new List <IActionSpecImmutable>();

            foreach (Type serviceType in services)
            {
                if (serviceType != spec.Type)
                {
                    var serviceSpecification = (IServiceSpecImmutable)metamodel.GetSpecification(serviceType);
                    IActionSpecImmutable[]      serviceActions           = serviceSpecification.ObjectActions.Where(sa => sa != null).ToArray();
                    List <IActionSpecImmutable> matchingActionsForObject = serviceActions.Where(sa => sa.IsContributedTo(spec)).ToList();
                    foreach (IActionSpecImmutable action in matchingActionsForObject)
                    {
                        contributedActions.Add(action);
                    }

                    List <IActionSpecImmutable> matchingActionsForCollection = serviceActions.Where(sa => sa.IsContributedToCollectionOf(spec)).ToList();
                    foreach (IActionSpecImmutable action in matchingActionsForCollection)
                    {
                        collectionContribActions.Add(action);
                    }
                }
            }
            spec.AddContributedActions(contributedActions);
            spec.AddCollectionContributedActions(collectionContribActions);
        }
예제 #5
0
        private void ProcessCollection(IReflector reflector, ISpecification holder)
        {
            Type collectionElementType = typeof(object);
            IObjectSpecBuilder spec    = reflector.LoadSpecification(collectionElementType);

            FacetUtils.AddFacet(new TypeOfFacetDefaultToType(holder, collectionElementType, spec));
            FacetUtils.AddFacet(new CollectionFacet(holder));
        }
 public override void Process(IReflector reflector, Type type, IMethodRemover methodRemover, ISpecificationBuilder specification)
 {
     if (DecimalValueSemanticsProvider.IsAdaptedType(type))
     {
         IObjectSpecBuilder spec = reflector.LoadSpecification(DecimalValueSemanticsProvider.AdaptedType);
         AddValueFacets(new DecimalValueSemanticsProvider(spec, specification), specification);
     }
 }
        private void PopulateContributedActions(IObjectSpecBuilder spec, Type[] services, IMetamodel metamodel)
        {
            var result = services.
                         AsParallel().
                         Select(serviceType => {
                var serviceSpecification = (IServiceSpecImmutable)metamodel.GetSpecification(serviceType);
                IActionSpecImmutable[] serviceActions = serviceSpecification.ObjectActions.Where(sa => sa != null).ToArray();

                var matchingActionsForObject     = new List <IActionSpecImmutable>();
                var matchingActionsForCollection = new List <IActionSpecImmutable>();
                var finderActions = new List <IActionSpecImmutable>();

                foreach (var sa in serviceActions)
                {
                    if (serviceType != spec.Type)
                    {
                        if (sa.IsContributedTo(spec))
                        {
                            matchingActionsForObject.Add(sa);
                        }

                        if (sa.IsContributedToCollectionOf(spec))
                        {
                            matchingActionsForCollection.Add(sa);
                        }
                    }

                    if (sa.IsFinderMethodFor(spec))
                    {
                        finderActions.Add(sa);
                    }
                }

                return(new Tuple <List <IActionSpecImmutable>, List <IActionSpecImmutable>, List <IActionSpecImmutable> >(matchingActionsForObject, matchingActionsForCollection, finderActions.OrderBy(a => a, new MemberOrderComparator <IActionSpecImmutable>()).ToList()));
            }).
                         Aggregate(new Tuple <List <IActionSpecImmutable>, List <IActionSpecImmutable>, List <IActionSpecImmutable> >(new List <IActionSpecImmutable>(), new List <IActionSpecImmutable>(), new List <IActionSpecImmutable>()),
                                   (a, t) => {
                a.Item1.AddRange(t.Item1);
                a.Item2.AddRange(t.Item2);
                a.Item3.AddRange(t.Item3);
                return(a);
            });

            //
            var contribActions = new List <IActionSpecImmutable>();

            // group by service - probably do this better - TODO
            foreach (var service in services)
            {
                var matching = result.Item1.Where(i => i.OwnerSpec.Type == service);
                contribActions.AddRange(matching);
            }

            spec.AddContributedActions(contribActions);
            spec.AddCollectionContributedActions(result.Item2);
            spec.AddFinderActions(result.Item3);
        }
예제 #8
0
        private void InstallSpecification(Type type, bool isService)
        {
            IObjectSpecBuilder spec = LoadSpecification(type);

            // Do this here so that if the service spec was found and loaded earlier for any reason it is still marked
            // as a service
            if (isService)
            {
                spec.MarkAsService();
            }
        }
        public override void Process(IReflector reflector, MethodInfo actionMethod, IMethodRemover methodRemover, ISpecificationBuilder action)
        {
            string capitalizedName = NameUtils.CapitalizeName(actionMethod.Name);

            Type type   = actionMethod.DeclaringType;
            var  facets = new List <IFacet>();
            IObjectSpecBuilder onType     = reflector.LoadSpecification(type);
            IObjectSpecBuilder returnSpec = reflector.LoadSpecification(actionMethod.ReturnType);

            IObjectSpecImmutable elementSpec = null;
            bool isQueryable = IsQueryOnly(actionMethod) || CollectionUtils.IsQueryable(actionMethod.ReturnType);

            if (returnSpec != null && returnSpec.IsCollection)
            {
                Type elementType = CollectionUtils.ElementType(actionMethod.ReturnType);
                elementSpec = reflector.LoadSpecification(elementType);
            }

            RemoveMethod(methodRemover, actionMethod);
            facets.Add(new ActionInvocationFacetViaMethod(actionMethod, onType, returnSpec, elementSpec, action, isQueryable));

            MethodType methodType = actionMethod.IsStatic ? MethodType.Class : MethodType.Object;

            Type[] paramTypes = actionMethod.GetParameters().Select(p => p.ParameterType).ToArray();
            FindAndRemoveValidMethod(reflector, facets, methodRemover, type, methodType, capitalizedName, paramTypes, action);

            DefaultNamedFacet(facets, capitalizedName, action); // must be called after the checkForXxxPrefix methods

            AddHideForSessionFacetNone(facets, action);
            AddDisableForSessionFacetNone(facets, action);
            FindDefaultHideMethod(reflector, facets, methodRemover, type, methodType, "ActionDefault", paramTypes, action);
            FindAndRemoveHideMethod(reflector, facets, methodRemover, type, methodType, capitalizedName, paramTypes, action);
            FindDefaultDisableMethod(reflector, facets, methodRemover, type, methodType, "ActionDefault", paramTypes, action);
            FindAndRemoveDisableMethod(reflector, facets, methodRemover, type, methodType, capitalizedName, paramTypes, action);

            var actionSpecImmutable = action as ActionSpecImmutable;

            if (actionSpecImmutable != null)
            {
                // Process the action's parameters names, descriptions and optional
                // an alternative design would be to have another facet factory processing just ActionParameter, and have it remove these
                // supporting methods.  However, the FacetFactory API doesn't allow for methods of the class to be removed while processing
                // action parameters, only while processing Methods (ie actions)
                IActionParameterSpecImmutable[] actionParameters = actionSpecImmutable.Parameters;
                string[] paramNames = actionMethod.GetParameters().Select(p => p.Name).ToArray();

                FindAndRemoveParametersAutoCompleteMethod(reflector, methodRemover, type, capitalizedName, paramTypes, actionParameters);
                FindAndRemoveParametersChoicesMethod(reflector, methodRemover, type, capitalizedName, paramTypes, paramNames, actionParameters);
                FindAndRemoveParametersDefaultsMethod(reflector, methodRemover, type, capitalizedName, paramTypes, paramNames, actionParameters);
                FindAndRemoveParametersValidateMethod(reflector, methodRemover, type, capitalizedName, paramTypes, paramNames, actionParameters);
            }
            FacetUtils.AddFacets(facets);
        }
        public override void Process(IReflector reflector, Type type, IMethodRemover methodRemover, ISpecificationBuilder specification)
        {
            if (typeof(Enum).IsAssignableFrom(type))
            {
                Type semanticsProviderType           = typeof(EnumValueSemanticsProvider <>).MakeGenericType(type);
                IObjectSpecBuilder spec              = reflector.LoadSpecification(type);
                object             semanticsProvider = Activator.CreateInstance(semanticsProviderType, spec, specification);

                MethodInfo method = typeof(ValueUsingValueSemanticsProviderFacetFactory).GetMethod("AddValueFacets", BindingFlags.Static | BindingFlags.Public).MakeGenericMethod(type);
                method.Invoke(null, new
                              [] { semanticsProvider, specification });
            }
        }
예제 #11
0
        private static void PopulateContributedActions(IObjectSpecBuilder spec, Type[] services, IMetamodel metamodel)
        {
            var(contribActions, collContribActions, finderActions) = services.AsParallel().Select(serviceType => {
                var serviceSpecification = (IServiceSpecImmutable)metamodel.GetSpecification(serviceType);
                var serviceActions       = serviceSpecification.ObjectActions.Where(sa => sa != null).ToArray();

                var matchingActionsForObject     = new List <IActionSpecImmutable>();
                var matchingActionsForCollection = new List <IActionSpecImmutable>();
                var matchingFinderActions        = new List <IActionSpecImmutable>();

                foreach (var sa in serviceActions)
                {
                    if (serviceType != spec.Type)
                    {
                        if (sa.IsContributedTo(spec))
                        {
                            matchingActionsForObject.Add(sa);
                        }

                        if (sa.IsContributedToCollectionOf(spec))
                        {
                            matchingActionsForCollection.Add(sa);
                        }
                    }

                    if (sa.IsFinderMethodFor(spec))
                    {
                        matchingFinderActions.Add(sa);
                    }
                }

                return(matchingActionsForObject, matchingActionsForCollection, matchingFinderActions.OrderBy(a => a, new MemberOrderComparator <IActionSpecImmutable>()).ToList());
            }).Aggregate((new List <IActionSpecImmutable>(), new List <IActionSpecImmutable>(), new List <IActionSpecImmutable>()),
                         (a, t) => {
                var(contrib, collContrib, finder) = a;
                var(ca, cca, fa) = t;
                contrib.AddRange(ca);
                collContrib.AddRange(cca);
                finder.AddRange(fa);
                return(a);
            });

            var groupedContribActions = contribActions.GroupBy(i => i.OwnerSpec.Type, i => i, (service, actions) => new { service, actions }).OrderBy(a => Array.IndexOf(services, a.service)).SelectMany(a => a.actions).ToList();

            spec.AddContributedActions(groupedContribActions);
            spec.AddCollectionContributedActions(collContribActions);
            spec.AddFinderActions(finderActions);
        }
        private void PopulateAssociatedActions(IObjectSpecBuilder spec, Type[] services)
        {
            if (string.IsNullOrWhiteSpace(spec.FullName))
            {
                string id = (spec.Identifier != null ? spec.Identifier.ClassName : "unknown") ?? "unknown";
                Log.WarnFormat("Specification with id : {0} as has null or empty name", id);
            }

            if (TypeUtils.IsSystem(spec.FullName) && !spec.IsCollection)
            {
                return;
            }
            if (TypeUtils.IsNakedObjects(spec.FullName))
            {
                return;
            }

            PopulateContributedActions(spec, services);
            PopulateFinderActions(spec, services);
        }
예제 #13
0
        private void PopulateAssociatedActions(IObjectSpecBuilder spec, Type[] services, IMetamodelBuilder metamodel)
        {
            if (string.IsNullOrWhiteSpace(spec.FullName))
            {
                var id = spec.Identifier?.ClassName ?? "unknown";
                logger.LogWarning($"Specification with id : {id} has null or empty name");
            }

            if (FasterTypeUtils.IsSystem(spec.FullName) && !spec.IsCollection)
            {
                return;
            }

            if (FasterTypeUtils.IsNakedObjects(spec.FullName))
            {
                return;
            }

            PopulateContributedActions(spec, services, metamodel);
        }
예제 #14
0
        private void PopulateFinderActions(IObjectSpecBuilder spec, Type[] services)
        {
            IList <IActionSpecImmutable> finderActions = new List <IActionSpecImmutable>();

            foreach (Type serviceType in services)
            {
                IObjectSpecImmutable        serviceSpecification = metamodel.GetSpecification(serviceType);
                List <IActionSpecImmutable> matchingActions      = serviceSpecification.ObjectActions.Where(a => a.IsFinderMethod).Where(serviceAction => serviceAction.IsFinderMethodFor(spec)).ToList();

                if (matchingActions.Any())
                {
                    matchingActions.Sort(new MemberOrderComparator <IActionSpecImmutable>());
                    foreach (IActionSpecImmutable action in matchingActions)
                    {
                        finderActions.Add(action);
                    }
                }
            }
            spec.AddFinderActions(finderActions);
        }
예제 #15
0
        public void IntrospectType(Type typeToIntrospect, IObjectSpecImmutable spec)
        {
            Log.InfoFormat("introspecting {0}: class-level details", typeToIntrospect.FullName);

            if (!TypeUtils.IsPublic(typeToIntrospect))
            {
                throw new ReflectionException(string.Format(Resources.NakedObjects.DomainClassReflectionError, typeToIntrospect));
            }

            introspectedType = typeToIntrospect;
            properties       = typeToIntrospect.GetProperties();
            methods          = GetNonPropertyMethods();

            // Process facets at object level
            // this will also remove some methods, such as the superclass methods.
            var methodRemover = new IntrospectorMethodRemover(methods);

            FacetFactorySet.Process(reflector, introspectedType, methodRemover, spec);

            if (SuperclassType != null && ClassStrategy.IsTypeToBeIntrospected(SuperclassType))
            {
                Superclass = reflector.LoadSpecification(SuperclassType);
            }

            AddAsSubclass(spec);

            var interfaces = new List <IObjectSpecBuilder>();

            foreach (Type interfaceType in InterfacesTypes)
            {
                if (interfaceType != null && ClassStrategy.IsTypeToBeIntrospected(interfaceType))
                {
                    IObjectSpecBuilder interfaceSpec = reflector.LoadSpecification(interfaceType);
                    interfaceSpec.AddSubclass(spec);
                    interfaces.Add(interfaceSpec);
                }
            }
            Interfaces = interfaces.ToArray();
            IntrospectPropertiesAndCollections(spec);
            IntrospectActions(spec);
        }
        public override void ProcessParams(IReflector reflector, MethodInfo method, int paramNum, ISpecificationBuilder holder)
        {
            ParameterInfo parameter = method.GetParameters()[paramNum];
            var           facets    = new List <IFacet>();

            if (parameter.ParameterType.IsGenericType && (parameter.ParameterType.GetGenericTypeDefinition() == typeof(Nullable <>)))
            {
                facets.Add(new NullableFacetAlways(holder));
            }

            IObjectSpecBuilder returnSpec = reflector.LoadSpecification(parameter.ParameterType);

            if (returnSpec != null && returnSpec.IsCollection)
            {
                Type elementType = CollectionUtils.ElementType(parameter.ParameterType);
                IObjectSpecImmutable elementSpec = reflector.LoadSpecification(elementType);
                facets.Add(new ElementTypeFacet(holder, elementType, elementSpec));
            }

            FacetUtils.AddFacets(facets);
        }
예제 #17
0
        private IEnumerable <IAssociationSpecImmutable> CreateCollectionSpecs(IEnumerable <PropertyInfo> collectionProperties, IObjectSpecImmutable spec)
        {
            var specs = new List <IAssociationSpecImmutable>();

            foreach (PropertyInfo property in collectionProperties)
            {
                Log.DebugFormat("Identified one-many association method {0}", property);

                IIdentifier identifier = new IdentifierImpl(metamodel, FullName, property.Name);

                // create a collection property spec
                Type returnType = property.PropertyType;
                IObjectSpecBuilder returnSpec = reflector.LoadSpecification(returnType);
                Type defaultType = typeof(object);
                IObjectSpecBuilder defaultSpec = reflector.LoadSpecification(defaultType);
                var collection = new OneToManyAssociationSpecImmutable(identifier, spec, returnSpec, defaultSpec);

                FacetFactorySet.Process(reflector, property, new IntrospectorMethodRemover(methods), collection, FeatureType.Collections);
                specs.Add(collection);
            }
            return(specs);
        }
예제 #18
0
        /// <summary>
        ///     Creates a list of Association fields for all the properties that use NakedObjects.
        /// </summary>
        private IEnumerable <IAssociationSpecImmutable> CreateRefPropertySpecs(IEnumerable <PropertyInfo> foundProperties, IObjectSpecImmutable spec)
        {
            var specs = new List <IAssociationSpecImmutable>();

            foreach (PropertyInfo property in foundProperties)
            {
                Log.DebugFormat("Identified 1-1 association method {0}", property);
                Log.DebugFormat("One-to-One association {0} -> {1}", property.Name, property);

                // create a reference property spec
                var  identifier   = new IdentifierImpl(metamodel, FullName, property.Name);
                Type propertyType = property.PropertyType;
                IObjectSpecBuilder propertySpec = reflector.LoadSpecification(propertyType);
                var referenceProperty           = new OneToOneAssociationSpecImmutable(identifier, spec, propertySpec);

                // Process facets for the property
                FacetFactorySet.Process(reflector, property, new IntrospectorMethodRemover(methods), referenceProperty, FeatureType.Property);
                specs.Add(referenceProperty);
            }

            return(specs);
        }
예제 #19
0
        private void PopulateFinderActions(IObjectSpecBuilder spec, Type[] services)
        {
            IList <IActionSpecImmutable> finderActions = new List <IActionSpecImmutable>();

            foreach (var serviceType in services)
            {
                var serviceSpecification = (IServiceSpecImmutable)metamodel.GetSpecification(serviceType);
                var matchingActions      =
                    serviceSpecification.ObjectActions.Where(serviceAction => serviceAction.IsFinderMethodFor(spec)).ToList();

                if (matchingActions.Any())
                {
                    var orderedActions = matchingActions.OrderBy(a => a, new MemberOrderComparator <IActionSpecImmutable>());
                    foreach (var action in orderedActions)
                    {
                        finderActions.Add(action);
                    }
                }
            }

            spec.AddFinderActions(finderActions);
        }
        private void Process(IReflector reflector, MethodInfo member, ISpecification holder)
        {
            ParameterInfo[] paramsWithAttribute = member.GetParameters().Where(p => p.GetCustomAttribute <ContributedActionAttribute>() != null).ToArray();
            if (!paramsWithAttribute.Any())
            {
                return;                             //Nothing to do
            }
            var facet = new ContributedActionFacet(holder);

            foreach (ParameterInfo p in paramsWithAttribute)
            {
                var attribute           = p.GetCustomAttribute <ContributedActionAttribute>();
                IObjectSpecBuilder type = reflector.LoadSpecification(p.ParameterType);
                if (type != null)
                {
                    //TODO: This guard is really only there for a unit test -  SMELL! Should be mocked out
                    if (type.IsCollection)
                    {
                        //TODO:  Will the return type Spec always exist by this point?
                        IObjectSpecBuilder returnType = reflector.LoadSpecification(member.ReturnType);
                        if (!returnType.IsCollection)
                        {
                            //Don't allow collection-contributed actions that return collections
                            Type elementType = p.ParameterType.GetGenericArguments()[0];
                            type = reflector.LoadSpecification(elementType);
                            facet.AddCollectionContributee(type, attribute.SubMenu, attribute.Id);
                        }
                    }
                    else
                    {
                        facet.AddObjectContributee(type, attribute.SubMenu, attribute.Id);
                    }
                }
            }
            FacetUtils.AddFacet(facet);
        }
예제 #21
0
 public void Add(Type type, IObjectSpecBuilder spec)
 {
     cache.Cache(classStrategy.GetKeyForType(type), spec);
 }
예제 #22
0
        private ITypicalLengthFacet GetTypicalLengthFacet(IReflector reflector, Type type)
        {
            IObjectSpecBuilder paramTypeSpec = reflector.LoadSpecification(type);

            return(paramTypeSpec.GetFacet <ITypicalLengthFacet>());
        }