Exemplo n.º 1
0
 public Metadata()
 {
     ShowDisplay = true;
     ShowEditor = true;
     rules = new List<IRule>();
     properties = new PropertiesMetadata();
 }
        public void SetProperty <T>(string name, T value)
        {
            var p = PropertiesMetadata.FirstOrDefault(v => v.Name == name);

            if (p != null)
            {
                // Type should match
                if (p.Type != value.GetType())
                {
                    throw new InvalidCastException();
                }
            }
            else
            {
                if (AllowDynamicProperties)
                {
                    p = new DynamicPropertyMetadata(name, value.GetType());
                    p.SaveTypeInfo = true;
                    PropertiesMetadata.Add(p);
                }
                else
                {
                    throw new InvalidPropertyException();
                }
            }

            Dictionary[name] = value;
            RaisePropertyChanged(name);
        }
        public string Save()
        {
            var sb = new StringBuilder();

            using (var xw = XmlWriter.Create(sb, new XmlWriterSettings
            {
                OmitXmlDeclaration = true,
                ConformanceLevel = ConformanceLevel.Fragment,
                Indent = true
            }))
            {
                foreach (var o in Dictionary)
                {
                    var propertyDefinition = PropertiesMetadata.Single(x => x.Name == o.Key);

                    if ((propertyDefinition.Options & DynamicPropertyMetadataOptions.Save) == DynamicPropertyMetadataOptions.None)
                    {
                        continue;
                    }

                    var s = new DataContractSerializer(o.Value.GetType(), null);

                    xw.WriteStartElement(o.Key);

                    if (propertyDefinition.SaveTypeInfo)
                    {
                        xw.WriteAttributeString("t", GetTypeFullName(propertyDefinition.Type));
                    }

                    object content = o.Value;
                    if (content is DateTime)
                    {
                        content = DateTime.SpecifyKind((DateTime)content, DateTimeKind.Unspecified);
                    }

                    if (ShouldWriteContent(o.Value.GetType()))
                    {
                        s.WriteObjectContent(xw, content);
                    }
                    else
                    {
                        s.WriteObject(xw, content);
                    }

                    xw.WriteEndElement();
                }
            }

            return(sb.ToString());
        }
        public void Load(string xml)
        {
            var root = XElement.Parse("<a>" + xml + "</a>");

            Dictionary.Clear();

            var b = new StringBuilder();

            foreach (var element in root.Elements())
            {
                Type type = null;

                var typeAttribute = element.Attribute("t");
                if (typeAttribute != null)
                {
                    type = GetType(typeAttribute.Value);
                }
                else
                {
                    var dynamicPropertyMetadata =
                        PropertiesMetadata.FirstOrDefault(x => x.Name == element.Name.LocalName);
                    if (dynamicPropertyMetadata == null)
                    {
                        throw new InvalidPropertyException();
                    }
                    type = dynamicPropertyMetadata.Type;
                }

                var s = new DataContractSerializer(type);

                using (var reader = ShouldWriteContent(type)
                                        ? element.CreateReader()
                                        : element.Elements().Single().CreateReader())
                {
                    var obj = s.ReadObject(reader, false);
                    SetProperty(element.Name.LocalName, obj);
                }
            }

            RefreshProxy();
        }
        public T GetProperty <T>(string name)
        {
            object value;

            if (Dictionary.TryGetValue(name, out value))
            {
                return((T)value);
            }

            var p = PropertiesMetadata.FirstOrDefault(v => v.Name == name);

            if (p != null)
            {
                return((T)(p.Type.IsValueType ? Activator.CreateInstance(p.Type) : null));
            }
            if (AllowDynamicProperties)
            {
                return(default(T));
            }

            throw new InvalidPropertyException();
        }
        public DocumentBuilder(System.Type clazz, Analyzer defaultAnalyzer, IDirectoryProvider[] directoryProviders,
            IIndexShardingStrategy shardingStrategy)
        {
            analyzer = new ScopedAnalyzer();
            beanClass = clazz;
            this.directoryProviders = directoryProviders;
            this.shardingStrategy = shardingStrategy;

            if (clazz == null) throw new AssertionFailure("Unable to build a DocumemntBuilder with a null class");

            rootPropertiesMetadata = new PropertiesMetadata();
            rootPropertiesMetadata.boost = GetBoost(clazz);
            rootPropertiesMetadata.analyzer = defaultAnalyzer;

            Set<System.Type> processedClasses = new HashedSet<System.Type>();
            processedClasses.Add(clazz);
            InitializeMembers(clazz, rootPropertiesMetadata, true, string.Empty, processedClasses);
            //processedClasses.remove( clazz ); for the sake of completness
            analyzer.GlobalAnalyzer = rootPropertiesMetadata.analyzer;
            if (idKeywordName == null)
                throw new SearchException("No document id for: " + clazz.Name);
        }
        private void InitializeMembers(
            System.Type clazz, PropertiesMetadata propertiesMetadata, bool isRoot, String prefix,
            ISet<System.Type> processedClasses)
        {
            IList<System.Type> hierarchy = new List<System.Type>();
            System.Type currClass = clazz;
            do
            {
                hierarchy.Add(currClass);
                currClass = currClass.BaseType;
                // NB Java stops at null we stop at object otherwise we process the class twice
                // We also need a null test for things like ISet which have no base class/interface
            } while (currClass != null && currClass != typeof(object));

            for (int index = hierarchy.Count - 1; index >= 0; index--)
            {
                currClass = hierarchy[index];
                /**
                 * Override the default analyzer for the properties if the class hold one
                 * That's the reason we go down the hierarchy
                 */

                // NB Must cast here as we want to look at the type's metadata
                Analyzer localAnalyzer = GetAnalyzer(currClass as MemberInfo);
                if (localAnalyzer != null)
                {
                    propertiesMetadata.analyzer = localAnalyzer;
                }

                // Check for any ClassBridges
                List<ClassBridgeAttribute> classBridgeAnn = AttributeUtil.GetClassBridges(currClass);
                if (classBridgeAnn != null)
                {
                    // Ok, pick up the parameters as well
                    AttributeUtil.GetClassBridgeParameters(currClass, classBridgeAnn);

                    // Now we can process the class bridges
                    foreach (ClassBridgeAttribute cb in classBridgeAnn)
                    {
                        BindClassAnnotation(prefix, propertiesMetadata, cb);
                    }
                }

                // NB As we are walking the hierarchy only retrieve items at this level
                PropertyInfo[] propertyInfos =
                    currClass.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Public |
                                            BindingFlags.Instance);
                foreach (PropertyInfo propertyInfo in propertyInfos)
                {
                    InitializeMember(propertyInfo, propertiesMetadata, isRoot, prefix, processedClasses);
                }

                FieldInfo[] fields =
                    clazz.GetFields(BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Public |
                                    BindingFlags.Instance);
                foreach (FieldInfo fieldInfo in fields)
                {
                    InitializeMember(fieldInfo, propertiesMetadata, isRoot, prefix, processedClasses);
                }
            }
        }
        private void InitializeMember(
            MemberInfo member, PropertiesMetadata propertiesMetadata, bool isRoot,
            String prefix, ISet<System.Type> processedClasses)
        {
            DocumentIdAttribute documentIdAnn = AttributeUtil.GetDocumentId(member);
            if (documentIdAnn != null)
            {
                if (isRoot)
                {
                    if (idKeywordName != null)
                    {
                        throw new AssertionFailure("Two document id assigned: " + idKeywordName + " and " + documentIdAnn.Name ?? "'Unknown'");
                    }

                    idKeywordName = prefix + documentIdAnn.Name;
                    IFieldBridge fieldBridge = BridgeFactory.GuessType(member);
                    if (fieldBridge is ITwoWayFieldBridge)
                    {
                        idBridge = (ITwoWayFieldBridge)fieldBridge;
                    }
                    else
                    {
                        throw new SearchException("Bridge for document id does not implement TwoWayFieldBridge: " + member.Name);
                    }

                    idBoost = GetBoost(member);
                    SetAccessible(member);
                    idGetter = member;
                }
                else
                {
                    // Component should index their document id
                    SetAccessible(member);
                    propertiesMetadata.fieldGetters.Add(member);
                    string fieldName = prefix + BinderHelper.GetAttributeName(member, documentIdAnn.Name);
                    propertiesMetadata.fieldNames.Add(fieldName);
                    propertiesMetadata.fieldStore.Add(GetStore(Attributes.Store.Yes));
                    propertiesMetadata.fieldIndex.Add(GetIndex(Index.UnTokenized));
                    propertiesMetadata.fieldBridges.Add(BridgeFactory.GuessType(member));

                    // Property > entity analyzer - no field analyzer
                    Analyzer memberAnalyzer = GetAnalyzer(member) ?? propertiesMetadata.analyzer;
                    if (memberAnalyzer == null)
                    {
                        throw new NotSupportedException("Analyzer should not be undefined");
                    }

                    analyzer.AddScopedAnalyzer(fieldName, memberAnalyzer);
                }
            }

            List<FieldAttribute> fieldAttributes = AttributeUtil.GetFields(member);
            if (fieldAttributes != null)
            {
                foreach (FieldAttribute fieldAnn in fieldAttributes)
                {
                    BindFieldAnnotation(member, propertiesMetadata, prefix, fieldAnn);
                }
            }

            IndexedEmbeddedAttribute embeddedAttribute = AttributeUtil.GetAttribute<IndexedEmbeddedAttribute>(member);
            if (embeddedAttribute != null)
            {
                int oldMaxLevel = maxLevel;
                int potentialLevel = embeddedAttribute.Depth + level;
                if (potentialLevel < 0)
                {
                    potentialLevel = int.MaxValue;
                }

                maxLevel = potentialLevel > maxLevel ? maxLevel : potentialLevel;
                level++;

                System.Type elementType = embeddedAttribute.TargetElement ?? GetMemberTypeOrGenericArguments(member);

                if (maxLevel == int.MaxValue && processedClasses.Contains(elementType))
                {
                    throw new SearchException(
                            string.Format(
                                    "Circular reference, Duplicate use of {0} in root entity {1}#{2}",
                                    elementType.FullName,
                                    beanClass.FullName,
                                    BuildEmbeddedPrefix(prefix, embeddedAttribute, member)));
                }

                if (level <= maxLevel)
                {
                    processedClasses.Add(elementType); // push

                    SetAccessible(member);
                    propertiesMetadata.embeddedGetters.Add(member);
                    PropertiesMetadata metadata = new PropertiesMetadata();
                    propertiesMetadata.embeddedPropertiesMetadata.Add(metadata);
                    metadata.boost = GetBoost(member);
                    // property > entity analyzer
                    metadata.analyzer = GetAnalyzer(member) ?? propertiesMetadata.analyzer;
                    string localPrefix = BuildEmbeddedPrefix(prefix, embeddedAttribute, member);
                    InitializeMembers(elementType, metadata, false, localPrefix, processedClasses);

                    /**
                     * We will only index the "expected" type but that's OK, HQL cannot do downcasting either
                     */
                    // ayende: because we have to deal with generic collections here, we aren't
                    // actually using the element type to determine what the value is, since that
                    // was resolved to the element type of the possible collection
                    Type actualFieldType = GetMemberTypeOrGenericCollectionType(member);
                    if (actualFieldType.IsArray)
                    {
                        propertiesMetadata.embeddedContainers.Add(Container.Array);
                    }
                    else if (typeof(IDictionary).IsAssignableFrom(actualFieldType) || typeof(IDictionary<,>).IsAssignableFrom(actualFieldType))
                    {
                        propertiesMetadata.embeddedContainers.Add(Container.Map);
                    }
                    else if (typeof(ICollection).IsAssignableFrom(actualFieldType))
                    {
                        propertiesMetadata.embeddedContainers.Add(Container.Collection);
                    }
                    else if (typeof(IEnumerable).IsAssignableFrom(actualFieldType))
                    {
                        // NB We only see ISet as IEnumerable
                        propertiesMetadata.embeddedContainers.Add(Container.Collection);
                    }
                    else
                    {
                        propertiesMetadata.embeddedContainers.Add(Container.Object);
                    }

                    processedClasses.Remove(actualFieldType); // pop
                }
                else if (logger.IsDebugEnabled)
                {
                    string localPrefix = BuildEmbeddedPrefix(prefix, embeddedAttribute, member);
                    logger.Debug("Depth reached, ignoring " + localPrefix);
                }

                level--;
                maxLevel = oldMaxLevel; // set back the old max level
            }

            ContainedInAttribute containedInAttribute = AttributeUtil.GetAttribute<ContainedInAttribute>(member);
            if (containedInAttribute != null)
            {
                SetAccessible(member);
                propertiesMetadata.containedInGetters.Add(member);
            }
        }
        private void BindFieldAnnotation(MemberInfo member, PropertiesMetadata propertiesMetadata, string prefix,
            FieldAttribute fieldAnn)
        {
            SetAccessible(member);
            propertiesMetadata.fieldGetters.Add(member);
            string fieldName = prefix + BinderHelper.GetAttributeName(member, fieldAnn.Name);
            propertiesMetadata.fieldNames.Add(prefix + fieldAnn.Name);
            propertiesMetadata.fieldStore.Add(GetStore(fieldAnn.Store));
            propertiesMetadata.fieldIndex.Add(GetIndex(fieldAnn.Index));
            propertiesMetadata.fieldBridges.Add(BridgeFactory.GuessType(member));

            // Field > property > entity analyzer
            Analyzer localAnalyzer = (GetAnalyzer(fieldAnn.Analyzer) ?? GetAnalyzer(member)) ??
                                     propertiesMetadata.analyzer;
            if (localAnalyzer == null)
            {
                throw new NotSupportedException("Analyzer should not be undefined");
            }

            analyzer.AddScopedAnalyzer(fieldName, localAnalyzer);
        }
Exemplo n.º 10
0
        private void BindClassAnnotation(string prefix, PropertiesMetadata propertiesMetadata, ClassBridgeAttribute ann)
        {
            // TODO: Name should be prefixed - NB is this still true?
            string fieldName = prefix + ann.Name;
            propertiesMetadata.classNames.Add(fieldName);
            propertiesMetadata.classStores.Add(GetStore(ann.Store));
            propertiesMetadata.classIndexes.Add(GetIndex(ann.Index));
            propertiesMetadata.classBridges.Add(BridgeFactory.ExtractType(ann));
            propertiesMetadata.classBoosts.Add(ann.Boost);

            Analyzer classAnalyzer = GetAnalyzer(ann.Analyzer) ?? propertiesMetadata.analyzer;
            if (classAnalyzer == null)
            {
                throw new NotSupportedException("Analyzer should not be undefined");
            }

            analyzer.AddScopedAnalyzer(fieldName, classAnalyzer);
        }
Exemplo n.º 11
0
 private static void ProcessFieldsForProjection(PropertiesMetadata metadata, String[] fields, Object[] result,
     Document document)
 {
     int nbrFoEntityFields = metadata.fieldNames.Count;
     for (int index = 0; index < nbrFoEntityFields; index++)
     {
         PopulateResult(metadata.fieldNames[index],
                        metadata.fieldBridges[index],
                        metadata.fieldStore[index],
                        fields,
                        result,
                        document
             );
     }
     int nbrOfEmbeddedObjects = metadata.embeddedPropertiesMetadata.Count;
     for (int index = 0; index < nbrOfEmbeddedObjects; index++)
     {
         // there is nothing we can do for collections
         if (metadata.embeddedContainers[index] == Container.Object)
         {
             ProcessFieldsForProjection(metadata.embeddedPropertiesMetadata[index], fields, result, document);
         }
     }
 }
Exemplo n.º 12
0
        private static void ProcessContainedIn(Object instance, List<LuceneWork> queue, PropertiesMetadata metadata,
            ISearchFactoryImplementor searchFactoryImplementor)
        {
            for (int i = 0; i < metadata.containedInGetters.Count; i++)
            {
                MemberInfo member = metadata.containedInGetters[i];
                object value = GetMemberValue(instance, member);

                if (value == null) continue;

                Array array = value as Array;
                if (array != null)
                {
                    foreach (object arrayValue in array)
                    {
                        // Highly inneficient but safe wrt the actual targeted class, e.g. polymorphic items in the array
                        System.Type valueType = NHibernateUtil.GetClass(arrayValue);
                        if (valueType == null || !searchFactoryImplementor.DocumentBuilders.ContainsKey(valueType))
                        {
                            continue;
                        }

                        ProcessContainedInValue(arrayValue, queue, valueType, searchFactoryImplementor.DocumentBuilders[valueType],
                                                searchFactoryImplementor);
                    }
                }
                else if (typeof(IEnumerable).IsAssignableFrom(value.GetType()))
                {
                    // NB We only see ISet and IDictionary`2 as IEnumerable
                    IEnumerable collection = value as IEnumerable;
                    if (typeof(IDictionary).IsAssignableFrom(value.GetType()))
                    {
                        collection = ((IDictionary) value).Values;
                    }

                    if (collection == null)
                    {
                        continue;
                    }

                    foreach (object collectionValue in collection)
                    {
                        // Highly inneficient but safe wrt the actual targeted class, e.g. polymorphic items in the array
                        System.Type valueType = NHibernateUtil.GetClass(collectionValue);
                        if (valueType == null || !searchFactoryImplementor.DocumentBuilders.ContainsKey(valueType))
                        {
                            continue;
                        }

                        ProcessContainedInValue(collectionValue, queue, valueType,
                                                searchFactoryImplementor.DocumentBuilders[valueType], searchFactoryImplementor);
                    }
                }
                else
                {
                    System.Type valueType = NHibernateUtil.GetClass(value);
                    if (valueType == null || !searchFactoryImplementor.DocumentBuilders.ContainsKey(valueType))
                    {
                        continue;
                    }

                    ProcessContainedInValue(value, queue, valueType, searchFactoryImplementor.DocumentBuilders[valueType],
                                            searchFactoryImplementor);
                }
            }
            //an embedded cannot have a useful @ContainedIn (no shared reference)
            //do not walk through them
        }
Exemplo n.º 13
0
        private static void BuildDocumentFields(Object instance, Document doc, PropertiesMetadata propertiesMetadata)
        {
            if (instance == null)
            {
                return;
            }

            object unproxiedInstance = Unproxy(instance);

            for (int i = 0; i < propertiesMetadata.classBridges.Count; i++)
            {
                IFieldBridge fb = propertiesMetadata.classBridges[i];

                try
                {
                    fb.Set(propertiesMetadata.classNames[i],
                           unproxiedInstance,
                           doc,
                           propertiesMetadata.classStores[i],
                           propertiesMetadata.classIndexes[i],
                           propertiesMetadata.classBoosts[i]);
                }
                catch (Exception e)
                {
                    logger.Error(
                        string.Format(CultureInfo.InvariantCulture, "Error processing class bridge for {0}",
                                      propertiesMetadata.classNames[i]), e);
                }
            }

            for (int i = 0; i < propertiesMetadata.fieldNames.Count; i++)
            {
                try
                {
                    MemberInfo member = propertiesMetadata.fieldGetters[i];
                    Object value = GetMemberValue(unproxiedInstance, member);
                    propertiesMetadata.fieldBridges[i].Set(
                        propertiesMetadata.fieldNames[i],
                        value,
                        doc,
                        propertiesMetadata.fieldStore[i],
                        propertiesMetadata.fieldIndex[i],
                        GetBoost(member));
                }
                catch (Exception e)
                {
                    logger.Error(
                        string.Format(CultureInfo.InvariantCulture, "Error processing field bridge for {0}.{1}",
                                      unproxiedInstance.GetType().FullName, propertiesMetadata.fieldNames[i]), e);
                }
            }

            for (int i = 0; i < propertiesMetadata.embeddedGetters.Count; i++)
            {
                MemberInfo member = propertiesMetadata.embeddedGetters[i];
                Object value = GetMemberValue(unproxiedInstance, member);
                //TODO handle boost at embedded level: already stored in propertiesMedatada.boost

                if (value == null)
                {
                    continue;
                }

                PropertiesMetadata embeddedMetadata = propertiesMetadata.embeddedPropertiesMetadata[i];
                try
                {
                    switch (propertiesMetadata.embeddedContainers[i])
                    {
                        case Container.Array:
                            foreach (object arrayValue in value as Array)
                            {
                                BuildDocumentFields(arrayValue, doc, embeddedMetadata);
                            }
                            break;

                        case Container.Collection:
                            // Need to cast down to IEnumerable to support ISet
                            foreach (object collectionValue in value as IEnumerable)
                            {
                                BuildDocumentFields(collectionValue, doc, embeddedMetadata);
                            }
                            break;

                        case Container.Map:
                            foreach (object collectionValue in (value as IDictionary).Values)
                            {
                                BuildDocumentFields(collectionValue, doc, embeddedMetadata);
                            }
                            break;

                        case Container.Object:
                            BuildDocumentFields(value, doc, embeddedMetadata);
                            break;

                        default:
                            throw new NotSupportedException("Unknown embedded container: " +
                                                            propertiesMetadata.embeddedContainers[i]);
                    }
                }
                catch (NullReferenceException)
                {
                    logger.Error(string.Format("Null reference whilst processing {0}.{1}, container type {2}",
                                               instance.GetType().FullName,
                                               member.Name, propertiesMetadata.embeddedContainers[i]));
                }
            }
        }