/// <summary>
        /// This method is called before the result of a mutating operation
        /// represented by the specified entry object is committed into the
        /// underlying cache.
        /// </summary>
        /// <remarks>
        /// An implementation of this method can evaluate the change by
        /// analyzing the original and the new value, and can perform any of
        /// the following:
        /// <list type="bullet">
        /// <item>
        /// override the requested change by setting
        /// <see cref="IInvocableCacheEntry.Value"/> to a different value;
        /// </item>
        /// <item>
        /// undo the pending change by resetting the entry value to the
        /// original value obtained from
        /// <see cref="ICacheTriggerEntry.OriginalValue"/>
        /// </item>
        /// <item>
        /// remove the entry from the underlying cache by calling
        /// <see cref="IInvocableCacheEntry.Remove"/>
        /// </item>
        /// <item>
        /// reject the pending change by throwing an <see cref="Exception"/>,
        /// which will prevent any changes from being committed, and will
        /// result in the exception being thrown from the operation that
        /// attempted to modify the cache; or
        /// </item>
        /// <item>
        /// do nothing, thus allowing the pending change to be committed to
        /// the underlying cache.
        /// </item>
        /// </list>
        /// </remarks>
        /// <param name="entry">
        /// An <see cref="ICacheTriggerEntry"/> object that represents the
        /// pending change to be committed to the cache, as well as the
        /// original state of the entry.
        /// </param>
        public virtual void Process(ICacheTriggerEntry entry)
        {
            if (entry.IsPresent && !InvocableCacheHelper.EvaluateEntry(m_filter, entry))
            {
                switch (m_action)
                {
                case ActionCode.Rollback:
                default:
                    throw new ArgumentException("Rejecting " + entry +
                                                " by trigger " + this);

                case ActionCode.Ignore:
                    object value = entry.OriginalValue;
                    if (value != null || entry.IsOriginalPresent)
                    {
                        entry.SetValue(value, true);
                    }
                    else
                    {
                        entry.Remove(true);
                    }
                    break;

                case ActionCode.Remove:
                    entry.Remove(true);
                    break;
                }
            }
        }
예제 #2
0
 /// <summary>
 /// Process an <see cref="IInvocableCacheEntry"/>.
 /// </summary>
 /// <param name="entry">
 /// The <b>IInvocableCacheEntry</b> to process.
 /// </param>
 /// <returns>
 /// The result of the processing, if any.
 /// </returns>
 public override object Process(IInvocableCacheEntry entry)
 {
     if (InvocableCacheHelper.EvaluateEntry(m_filter, entry))
     {
         return(m_processor.Process(entry));
     }
     return(null);
 }
예제 #3
0
        /// <summary>
        /// Apply the test to an <see cref="ICacheEntry"/>.
        /// </summary>
        /// <param name="entry">
        /// The <b>ICacheEntry</b> to evaluate; never <c>null</c>.
        /// </param>
        /// <returns>
        /// <b>true</b> if the test passes, <b>false</b> otherwise.
        /// </returns>
        public new virtual bool EvaluateEntry(ICacheEntry entry)
        {
            IValueExtractor extractor = ValueExtractor;

            return(EvaluateExtracted(entry is IQueryCacheEntry
                    ? ((IQueryCacheEntry)entry).Extract(extractor)
                    : InvocableCacheHelper.ExtractFromEntry(extractor, entry)));
        }
예제 #4
0
 /// <summary>
 /// Process an <see cref="IInvocableCacheEntry"/>.
 /// </summary>
 /// <param name="entry">
 /// The <b>IInvocableCacheEntry</b> to process.
 /// </param>
 /// <returns>
 /// The result of the processing, if any.
 /// </returns>
 public override object Process(IInvocableCacheEntry entry)
 {
     if (entry.IsPresent && InvocableCacheHelper.EvaluateEntry(m_filter, entry))
     {
         entry.Remove(false);
         return(null);
     }
     return(m_return ? entry.Value : null);
 }
 /// <summary>
 /// Process an <see cref="IInvocableCacheEntry"/>.
 /// </summary>
 /// <param name="entry">
 /// The <b>IInvocableCacheEntry</b> to process.
 /// </param>
 /// <returns>
 /// The result of the processing, if any.
 /// </returns>
 public override object Process(IInvocableCacheEntry entry)
 {
     if (InvocableCacheHelper.EvaluateEntry(m_filter, entry))
     {
         entry.SetValue(m_value, false);
         return(null);
     }
     return(m_return ? entry.Value : null);
 }
 /// <summary>
 /// Extract the "old" value from the specified entry.
 /// </summary>
 /// <param name="entry">
 /// The entry to extract the "old" value from.
 /// </param>
 /// <returns>
 /// The extracted "old" value, or NO_VALUE if the extraction failed.
 /// </returns>
 protected Object ExtractOldValue(CacheEntry entry)
 {
     try
     {
         return(InvocableCacheHelper.ExtractOriginalFromEntry(ValueExtractor, entry));
     }
     catch (Exception)
     {
         return(NO_VALUE);
     }
 }
예제 #7
0
        /// <summary>
        /// Process an <see cref="IInvocableCacheEntry"/>.
        /// </summary>
        /// <param name="entry">
        /// The <b>IInvocableCacheEntry</b> to process.
        /// </param>
        /// <returns>
        /// The result of the processing, if any.
        /// </returns>
        public override object Process(IInvocableCacheEntry entry)
        {
            IDictionary dictionary = m_dictionary;
            object      key        = entry.Key;

            if (dictionary.Contains(key) && InvocableCacheHelper.EvaluateEntry(m_filter, entry))
            {
                entry.SetValue(dictionary[key], false);
            }
            return(null);
        }
        /// <summary>
        /// Extract the value from the passed entry.
        /// </summary>
        /// <remarks>
        /// The underlying extractors are applied sequentially, so a result
        /// of a previous extractor serves as a target object for a next one.
        /// A value of <code>null</code> prevents any further extractions and
        /// is returned immediately.
        /// </remarks>
        /// <param name="entry">
        /// An Entry object to extract a desired value from
        /// </param>
        /// <returns>The extracted value</returns>
        public override object ExtractFromEntry(ICacheEntry entry)
        {
            IValueExtractor[] extractors = Extractors;
            object            target     = InvocableCacheHelper.ExtractFromEntry(extractors[0], entry);

            for (int i = 1, c = extractors.Length; i < c && target != null; i++)
            {
                target = extractors[i].Extract(target);
            }
            return(target);
        }
예제 #9
0
        /// <summary>
        /// Extract a collection of values from the passed entry using the
        /// underlying array of <b>IValueExtractor</b> objects.
        /// </summary>
        /// <param name="entry">
        /// An entry to retrieve the collection of values from
        /// </param>
        /// <returns>
        /// An array containing extracted values
        /// </returns>
        public override object ExtractFromEntry(ICacheEntry entry)
        {
            IValueExtractor[] extractors = Extractors;
            int count = extractors.Length;

            object[] values = new object[count];
            for (int i = 0; i < count; i++)
            {
                values[i] = InvocableCacheHelper.ExtractFromEntry(extractors[i], entry);
            }
            return(values);
        }
예제 #10
0
 /// <summary>
 /// Apply the test to an <see cref="ICacheEntry"/>.
 /// </summary>
 /// <param name="entry">
 /// The <b>ICacheEntry</b> to evaluate; never <c>null</c>.
 /// </param>
 /// <returns>
 /// <b>true</b> if the test passes, <b>false</b> otherwise.
 /// </returns>
 public override bool EvaluateEntry(ICacheEntry entry)
 {
     IFilter[] filters = m_filters;
     for (int i = 0, c = filters.Length; i < c; i++)
     {
         if (!(InvocableCacheHelper.EvaluateEntry(filters[i], entry)))
         {
             return(false);
         }
     }
     return(true);
 }
예제 #11
0
        /// <summary>
        /// Process a collection of <see cref="IInvocableCacheEntry"/>
        /// objects.
        /// </summary>
        /// <param name="entries">
        /// A read-only collection of <b>IInvocableCacheEntry</b>
        /// objects to process.
        /// </param>
        /// <returns>
        /// A dictionary containing the results of the processing, up to one
        /// entry for each <b>IInvocableCacheEntry</b> that was
        /// processed, keyed by the keys of the dictionary that were
        /// processed, with a corresponding value being the result of the
        /// processing for each key.
        /// </returns>
        public override IDictionary ProcessAll(ICollection entries)
        {
            IDictionary results = new LiteDictionary();
            IFilter     filter  = m_filter;

            foreach (IInvocableCacheEntry entry in entries)
            {
                if (InvocableCacheHelper.EvaluateEntry(filter, entry))
                {
                    results[entry.Key] = Process(entry);
                }
            }
            return(results);
        }
예제 #12
0
        /// <summary>
        /// Process a collection of <see cref="IInvocableCacheEntry"/>
        /// objects.
        /// </summary>
        /// <param name="entries">
        /// A read-only collection of <b>IInvocableCacheEntry</b>
        /// objects to process.
        /// </param>
        /// <returns>
        /// An empty, immutable dictionary.
        /// </returns>
        public override IDictionary ProcessAll(ICollection entries)
        {
            IDictionary dictionary = m_dictionary;
            IFilter     filter     = m_filter;

            foreach (IInvocableCacheEntry entry in entries)
            {
                object key = entry.Key;
                if (dictionary.Contains(key) && InvocableCacheHelper.EvaluateEntry(filter, entry))
                {
                    entry.SetValue(dictionary[key], false);
                }
            }
            return(NullImplementation.GetDictionary());
        }
        /// <summary>
        /// Extract the "new" value from the specified entry.
        /// </summary>
        /// <param name="entry">
        /// The entry to extract the "new" value from.
        /// </param>
        /// <returns>
        /// The extracted "new" value, or NO_VALUE if the extraction failed
        /// </returns>
        protected Object ExtractNewValue(ICacheEntry entry)
        {
            try
            {
                return(InvocableCacheHelper.ExtractFromEntry(ValueExtractor, entry));
            }
            catch (Exception e)
            {
                CacheFactory.Log("An Exception occurred during index update for key " + entry.Key
                                 + ". The entry will be excluded from the index.\n",
                                 CacheFactory.LogLevel.Warn);
                CacheFactory.Log(e + ":\n" + e.StackTrace, CacheFactory.LogLevel.Warn);

                return(NO_VALUE);
            }
        }
예제 #14
0
        /// <summary>
        /// Evaluate the given entry using this index's filter. If the entry
        /// does not pass the filter then it should be excluded from this
        /// index, making this a partial index.
        /// </summary>
        /// <param name="entry">The entry to evaluate.</param>
        /// <returns>
        /// <c>true</c> If the entry passes the filter, <b>false</b> otherwise.
        /// </returns>
        protected virtual bool EvaluateEntry(ICacheEntry entry)
        {
            try
            {
                if (InvocableCacheHelper.EvaluateEntry(Filter, entry))
                {
                    return(true);
                }
            }
            catch (Exception)
            {
                // COH-6447: don't drop the index upon exception
            }

            m_partial = true;
            return(false);
        }
예제 #15
0
        /// <summary>
        /// Process a collection of <see cref="IInvocableCacheEntry"/>
        /// objects.
        /// </summary>
        /// <param name="entries">
        /// A read-only collection of <b>IInvocableCacheEntry</b>
        /// objects to process.
        /// </param>
        /// <returns>
        /// A dictionary containing the results of the processing, up to one
        /// entry for each <b>IInvocableCacheEntry</b> that was
        /// processed, keyed by the keys of the dictionary that were
        /// processed, with a corresponding value being the result of the
        /// processing for each key.
        /// </returns>
        public override IDictionary ProcessAll(ICollection entries)
        {
            IDictionary results = new LiteDictionary();
            IFilter     filter  = m_filter;

            foreach (IInvocableCacheEntry entry in entries)
            {
                if (entry.IsPresent && InvocableCacheHelper.EvaluateEntry(filter, entry))
                {
                    entry.Remove(false);
                }
                else if (m_return)
                {
                    results[entry.Key] = entry.Value;
                }
            }
            return(results);
        }
예제 #16
0
        /// <summary>
        /// Update this index in response to a delete operation on a cache.
        /// </summary>
        /// <param name="entry">
        /// The entry representing the object being inserted.
        /// </param>
        protected override void DeleteInternal(ICacheEntry entry)
        {
            try
            {
                if (entry is CacheEntry &&
                    !InvocableCacheHelper.EvaluateOriginalEntry(Filter, (CacheEntry)entry))
                {
                    // the "original" entry would have been excluded; nothing to do
                    return;
                }
            }
            catch (Exception)
            {
                // COH-6447: attempt the delete anyway because the filter may have
                // allowed this value previously and it may be in the index
            }

            base.DeleteInternal(entry);
        }
        /// <summary>
        /// Process a collection of <see cref="IInvocableCacheEntry"/>
        /// objects.
        /// </summary>
        /// <param name="entries">
        /// A read-only collection of <b>IInvocableCacheEntry</b>
        /// objects to process.
        /// </param>
        /// <returns>
        /// A dictionary containing the results of the processing, up to one
        /// entry for each <b>IInvocableCacheEntry</b> that was
        /// processed, keyed by the keys of the dictionary that were
        /// processed, with a corresponding value being the result of the
        /// processing for each key.
        /// </returns>
        public override IDictionary ProcessAll(ICollection entries)
        {
            IDictionary results = new LiteDictionary();
            IFilter     filter  = m_filter;
            object      value   = m_value;
            bool        ret     = m_return;

            foreach (IInvocableCacheEntry entry in entries)
            {
                if (InvocableCacheHelper.EvaluateEntry(filter, entry))
                {
                    entry.SetValue(value, false);
                }
                else if (ret)
                {
                    results[entry.Key] = entry.Value;
                }
            }
            return(results);
        }
 /// <summary>
 /// Apply the test to an <see cref="ICacheEntry"/>.
 /// </summary>
 /// <param name="entry">
 /// The <b>ICacheEntry</b> to evaluate; never <c>null</c>.
 /// </param>
 /// <returns>
 /// <b>true</b> if the test passes, <b>false</b> otherwise.
 /// </returns>
 public override bool EvaluateEntry(ICacheEntry entry)
 {
     IFilter[] filters = m_filters;
     return(InvocableCacheHelper.EvaluateEntry(filters[0], entry)
            ^ InvocableCacheHelper.EvaluateEntry(filters[1], entry));
 }
예제 #19
0
 /// <summary>
 /// Apply the test to an <see cref="ICacheEntry"/>.
 /// </summary>
 /// <param name="entry">
 /// The <b>ICacheEntry</b> to evaluate; never <c>null</c>.
 /// </param>
 /// <returns>
 /// <b>true</b> if the test passes, <b>false</b> otherwise.
 /// </returns>
 public virtual bool EvaluateEntry(ICacheEntry entry)
 {
     return(CollectionUtils.Contains(m_keys, entry.Key) &&
            InvocableCacheHelper.EvaluateEntry(m_filter, entry));
 }
 /// <summary>
 /// Apply the test to an <see cref="ICacheEntry"/>.
 /// </summary>
 /// <param name="entry">
 /// The <b>ICacheEntry</b> to evaluate; never <c>null</c>.
 /// </param>
 /// <returns>
 /// <b>true</b> if the test passes, <b>false</b> otherwise.
 /// </returns>
 public virtual bool EvaluateEntry(ICacheEntry entry)
 {
     return(!InvocableCacheHelper.EvaluateEntry(m_filter, entry));
 }