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)); } } }
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); }
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); }
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); }
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 }); } }
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); }
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); }
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); }
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); }
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); }
/// <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); }
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); }
public void Add(Type type, IObjectSpecBuilder spec) { cache.Cache(classStrategy.GetKeyForType(type), spec); }
private ITypicalLengthFacet GetTypicalLengthFacet(IReflector reflector, Type type) { IObjectSpecBuilder paramTypeSpec = reflector.LoadSpecification(type); return(paramTypeSpec.GetFacet <ITypicalLengthFacet>()); }