text:
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Collections.Generic;
using System.IO;
using Lucene.Net.Analysis.Tokenattributes;
using Lucene.Net.Store;
using Lucene.Net.Support;
using Lucene.Net.Util;

namespace Lucene.Net.Facet.Taxonomy.Directory
{

    using TokenStream = Lucene.Net.Analysis.TokenStream;
    using CharTermAttribute = Lucene.Net.Analysis.Tokenattributes.CharTermAttribute;
    using PositionIncrementAttribute = Lucene.Net.Analysis.Tokenattributes.PositionIncrementAttribute;
    using Document = Lucene.Net.Documents.Document;
    using Field = Lucene.Net.Documents.Field;
    using FieldType = Lucene.Net.Documents.FieldType;
    using StringField = Lucene.Net.Documents.StringField;
    using TextField = Lucene.Net.Documents.TextField;
    using TaxonomyWriterCache = Lucene.Net.Facet.Taxonomy.WriterCache.TaxonomyWriterCache;
    using Cl2oTaxonomyWriterCache = Lucene.Net.Facet.Taxonomy.WriterCache.Cl2oTaxonomyWriterCache;
    using LruTaxonomyWriterCache = Lucene.Net.Facet.Taxonomy.WriterCache.LruTaxonomyWriterCache;
    using AtomicReader = Lucene.Net.Index.AtomicReader;
    using AtomicReaderContext = Lucene.Net.Index.AtomicReaderContext;
    using CorruptIndexException = Lucene.Net.Index.CorruptIndexException; // javadocs
    using DirectoryReader = Lucene.Net.Index.DirectoryReader;
    using DocsEnum = Lucene.Net.Index.DocsEnum;
    using IndexReader = Lucene.Net.Index.IndexReader;
    using IndexWriter = Lucene.Net.Index.IndexWriter;
    using OpenMode = Lucene.Net.Index.IndexWriterConfig.OpenMode_e;
    using IndexWriterConfig = Lucene.Net.Index.IndexWriterConfig;
    using LogByteSizeMergePolicy = Lucene.Net.Index.LogByteSizeMergePolicy;
    using ReaderManager = Lucene.Net.Index.ReaderManager;
    using SegmentInfos = Lucene.Net.Index.SegmentInfos;
    using Terms = Lucene.Net.Index.Terms;
    using TermsEnum = Lucene.Net.Index.TermsEnum;
    using TieredMergePolicy = Lucene.Net.Index.TieredMergePolicy;
    using AlreadyClosedException = Lucene.Net.Store.AlreadyClosedException;
    using Directory = Lucene.Net.Store.Directory;
    using LockObtainFailedException = Lucene.Net.Store.LockObtainFailedException; // javadocs
    using NativeFSLockFactory = Lucene.Net.Store.NativeFSLockFactory;
    using SimpleFSLockFactory = Lucene.Net.Store.SimpleFSLockFactory;
    using BytesRef = Lucene.Net.Util.BytesRef;

    ///
    /// <seealso cref="TaxonomyWriter"/> which uses a <seealso cref="Directory"/> to store the taxonomy
    /// information on disk, and keeps an additional in-memory cache of some or all
    /// categories.
    /// <para>
    /// In addition to the permanently-stored information in the <seealso cref="Directory"/>,
    /// efficiency dictates that we also keep an in-memory cache of recently
    /// seen or all categories, so that we do not need to go back to disk
    /// for every category addition to see which ordinal this category already has,
    /// if any. A <seealso cref="TaxonomyWriterCache"/> object determines the specific caching
    /// algorithm used.
    /// </para>
    /// <para>
    /// This class offers some hooks for extending classes to control the
    /// <seealso cref="IndexWriter"/> instance that is used. See <seealso cref="#openIndexWriter"/>.
    ///
    /// @lucene.experimental
    /// </para>
    ///
    public class DirectoryTaxonomyWriter : TaxonomyWriter
    {

        ///
        /// Property name of user commit data that contains the index epoch. The epoch
        /// changes whenever the taxonomy is recreated (i.e. opened with
        /// <seealso cref="OpenMode#CREATE"/>.
        /// <para>
        /// Applications should not use this property in their commit data because it
        /// will be overridden by this taxonomy writer.
        /// </para>
        ///
        public const string INDEX_EPOCH = "index.epoch";

        private readonly Directory dir;
        private readonly IndexWriter indexWriter;
        private readonly TaxonomyWriterCache cache;
        private readonly AtomicInteger cacheMisses = new AtomicInteger(0);

        // Records the taxonomy index epoch, updated on replaceTaxonomy as well.
        private long indexEpoch;

        private SinglePositionTokenStream parentStream = new SinglePositionTokenStream(Consts.PAYLOAD_PARENT);
        private Field parentStreamField;
        private Field fullPathField;
        private int cacheMissesUntilFill = 11;
        private bool shouldFillCache = true;

        // even though lazily initialized, not volatile so that access to it is
        // faster. we keep a volatile boolean init instead.
        private ReaderManager readerManager;
        private volatile bool initializedReaderManager = false;
        private volatile bool shouldRefreshReaderManager;

        ///
        /// We call the cache "complete" if we know that every category in our
        /// taxonomy is in the cache. When the cache is not complete, and
        /// we can't find a category in the cache, we still need to look for it
        /// in the on-disk index; Therefore when the cache is not complete, we
        /// need to open a "reader" to the taxonomy index.
        /// The cache becomes incomplete if it was never filled with the existing
        /// categories, or if a put() to the cache ever returned true (meaning
        /// that some of the cached data was cleared).
        ///
        private volatile bool cacheIsComplete;
        private volatile bool isClosed = false;
        private volatile TaxonomyIndexArrays taxoArrays;
        private volatile int nextID;

        ///
        /// Reads the commit data from a Directory.
        private static IDictionary<string, string> ReadCommitData(Directory dir)
        {
            SegmentInfos infos = new SegmentInfos();
            infos.Read(dir);
            return infos.UserData;
        }

        ///
        /// Forcibly unlocks the taxonomy in the named directory.
        ///

        /// Caution: this should only be used by failure recovery code, when it is
        /// known that no other process nor thread is in fact currently accessing
        /// this taxonomy.
        ///

        /// This method is unnecessary if your <seealso cref="Directory"/> uses a
        /// <seealso cref="NativeFSLockFactory"/> instead of the default
        /// <seealso cref="SimpleFSLockFactory"/>. When the "native" lock is used, a lock
        /// does not stay behind forever when the process using it dies.
        ///
        public static void Unlock(Directory directory)
        {
            IndexWriter.Unlock(directory);
        }

        ///
        /// Construct a Taxonomy writer.
        ///
        /// <param name="directory">
        ///    The <seealso cref="Directory"/> in which to store the taxonomy. Note that
        ///    the taxonomy is written directly to that directory (not to a
        ///    subdirectory of it). </param>
        /// <param name="openMode">
        ///    Specifies how to open a taxonomy for writing: APPEND
        ///    means open an existing index for append (failing if the index does
        ///    not yet exist). CREATE means create a new index (first
        ///    deleting the old one if it already existed).
        ///    APPEND_OR_CREATE appends to an existing index if there
        ///    is one, otherwise it creates a new index. </param>
        /// <param name="cache">
        ///    A <seealso cref="TaxonomyWriterCache"/> implementation which determines
        ///    the in-memory caching policy. See for example
        ///    <seealso cref="LruTaxonomyWriterCache"/> and <seealso cref="Cl2oTaxonomyWriterCache"/>.
        ///    If null or missing, <seealso cref="#defaultTaxonomyWriterCache()"/> is used. </param>
        /// <exception cref="CorruptIndexException">
        ///     if the taxonomy is corrupted. </exception>
        /// <exception cref="LockObtainFailedException">
        ///     if the taxonomy is locked by another writer. If it is known
        ///     that no other concurrent writer is active, the lock might
        ///     have been left around by an old dead process, and should be
        ///     removed using <seealso cref="#unlock(Directory)"/>. </exception>
        /// <exception cref="IOException">
        ///     if another error occurred. </exception>
        public DirectoryTaxonomyWriter(Directory directory, OpenMode openMode, TaxonomyWriterCache cache)
        {

            dir = directory;
            IndexWriterConfig config = CreateIndexWriterConfig(openMode);
            indexWriter = OpenIndexWriter(dir, config);

            // verify (to some extent) that merge policy in effect would preserve category docids
            if (indexWriter != null)
            {
                Debug.Assert(!(indexWriter.Config.MergePolicy is TieredMergePolicy), "for preserving category docids, merging none-adjacent segments is not allowed");
            }

            // after we opened the writer, and the index is locked, it's safe to check
            // the commit data and read the index epoch
            openMode = config.OpenMode.HasValue ? config.OpenMode.Value : OpenMode.CREATE_OR_APPEND;
            if (!DirectoryReader.IndexExists(directory))
            {
                indexEpoch = 1;
            }
            else
            {
                string epochStr = null;
                IDictionary<string, string> commitData = ReadCommitData(directory);
                if (commitData != null && commitData.ContainsKey(INDEX_EPOCH))
                {
                    epochStr = commitData[INDEX_EPOCH];
                }
                // no commit data, or no epoch in it means an old taxonomy, so set its epoch to 1, for lack
                // of a better value.
                indexEpoch = epochStr == null ? 1 : Convert.ToInt64(epochStr, 16);
            }

            if (openMode == OpenMode.CREATE)
            {
                ++indexEpoch;
            }

            FieldType ft = new FieldType(TextField.TYPE_NOT_STORED);
            ft.OmitNorms = true;
            parentStreamField = new Field(Consts.FIELD_PAYLOADS, parentStream, ft);
            fullPathField = new StringField(Consts.FULL, "", Field.Store.YES);

            if (indexWriter == null)
                return;

            nextID = indexWriter.MaxDoc;

            if (cache == null)
            {
                cache = DefaultTaxonomyWriterCache();
            }
            this.cache = cache;

            if (nextID == 0)
            {
                cacheIsComplete = true;
                // Make sure that the taxonomy always contain the root category
                // with category id 0.
                AddCategory(new FacetLabel());
            }
            else
            {
                // There are some categories on the disk, which we have not yet
                // read into the cache, and therefore the cache is incomplete.
                // We choose not to read all the categories into the cache now,
                // to avoid terrible performance when a taxonomy index is opened
                // to add just a single category. We will do it later, after we
                // notice a few cache misses.
                cacheIsComplete = false;
            }
        }

        ///
        /// Open internal index writer, which contains the taxonomy data.
        /// <para>
        /// Extensions may provide their own <seealso cref="IndexWriter"/> implementation or instance.
        ///
NOTE: the instance this method returns will be closed upon calling
        /// to <seealso cref="#close()"/>.
        ///
NOTE: the merge policy in effect must not merge none adjacent segments. See
        /// comment in <seealso cref="#createIndexWriterConfig(IndexWriterConfig.OpenMode)"/> for the logic behind this.
        ///
        /// </para>
        ///
        /// <seealso cref= #createIndexWriterConfig(IndexWriterConfig.OpenMode)
        /// </seealso>
        /// <param name="directory">
        ///          the <seealso cref="Directory"/> on top of which an <seealso cref="IndexWriter"/>
        ///          should be opened. </param>
        /// <param name="config">
        ///          configuration for the internal index writer. </param>
        protected virtual IndexWriter OpenIndexWriter(Directory directory, IndexWriterConfig config)
        {
            return new IndexWriter(directory, config);
        }

        ///
        /// Create the <seealso cref="IndexWriterConfig"/> that would be used for opening the internal index writer.
        ///
Extensions can configure the <seealso cref="IndexWriter"/> as they see fit,
        /// including setting a <seealso cref="Lucene.Net.index.MergeScheduler merge-scheduler"/>, or
        /// <seealso cref="Lucene.Net.index.IndexDeletionPolicy deletion-policy"/>, different RAM size
        /// etc.

        ///
NOTE: internal docids of the configured index must not be altered.
        /// For that, categories are never deleted from the taxonomy index.
        /// In addition, merge policy in effect must not merge none adjacent segments.
        ///
        /// <seealso cref= #openIndexWriter(Directory, IndexWriterConfig)
        /// </seealso>
        /// <param name="openMode"> see <seealso cref="OpenMode"/> </param>
        protected virtual IndexWriterConfig CreateIndexWriterConfig(OpenMode openMode)
        {
            // TODO: should we use a more optimized Codec, e.g. Pulsing (or write custom)?
            // The taxonomy has a unique structure, where each term is associated with one document

            // :Post-Release-Update-Version.LUCENE_XY:
            // Make sure we use a MergePolicy which always merges adjacent segments and thus
            // keeps the doc IDs ordered as well (this is crucial for the taxonomy index).
            return (new IndexWriterConfig(LuceneVersion.LUCENE_48, null)).SetOpenMode(openMode).SetMergePolicy(new LogByteSizeMergePolicy());
        }

        ///
        /// Opens a <seealso cref="ReaderManager"/> from the internal <seealso cref="IndexWriter"/>.
        ///
        private void InitReaderManager()
        {
            if (!initializedReaderManager)
            {
                lock (this)
                {
                    // verify that the taxo-writer hasn't been closed on us.
                    EnsureOpen();
                    if (!initializedReaderManager)
                    {
                        readerManager = new ReaderManager(indexWriter, false);
                        shouldRefreshReaderManager = false;
                        initializedReaderManager = true;
                    }
                }
            }
        }

        ///
        /// Creates a new instance with a default cache as defined by
        /// <seealso cref="#defaultTaxonomyWriterCache()"/>.
        ///
        public DirectoryTaxonomyWriter(Directory directory, OpenMode openMode = OpenMode.CREATE_OR_APPEND)
            : this(directory, openMode, DefaultTaxonomyWriterCache())
        {
        }

        ///
        /// Defines the default <seealso cref="TaxonomyWriterCache"/> to use in constructors
        /// which do not specify one.
        ///

        /// The current default is <seealso cref="Cl2oTaxonomyWriterCache"/> constructed
        /// with the parameters (1024, 0.15f, 3), i.e., the entire taxonomy is
        /// cached in memory while building it.
        ///
        public static TaxonomyWriterCache DefaultTaxonomyWriterCache()
        {
            return new Cl2oTaxonomyWriterCache(1024, 0.15f, 3);
        }

        ///
        /// Frees used resources as well as closes the underlying <seealso cref="IndexWriter"/>,
        /// which commits whatever changes made to it to the underlying
        /// <seealso cref="Directory"/>.
        ///
        public void Dispose()
        {
            lock (this)
            {
                if (!isClosed)
                {
                    Commit();
                    DoClose();
                }
            }
        }

        private void DoClose()
        {
            indexWriter.Dispose();
            isClosed = true;
            CloseResources();
        }

        ///
        /// A hook for extending classes to close additional resources that were used.
        /// The default implementation closes the <seealso cref="IndexReader"/> as well as the
        /// <seealso cref="TaxonomyWriterCache"/> instances that were used.

        /// NOTE: if you override this method, you should include a
        /// super.closeResources() call in your implementation.
        ///
        protected virtual void CloseResources()
        {
            lock (this)
            {
                if (initializedReaderManager)
                {
                    readerManager.Dispose();
                    readerManager = null;
                    initializedReaderManager = false;
                }
                if (cache != null)
                {
                    cache.Close();
                }
            }
        }

        ///
        /// Look up the given category in the cache and/or the on-disk storage,
        /// returning the category's ordinal, or a negative number in case the
        /// category does not yet exist in the taxonomy.
        ///
        protected virtual int FindCategory(FacetLabel categoryPath)
        {
            lock (this)
            {
                // If we can find the category in the cache, or we know the cache is
                // complete, we can return the response directly from it
                int res = cache.Get(categoryPath);
                if (res >= 0 || cacheIsComplete)
                {
                    return res;
                }

                cacheMisses.IncrementAndGet();
                // After a few cache misses, it makes sense to read all the categories
                // from disk and into the cache. The reason not to do this on the first
                // cache miss (or even when opening the writer) is that it will
                // significantly slow down the case when a taxonomy is opened just to
                // add one category. The idea only spending a long time on reading
                // after enough time was spent on cache misses is known as an "online
                // algorithm".
                PerhapsFillCache();
                res = cache.Get(categoryPath);
                if (res >= 0 || cacheIsComplete)
                {
                    // if after filling the cache from the info on disk, the category is in it
                    // or the cache is complete, return whatever cache.get returned.
                    return res;
                }

                // if we get here, it means the category is not in the cache, and it is not
                // complete, and therefore we must look for the category on disk.

                // We need to get an answer from the on-disk index.
                InitReaderManager();

                int doc = -1;
                DirectoryReader reader = readerManager.Acquire();
                try
                {
                    BytesRef catTerm = new BytesRef(FacetsConfig.PathToString(categoryPath.Components, categoryPath.Length));
                    TermsEnum termsEnum = null; // reuse
                    DocsEnum docs = null; // reuse
                    foreach (AtomicReaderContext ctx in reader.Leaves)
                    {
                        Terms terms = ctx.AtomicReader.Terms(Consts.FULL);
                        if (terms != null)
                        {
                            termsEnum = terms.Iterator(termsEnum);
                            if (termsEnum.SeekExact(catTerm))
                            {
                                // liveDocs=null because the taxonomy has no deletes
                                docs = termsEnum.Docs(null, docs, 0); // freqs not required
                                // if the term was found, we know it has exactly one document.
                                doc = docs.NextDoc() + ctx.DocBase;
                                break;
                            }
                        }
                    }
                }
                finally
                {
                    readerManager.Release(reader);
                }
                if (doc > 0)
                {
                    AddToCache(categoryPath, doc);
                }
                return doc;
            }
        }

        public virtual int AddCategory(FacetLabel categoryPath)
        {
            EnsureOpen();
            // check the cache outside the synchronized block. this results in better
            // concurrency when categories are there.
            int res = cache.Get(categoryPath);
            if (res < 0)
            {
                // the category is not in the cache - following code cannot be executed in parallel.
                lock (this)
                {
                    res = FindCategory(categoryPath);
                    if (res < 0)
                    {
                        // This is a new category, and we need to insert it into the index
                        // (and the cache). Actually, we might also need to add some of
                        // the category's ancestors before we can add the category itself
                        // (while keeping the invariant that a parent is always added to
                        // the taxonomy before its child). internalAddCategory() does all
                        // this recursively
                        res = InternalAddCategory(categoryPath);
                    }
                }
            }
            return res;
        }

        ///
        /// Add a new category into the index (and the cache), and return its new
        /// ordinal.
        /// <para>
        /// Actually, we might also need to add some of the category's ancestors
        /// before we can add the category itself (while keeping the invariant that a
        /// parent is always added to the taxonomy before its child). We do this by
        /// recursion.
        /// </para>
        ///
        private int InternalAddCategory(FacetLabel cp)
        {
            // Find our parent's ordinal (recursively adding the parent category
            // to the taxonomy if it's not already there). Then add the parent
            // ordinal as payloads (rather than a stored field; payloads can be
            // more efficiently read into memory in bulk by LuceneTaxonomyReader)
            int parent;
            if (cp.Length > 1)
            {
                FacetLabel parentPath = cp.Subpath(cp.Length - 1);
                parent = FindCategory(parentPath);
                if (parent < 0)
                {
                    parent = InternalAddCategory(parentPath);
                }
            }
            else if (cp.Length == 1)
            {
                parent = TaxonomyReader.ROOT_ORDINAL;
            }
            else
            {
                parent = TaxonomyReader.INVALID_ORDINAL;
            }
            int id = AddCategoryDocument(cp, parent);

            return id;
        }

        ///
        /// Verifies that this instance wasn't closed, or throws
        /// <seealso cref="AlreadyClosedException"/> if it is.
        ///
        protected internal void EnsureOpen()
        {
            if (isClosed)
            {
                throw new AlreadyClosedException("The taxonomy writer has already been closed");
            }
        }

        ///
        /// Note that the methods calling addCategoryDocument() are synchornized, so
        /// this method is effectively synchronized as well.
        ///
        private int AddCategoryDocument(FacetLabel categoryPath, int parent)
        {
            // Before Lucene 2.9, position increments >=0 were supported, so we
            // added 1 to parent to allow the parent -1 (the parent of the root).
            // Unfortunately, starting with Lucene 2.9, after LUCENE-1542, this is
            // no longer enough, since 0 is not encoded consistently either (see
            // comment in SinglePositionTokenStream). But because we must be
            // backward-compatible with existing indexes, we can't just fix what
            // we write here (e.g., to write parent+2), and need to do a workaround
            // in the reader (which knows that anyway only category 0 has a parent
            // -1).
            parentStream.Set(Math.Max(parent + 1, 1));
            Document d = new Document();
            d.Add(parentStreamField);

            fullPathField.StringValue = FacetsConfig.PathToString(categoryPath.Components, categoryPath.Length);
            d.Add(fullPathField);

            // Note that we do no pass an Analyzer here because the fields that are
            // added to the Document are untokenized or contains their own TokenStream.
            // Therefore the IndexWriter's Analyzer has no effect.
            indexWriter.AddDocument(d);
            int id = nextID++;

            // added a category document, mark that ReaderManager is not up-to-date
            shouldRefreshReaderManager = true;

            // also add to the parent array
            taxoArrays = TaxoArrays.Add(id, parent);

            // NOTE: this line must be executed last, or else the cache gets updated
            // before the parents array (LUCENE-4596)
            AddToCache(categoryPath, id);

            return id;
        }

        private class SinglePositionTokenStream : TokenStream
        {
            internal ICharTermAttribute termAtt;
            internal IPositionIncrementAttribute posIncrAtt;
            internal bool returned;
            internal int val;
            internal readonly string word;

            public SinglePositionTokenStream(string word)
            {
                termAtt = AddAttribute<ICharTermAttribute>();
                posIncrAtt = AddAttribute<IPositionIncrementAttribute>();
                this.word = word;
                returned = true;
            }

            ///
            /// Set the value we want to keep, as the position increment.
            /// Note that when TermPositions.nextPosition() is later used to
            /// retrieve this value, val-1 will be returned, not val.
            ///

            /// IMPORTANT NOTE: Before Lucene 2.9, val>=0 were safe (for val==0,
            /// the retrieved position would be -1). But starting with Lucene 2.9,
            /// this unfortunately changed, and only val>0 are safe. val=0 can
            /// still be used, but don't count on the value you retrieve later
            /// (it could be 0 or -1, depending on circumstances or versions).
            /// This change is described in Lucene's JIRA: LUCENE-1542.
            ///
            public virtual void Set(int val)
            {
                this.val = val;
                returned = false;
            }

            public sealed override bool IncrementToken()
            {
                if (returned)
                {
                    return false;
                }
                ClearAttributes();
                posIncrAtt.PositionIncrement = val;
                termAtt.SetEmpty();
                termAtt.Append(word);
                returned = true;
                return true;
            }
        }

        private void AddToCache(FacetLabel categoryPath, int id)
        {
            if (cache.Put(categoryPath, id))
            {
                // If cache.put() returned true, it means the cache was limited in
                // size, became full, and parts of it had to be evicted. It is
                // possible that a relatively-new category that isn't yet visible
                // to our 'reader' was evicted, and therefore we must now refresh
                // the reader.
                RefreshReaderManager();
                cacheIsComplete = false;
            }
        }

        private void RefreshReaderManager()
        {
            lock (this)
            {
                // this method is synchronized since it cannot happen concurrently with
                // addCategoryDocument -- when this method returns, we must know that the
                // reader manager's state is current. also, it sets shouldRefresh to false,
                // and this cannot overlap with addCatDoc too.
                // NOTE: since this method is sync'ed, it can call maybeRefresh, instead of
                // maybeRefreshBlocking. If ever this is changed, make sure to change the
                // call too.
                if (shouldRefreshReaderManager && initializedReaderManager)
                {
                    readerManager.MaybeRefresh();
                    shouldRefreshReaderManager = false;
                }
            }
        }

        public virtual void Commit()
        {
            lock (this)
            {
                EnsureOpen();
                // LUCENE-4972: if we always call setCommitData, we create empty commits
                string epochStr = null;
                indexWriter.CommitData.TryGetValue(INDEX_EPOCH, out epochStr);
                if (epochStr == null || Convert.ToInt64(epochStr, 16) != indexEpoch)
                {
                    indexWriter.CommitData = CombinedCommitData(indexWriter.CommitData);
                }
                indexWriter.Commit();
            }
        }

        ///
        /// Combine original user data with the taxonomy epoch.
        private IDictionary<string, string> CombinedCommitData(IDictionary<string, string> commitData)
        {
            IDictionary<string, string> m = new Dictionary<string, string>();
            if (commitData != null)
            {
                m.PutAll(commitData);
            }
            m[INDEX_EPOCH] = Convert.ToString(indexEpoch, 16);
            return m;
        }

        public virtual IDictionary<string, string> CommitData
        {
            set
            {
                indexWriter.CommitData = CombinedCommitData(value);
            }
            get
            {
                return CombinedCommitData(indexWriter.CommitData);
            }
        }

        ///
        /// prepare most of the work needed for a two-phase commit.
        /// See <seealso cref="IndexWriter#prepareCommit"/>.
        ///
        public virtual void PrepareCommit()
        {
            lock (this)
            {
                EnsureOpen();
                // LUCENE-4972: if we always call setCommitData, we create empty commits
                string epochStr = indexWriter.CommitData[INDEX_EPOCH];
                if (epochStr == null || Convert.ToInt64(epochStr, 16) != indexEpoch)
                {
                    indexWriter.CommitData = CombinedCommitData(indexWriter.CommitData);
                }
                indexWriter.PrepareCommit();
            }
        }

        public virtual int Size
        {
            get
            {
                EnsureOpen();
                return nextID;
            }
        }

        ///
        /// Set the number of cache misses before an attempt is made to read the entire
        /// taxonomy into the in-memory cache.
        /// <para>
        /// This taxonomy writer holds an in-memory cache of recently seen categories
        /// to speed up operation. On each cache-miss, the on-disk index needs to be
        /// consulted. When an existing taxonomy is opened, a lot of slow disk reads
        /// like that are needed until the cache is filled, so it is more efficient to
        /// read the entire taxonomy into memory at once. We do this complete read
        /// after a certain number (defined by this method) of cache misses.
        /// </para>
        /// <para>
        /// If the number is set to {@code 0}, the entire taxonomy is read into the
        /// cache on first use, without fetching individual categories first.
        /// </para>
        /// <para>
        /// NOTE: it is assumed that this method is called immediately after the
        /// taxonomy writer has been created.
        /// </para>
        ///
        public virtual int CacheMissesUntilFill
        {
            set
            {
                EnsureOpen();
                cacheMissesUntilFill = value;
            }
        }

        // we need to guarantee that if several threads call this concurrently, only
        // one executes it, and after it returns, the cache is updated and is either
        // complete or not.
        private void PerhapsFillCache()
        {
            lock (this)
            {
                if (cacheMisses.Get() < cacheMissesUntilFill)
                {
                    return;
                }

                if (!shouldFillCache)
                {
                    // we already filled the cache once, there's no need to re-fill it
                    return;
                }
                shouldFillCache = false;

                InitReaderManager();

                bool aborted = false;
                DirectoryReader reader = readerManager.Acquire();
                try
                {
                    TermsEnum termsEnum = null;
                    DocsEnum docsEnum = null;
                    foreach (AtomicReaderContext ctx in reader.Leaves)
                    {
                        Terms terms = ctx.AtomicReader.Terms(Consts.FULL);
                        if (terms != null) // cannot really happen, but be on the safe side
                        {
                            termsEnum = terms.Iterator(termsEnum);
                            while (termsEnum.Next() != null)
                            {
                                if (!cache.Full)
                                {
                                    BytesRef t = termsEnum.Term();
                                    // Since we guarantee uniqueness of categories, each term has exactly
                                    // one document. Also, since we do not allow removing categories (and
                                    // hence documents), there are no deletions in the index. Therefore, it
                                    // is sufficient to call next(), and then doc(), exactly once with no
                                    // 'validation' checks.
                                    FacetLabel cp = new FacetLabel(FacetsConfig.StringToPath(t.Utf8ToString()));
                                    docsEnum = termsEnum.Docs(null, docsEnum, DocsEnum.FLAG_NONE);
                                    bool res = cache.Put(cp, docsEnum.NextDoc() + ctx.DocBase);
                                    Debug.Assert(!res, "entries should not have been evicted from the cache");
                                }
                                else
                                {
                                    // the cache is full and the next put() will evict entries from it, therefore abort the iteration.
                                    aborted = true;
                                    break;
                                }
                            }
                        }
                        if (aborted)
                        {
                            break;
                        }
                    }
                }
                finally
                {
                    readerManager.Release(reader);
                }

                cacheIsComplete = !aborted;
                if (cacheIsComplete)
                {
                    lock (this)
                    {
                        // everything is in the cache, so no need to keep readerManager open.
                        // this block is executed in a sync block so that it works well with
                        // initReaderManager called in parallel.
                        readerManager.Dispose();
                        readerManager = null;
                        initializedReaderManager = false;
                    }
                }
            }
        }

        private TaxonomyIndexArrays TaxoArrays
        {
            get
            {
                if (taxoArrays == null)
                {
                    lock (this)
                    {
                        if (taxoArrays == null)
                        {
                            InitReaderManager();
                            DirectoryReader reader = readerManager.Acquire();
                            try
                            {
                                // according to Java Concurrency, this might perform better on some
                                // JVMs, since the object initialization doesn't happen on the
                                // volatile member.
                                TaxonomyIndexArrays tmpArrays = new TaxonomyIndexArrays(reader);
                                taxoArrays = tmpArrays;
                            }
                            finally
                            {
                                readerManager.Release(reader);
                            }
                        }
                    }
                }
                return taxoArrays;
            }
        }

        public virtual int GetParent(int ordinal)
        {
            EnsureOpen();
            // Note: the following if() just enforces that a user can never ask
            // for the parent of a nonexistant category - even if the parent array
            // was allocated bigger than it really needs to be.
            if (ordinal >= nextID)
            {
                throw new System.IndexOutOfRangeException("requested ordinal is bigger than the largest ordinal in the taxonomy");
            }

            int[] parents = TaxoArrays.Parents();
            Debug.Assert(ordinal < parents.Length, "requested ordinal (" + ordinal + "); parents.length (" + parents.Length + ") !");
            return parents[ordinal];
        }

        ///
        /// Takes the categories from the given taxonomy directory, and adds the
        /// missing ones to this taxonomy. Additionally, it fills the given
        /// <seealso cref="OrdinalMap"/> with a mapping from the original ordinal to the new
        /// ordinal.
        ///
        public virtual void AddTaxonomy(Directory taxoDir, OrdinalMap map)
        {
            EnsureOpen();
            DirectoryReader r = DirectoryReader.Open(taxoDir);
            try
            {
                int size = r.NumDocs;
                OrdinalMap ordinalMap = map;
                ordinalMap.Size = size;
                int @base = 0;
                TermsEnum te = null;
                DocsEnum docs = null;
                foreach (AtomicReaderContext ctx in r.Leaves)
                {
                    AtomicReader ar = ctx.AtomicReader;
                    Terms terms = ar.Terms(Consts.FULL);
                    te = terms.Iterator(te);
                    while (te.Next() != null)
                    {
                        FacetLabel cp = new FacetLabel(FacetsConfig.StringToPath(te.Term().Utf8ToString()));
                        int ordinal = AddCategory(cp);
                        docs = te.Docs(null, docs, DocsEnum.FLAG_NONE);
                        ordinalMap.AddMapping(docs.NextDoc() + @base, ordinal);
                    }
                    @base += ar.MaxDoc; // no deletions, so we're ok
                }
                ordinalMap.AddDone();
            }
            finally
            {
                r.Dispose();
            }
        }

        ///
        /// Mapping from old ordinal to new ordinals, used when merging indexes
        /// wit separate taxonomies.
        /// <para>
        /// addToTaxonomies() merges one or more taxonomies into the given taxonomy
        /// (this). An OrdinalMap is filled for each of the added taxonomies,
        /// containing the new ordinal (in the merged taxonomy) of each of the
        /// categories in the old taxonomy.
        ///

        /// There exist two implementations of OrdinalMap: MemoryOrdinalMap and
        /// DiskOrdinalMap. As their names suggest, the former keeps the map in
        /// memory and the latter in a temporary disk file. Because these maps will
        /// later be needed one by one (to remap the counting lists), not all at the
        /// same time, it is recommended to put the first taxonomy's map in memory,
        /// and all the rest on disk (later to be automatically read into memory one
        /// by one, when needed).
        /// </para>
        ///
        public interface OrdinalMap
        {
            ///
            /// Set the size of the map. This MUST be called before addMapping().
            /// It is assumed (but not verified) that addMapping() will then be
            /// called exactly 'size' times, with different origOrdinals between 0
            /// and size-1.
            ///
            int Size { set; }

            ///
            /// Record a mapping.
            void AddMapping(int origOrdinal, int newOrdinal);

            ///
            /// Call addDone() to say that all addMapping() have been done.
            /// In some implementations this might free some resources.
            ///
            void AddDone();

            ///
            /// Return the map from the taxonomy's original (consecutive) ordinals
            /// to the new taxonomy's ordinals. If the map has to be read from disk
            /// and ordered appropriately, it is done when getMap() is called.
            /// getMap() should only be called once, and only when the map is actually
            /// needed. Calling it will also free all resources that the map might
            /// be holding (such as temporary disk space), other than the returned int[].
            ///
            int[] Map { get; }
        }

        ///
        /// <seealso cref="OrdinalMap"/> maintained in memory
        ///
        public sealed class MemoryOrdinalMap : OrdinalMap
        {
            internal int[] map;

            ///
            /// Sole constructor.
            ///
            public MemoryOrdinalMap()
            {
                map = new int[] { };
            }

            public int Size { set; private get; }

            public void AddMapping(int origOrdinal, int newOrdinal)
            {
                if (map.Length - 1 >= origOrdinal)
                {
                    map[origOrdinal] = newOrdinal;
                }
                else
                {
                    Array.Resize(ref map, origOrdinal + 1);
                    map[origOrdinal] = newOrdinal;
                }

            }

            public void AddDone() // nothing to do
            {
            }
            public int[] Map
            {
                get
                {
                    return map;
                }
            }
        }

        ///
        /// <seealso cref="OrdinalMap"/> maintained on file system
        ///
        public sealed class DiskOrdinalMap : OrdinalMap
        {
            internal string tmpfile;
            internal OutputStreamDataOutput @out;

            ///
            /// Sole constructor.
            ///
            public DiskOrdinalMap(string tmpfile)
            {
                this.tmpfile = tmpfile;
                var outfs = new FileStream(tmpfile, FileMode.OpenOrCreate, FileAccess.Write);
                @out = new OutputStreamDataOutput(outfs);
            }

            public void AddMapping(int origOrdinal, int newOrdinal)
            {
                @out.WriteInt(origOrdinal);
                @out.WriteInt(newOrdinal);
            }

            public int Size
            {
                set
                {
                    @out.WriteInt(value);
                }
            }

            public void AddDone()
            {
                if (@out != null)
                {
                    @out.Dispose();
                    @out = null;
                }
            }

            int[] map = null;

            public int[] Map
            {
                get
                {
                    if (map != null)
                    {
                        return map;
                    }
                    AddDone(); // in case this wasn't previously called

                    var ifs = new FileStream(tmpfile, FileMode.OpenOrCreate, FileAccess.Read);
                    var @in = new InputStreamDataInput(ifs);
                    map = new int[@in.ReadInt()];
                    // NOTE: The current code assumes here that the map is complete,
                    // i.e., every ordinal gets one and exactly one value. Otherwise,
                    // we may run into an EOF here, or vice versa, not read everything.
                    for (int i = 0; i < map.Length; i++)
                    {
                        int origordinal = @in.ReadInt();
                        int newordinal = @in.ReadInt();
                        map[origordinal] = newordinal;
                    }
                    @in.Dispose();

                    // Delete the temporary file, which is no longer needed.
                    if (File.Exists(tmpfile))
                    {
                        File.Delete(tmpfile);
                    }
                    return map;
                }
            }
        }

        ///
        /// Rollback changes to the taxonomy writer and closes the instance. Following
        /// this method the instance becomes unusable (calling any of its API methods
        /// will yield an <seealso cref="AlreadyClosedException"/>).
        ///
        public virtual void Rollback()
        {
            lock (this)
            {
                EnsureOpen();
                indexWriter.Rollback();
                DoClose();
            }
        }

        ///
        /// Replaces the current taxonomy with the given one. This method should
        /// generally be called in conjunction with
        /// <seealso cref="IndexWriter#addIndexes(Directory...)"/> to replace both the taxonomy
        /// as well as the search index content.
        ///
        public virtual void ReplaceTaxonomy(Directory taxoDir)
        {
            lock (this)
            {
                // replace the taxonomy by doing IW optimized operations
                indexWriter.DeleteAll();
                indexWriter.AddIndexes(taxoDir);
                shouldRefreshReaderManager = true;
                InitReaderManager(); // ensure that it's initialized
                RefreshReaderManager();
                nextID = indexWriter.MaxDoc;
                taxoArrays = null; // must nullify so that it's re-computed next time it's needed

                // need to clear the cache, so that addCategory won't accidentally return
                // old categories that are in the cache.
                cache.Clear();
                cacheIsComplete = false;
                shouldFillCache = true;
                cacheMisses.Set(0);

                // update indexEpoch as a taxonomy replace is just like it has be recreated
                ++indexEpoch;
            }
        }

        ///
        /// Returns the <seealso cref="Directory"/> of this taxonomy writer.
        public virtual Directory Directory
        {
            get
            {
                return dir;
            }
        }

        ///
        /// Used by <seealso cref="DirectoryTaxonomyReader"/> to support NRT.
        /// <para>
        /// NOTE: you should not use the obtained <seealso cref="IndexWriter"/> in any
        /// way, other than opening an IndexReader on it, or otherwise, the taxonomy
        /// index may become corrupt!
        /// </para>
        ///
        internal IndexWriter InternalIndexWriter
        {
            get
            {
                return indexWriter;
            }
        }

        ///
        /// Expert: returns current index epoch, if this is a
        /// near-real-time reader.  Used by {@link
        /// DirectoryTaxonomyReader} to support NRT.
        ///
        /// @lucene.internal
        ///
        public long TaxonomyEpoch
        {
            get
            {
                return indexEpoch;
            }
        }
    }

}


text:
layout: tag
section-type: tag
title: discovery
---
## Tag

redpajama_set_name: RedPajamaGithub


text:
{% extends "base.html" %}

{% block title %}activeMDM{% endblock %}

{% block content %}

			Name

			Description

			Passcode

			Configure the passcode requirements of the device

			Create

{% endblock %}


text:
module.exports = Person;

function Person(name) {
    this.name = name.toUpperCase();
}


text:
module.exports = (sanitize, params) => {
  return sanitize`
    EXEC core.GenerateSession
      @UserId = ${params.userId},
      @ExpiryDate = ${params.expiryDate}
  `
}


text:
'use strict';

import 'whatwg-fetch';
import 'socket.io-client/socket.io.js';
import 'leaflet/dist/leaflet.js';
import 'leaflet/dist/leaflet.css';
L.Icon.Default.imagePath = "/images/leaflet";
import 'leaflet-control-geocoder/dist/Control.Geocoder.js';
import 'leaflet-control-geocoder/dist/Control.Geocoder.css';

import { pokemon } from 'pokemon-go-node-api/pokemons.json';
var pokemonList = pokemon;

// npm install left-pad alternative.
function pad(s, chars) {
    return (chars + s).slice(-chars.length);
}

// dom creation helper
function h(tag, attrs, content) {
    var result = document.createElement(tag);

    if (attrs) for (var attr in attrs) result.setAttribute(attr, attrs[attr]);

    function populate(c) {
        if (!c) return;

        if (Array.isArray(c)) c.forEach(populate);
        else if (typeof c === 'string') result.appendChild(document.createTextNode(c));
        else result.appendChild(c);
    }
    populate(content);
    return result;
}

function generateUserId() {
    return pad(Math.floor(Math.random() * Math.pow(16, 10)).toString(16), '0'.repeat(10));
}

function getUserId() {
    var userId = localStorage.getItem('userId');
    if (!userId) {
        userId = generateUserId();
        localStorage.setItem('userId', userId);
    }
    return userId;
}

var map,
    markers = {},
    scannerCircle,
    clickMarker,
    scanButton,
    currentPosition = [48.869147, 2.3251892],
    initZoom = 16;

function setupHashRoute () {
    var res,
        url = new URL(window.location);

    if (url.hash) {
        res = window.location.hash.match(/(\d+\.\d+)\/(\d+\.\d+)\/(\d+)/);
        if (res) {
            currentPosition = [res[1], res[2]];
            initZoom = res[3];
        }
    }
}

// Setup map
function initMap(leafletURL) {
    // Add retina tiles if retina screen
    var retinaAwareURL;
    if (L.Browser.retina) {
        retinaAwareURL = leafletURL.replace('{y}?access_token', '{y}@2x?access_token');
    } else {
        retinaAwareURL = leafletURL;
    }
    map = L.map('map').setView(currentPosition, initZoom);
    L.tileLayer(retinaAwareURL, {maxZoom: 18}).addTo(map);

    // Map events
    map.on('dragend', savePosition);
    map.on('zoomend', savePosition);
    map.on('click', addMarkerForScan);
}

// Update location.hash with given position
function savePosition(center) {
    if (!center.lat && !center.lng) {
        center = map.getCenter();
    }
    window.location = '#' + center.lat + '/' + center.lng + '/' + map.getZoom();
}

// Add the marker for location to scan
function addMarkerForScan (e) {
    clickMarker.setLatLng(e.latlng).addTo(map);
    map.addControl(scanButton);
    scanButton.getContainer().style.display = 'block';
}

function addMapControls () {
    addGeocoder();
    map.addControl(new locateControl());
    scanButton = new scanControl();
    scannerCircle = L.circle(currentPosition, 50, {
        clickable: false,
        fillOpacity: 0.2,
        opacity:0.2,
    }).addTo(map);

    clickMarker = L.marker(currentPosition);
}

// Scan control
var scanControl = L.Control.extend({
    options: {
        position: 'bottomleft'
    },

    onAdd: function () {
        var container = h('div', { class: 'leaflet-bar leaflet-control scan-control' }, [
            h('span', { class: 'name' }, 'Scan')
        ]);

        container.onclick = function(e){
            e.stopPropagation();
            doScan(clickMarker.getLatLng());
            map.removeControl(scanButton);
            map.removeControl(clickMarker);
        };
        return container;
    }
});

// Geolocation control
var locateControl = L.Control.extend({
    options: {position: 'topright'},

    onAdd: function (map) {
        var container = L.DomUtil.create('div', 'leaflet-bar leaflet-control leaflet-control-locate');
        container.innerHTML = '✛';

        container.onclick = function(event){
            event.stopPropagation();
            map.locate({setView: true, maxZoom: 16});
        };
        return container;
    }

});

// Add searchbar
function addGeocoder () {
    L.Control.geocoder({
        defaultMarkGeocode: false
    }).on('markgeocode', function(e) {
        var center = e.geocode.center;

        doScan(center)
        .then(function () {
            centerOnPoint(center);
        });
    })
    .addTo(map);
}

// Center map on given point
function centerOnPoint(center) {
    newLocation({
        latitude : center.lat,
        longitude : center.lng
    });
    savePosition(center);
    map.setView([center.lat, center.lng], initZoom);
}

// Queue location for scan
function doScan(latlng) {
    currentPosition = latlng;
    return fetch(`/scan/${getUserId()}/${latlng.lat}/${latlng.lng}`)
    .then(function (response) {
        response.json()
        .then(function (json) {
            var pop = L.popup()
                .setLatLng([latlng.lat, latlng.lng])
                .setContent('
Scan queued.
 Scanning in ~' + json.position * json.interval + 's')
                .openOn(map);
            window.setTimeout(function () {map.closePopup(pop);}, 1300);
        });
    });
}

// Icon creation for pokemon
function getIcon(pokemonid) {
    var size = L.Browser.retina ? 'retina' : 'narmol';
    return L.icon({
        iconUrl: `images/pokemons/${size}/${pokemonid}.png`,
        iconSize: [48, 48]
    });
}

function formatTime(ms) {
    var totalSeconds = Math.round(ms / 1000);
    var minutes = Math.floor(totalSeconds / 60);
    var seconds = totalSeconds % 60;

    return ` ${minutes}:${pad(seconds, '00')}`;
}

// Counter for pokemon popup
function createCounter(expiration, updatefn) {
    function update() {
        var remaining = expiration - Date.now();
        if (remaining < 0) remaining = 0;
        updatefn(remaining);
        if (!remaining) clearInterval(interval);
    }

    var interval = window.setInterval(update, 1000);
    update();
}

// Pokemon popup
function createPopup(pokemon) {
    var counter = h('span');

    createCounter(pokemon.expiration, function (remaining) {
        counter.textContent = formatTime(remaining);
    });

    return h('div', { class: 'popup' }, [
        h('span', { class: 'name' }, pokemonList[pokemon.pokemonid].name),
        counter,
    ]);
}

// Listen to newPokemon and newLocation
var socket = io();

// Let's go, baby
socket.once('run', run);
function run(leafletURL) {
    setupHashRoute();
    initMap(leafletURL);
    addMapControls();
    setInterval(function () {
        // Renew poi every 5 minutes
        doScan(currentPosition);
    }, 3e5 /* 5 minutes*/);
}

socket.on('newPokemon', addPokemon);
// Add pokemon marker to map
function addPokemon(pokemon) {
    var oldMarker = markers[pokemon.id];
    if (oldMarker) {
        if (oldMarker.pokemonid == pokemon.pokemonid && oldMarker.expiration == pokemon.expiration) {
            return;
        } else { //update lure
            oldMarker.marker.setIcon(getIcon(pokemon.pokemonid));
        }
    } else {
        var time = new Date(+pokemon.expiration);
        var icon = getIcon(pokemon.pokemonid);

        var formattedTime = time.getHours() + ':' + ('00' + time.getMinutes()).slice(-2)+ ':' + ('00' + time.getSeconds()).slice(-2);

        var marker = L.marker([pokemon.latitude, pokemon.longitude], {
            icon: icon,
            title: pokemonList[pokemon.pokemonid].name + ' (' + formattedTime + ')',
            opacity: pokemon.isLure ? 0.5 : 1
        }).addTo(map);

        marker.bindPopup(createPopup(pokemon));

        window.setTimeout(function() {
            delete markers[pokemon.id];
            map.removeLayer(marker);
        }, +pokemon.expiration - Date.now());

        markers[pokemon.id] = {marker: marker, pokemonid: pokemon.pokemonid, expiration: pokemon.expiration};
    }
}

socket.on('newLocation', newLocation);

// Update scannerCircle position
function newLocation (location) {
    scannerCircle.setLatLng([location.latitude, location.longitude]);
}


text:
var Hashes = require('../../hashes');

// sample string
var str = 'This is a sample text!';

// new MD5 instance
var MD5 = new Hashes.MD5;
// new SHA1 instance
var SHA1 = new Hashes.SHA1;
// new SHA256 instance
var SHA256 =  new Hashes.SHA256;
// new SHA512 instace
var SHA512 = new Hashes.SHA512;
// new RIPEMD160 instace
var RMD160 = new Hashes.RMD160;

console.log('jsHashes\nCustom encoding values example...\n');

// custom string value to use for hash encoding
var custom = 'abc123';

console.log('MD5 -> ' + MD5.any(str,custom));
console.log('SHA1 -> ' + SHA1.any(str,custom));
console.log('SHA256 -> ' + SHA256.any(str,custom));
console.log('SHA512 -> ' + SHA512.any(str,custom));
console.log('RIPEMD160 -> ' + RMD160.any(str,custom));


text:
require 'helper'

class TestFactory < Test::Unit::TestCase
  include Factory

  context "Factory" do
    should "create proper import statement" do
      assert_equal '<import file="foo.xml"/>', create_import_statement("foo.xml")
    end

    should "raise error when target name not specified" do
      assert_raise(RuntimeError) { create_ant_target("") }
    end

    should "create proper ant target statement with empty depends attribute" do
      assert_equal '<target name="foo" depends=""/>', create_ant_target("foo")
    end

    should "create proper ant target statement with dependency" do
      assert_equal '<target name="foo" depends="bar"/>', create_ant_target("foo", "bar")
    end

    should "create ant target with antcall" do
      target = create_ant_target_with_ant_call("boo", "bar")
      assert_equal '<target name="boo"><antcall target="bar"/></target>', target
    end

    should "create build file with no targets" do
      build = create_build_file("project")
      assert_equal '<?xml version="1.0" encoding="UTF-8"?><project name="project"></project>', build
    end

    should "create build file with ant target" do
      target = create_ant_target("foo", "bar")
      build = create_build_file("project", target)
      assert_equal '<?xml version="1.0" encoding="UTF-8"?><project name="project"><target name="foo" depends="bar"/></project>', build
    end

    should "create build file with import statement" do
      import = create_import_statement("foo.xml")
      build = create_build_file("project", import)
      assert_equal '<?xml version="1.0" encoding="UTF-8"?><project name="project"><import file="foo.xml"/></project>', build
    end

    should "create build file with multiple children" do
      import = create_import_statement("foo.xml")
      target = create_ant_target("foo", "bar")
      build = create_build_file("project", import, target)
      assert_equal '<?xml version="1.0" encoding="UTF-8"?><project name="project"><import file="foo.xml"/><target name="foo" depends="bar"/></project>', build
    end
  end
end


text:
package bootstrappolicy

import (
	"fmt"

	kapi "k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/apis/autoscaling"
	"k8s.io/kubernetes/pkg/apis/batch"
	"k8s.io/kubernetes/pkg/apis/extensions"
	"k8s.io/kubernetes/pkg/util/sets"

	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
)

const (
	InfraBuildControllerServiceAccountName = "build-controller"
	BuildControllerRoleName                = "system:build-controller"

	InfraReplicationControllerServiceAccountName = "replication-controller"
	ReplicationControllerRoleName                = "system:replication-controller"

	InfraDeploymentControllerServiceAccountName = "deployment-controller"
	DeploymentControllerRoleName                = "system:deployment-controller"

	InfraJobControllerServiceAccountName = "job-controller"
	JobControllerRoleName                = "system:job-controller"

	InfraDaemonSetControllerServiceAccountName = "daemonset-controller"
	DaemonSetControllerRoleName                = "system:daemonset-controller"

	InfraHPAControllerServiceAccountName = "hpa-controller"
	HPAControllerRoleName                = "system:hpa-controller"

	InfraNamespaceControllerServiceAccountName = "namespace-controller"
	NamespaceControllerRoleName                = "system:namespace-controller"

	InfraPersistentVolumeBinderControllerServiceAccountName = "pv-binder-controller"
	PersistentVolumeBinderControllerRoleName                = "system:pv-binder-controller"

	InfraPersistentVolumeRecyclerControllerServiceAccountName = "pv-recycler-controller"
	PersistentVolumeRecyclerControllerRoleName                = "system:pv-recycler-controller"

	InfraPersistentVolumeProvisionerControllerServiceAccountName = "pv-provisioner-controller"
	PersistentVolumeProvisionerControllerRoleName                = "system:pv-provisioner-controller"

	InfraGCControllerServiceAccountName = "gc-controller"
	GCControllerRoleName                = "system:gc-controller"

	InfraServiceLoadBalancerControllerServiceAccountName = "service-load-balancer-controller"
	ServiceLoadBalancerControllerRoleName                = "system:service-load-balancer-controller"

	ServiceServingCertServiceAccountName = "service-serving-cert-controller"
	ServiceServingCertControllerRoleName = "system:service-serving-cert-controller"
)

type InfraServiceAccounts struct {
	serviceAccounts sets.String
	saToRole        map[string]authorizationapi.ClusterRole
}

var InfraSAs = &InfraServiceAccounts{}

func (r *InfraServiceAccounts) addServiceAccount(saName string, role authorizationapi.ClusterRole) error {
	if _, exists := r.serviceAccounts[saName]; exists {
		return fmt.Errorf("%s already registered", saName)
	}

	for existingSAName, existingRole := range r.saToRole {
		if existingRole.Name == role.Name {
			return fmt.Errorf("clusterrole/%s is already registered for %s", existingRole.Name, existingSAName)
		}
	}

	r.saToRole[saName] = role
	r.serviceAccounts.Insert(saName)
	return nil
}

func (r *InfraServiceAccounts) GetServiceAccounts() []string {
	return r.serviceAccounts.List()
}

func (r *InfraServiceAccounts) RoleFor(saName string) (authorizationapi.ClusterRole, bool) {
	ret, exists := r.saToRole[saName]
	return ret, exists
}

func (r *InfraServiceAccounts) AllRoles() []authorizationapi.ClusterRole {
	ret := []authorizationapi.ClusterRole{}
	for _, saName := range r.serviceAccounts.List() {
		ret = append(ret, r.saToRole[saName])
	}
	return ret
}

func init() {
	InfraSAs.serviceAccounts = sets.String{}
	InfraSAs.saToRole = map[string]authorizationapi.ClusterRole{}

	var err error
	err = InfraSAs.addServiceAccount(
		InfraBuildControllerServiceAccountName,
		authorizationapi.ClusterRole{
			ObjectMeta: kapi.ObjectMeta{
				Name: BuildControllerRoleName,
			},
			Rules: []authorizationapi.PolicyRule{
				// BuildControllerFactory.buildLW
				// BuildControllerFactory.buildDeleteLW
				{
					Verbs:     sets.NewString("get", "list", "watch"),
					Resources: sets.NewString("builds"),
				},
				// BuildController.BuildUpdater (OSClientBuildClient)
				{
					Verbs:     sets.NewString("update"),
					Resources: sets.NewString("builds"),
				},
				// Create permission on virtual build type resources allows builds of those types to be updated
				{
					Verbs:     sets.NewString("create"),
					Resources: sets.NewString("builds/docker", "builds/source", "builds/custom", "builds/jenkinspipeline"),
				},
				// BuildController.ImageStreamClient (ControllerClient)
				{
					Verbs:     sets.NewString("get"),
					Resources: sets.NewString("imagestreams"),
				},
				// BuildController.PodManager (ControllerClient)
				// BuildDeleteController.PodManager (ControllerClient)
				// BuildControllerFactory.buildDeleteLW
				{
					Verbs:     sets.NewString("get", "list", "create", "delete"),
					Resources: sets.NewString("pods"),
				},
				// BuildController.Recorder (EventBroadcaster)
				{
					Verbs:     sets.NewString("create", "update", "patch"),
					Resources: sets.NewString("events"),
				},
			},
		},
	)
	if err != nil {
		panic(err)
	}

	err = InfraSAs.addServiceAccount(
		InfraDeploymentControllerServiceAccountName,
		authorizationapi.ClusterRole{
			ObjectMeta: kapi.ObjectMeta{
				Name: DeploymentControllerRoleName,
			},
			Rules: []authorizationapi.PolicyRule{
				// DeploymentControllerFactory.deploymentLW
				{
					Verbs:     sets.NewString("list", "watch"),
					Resources: sets.NewString("replicationcontrollers"),
				},
				// DeploymentControllerFactory.deploymentClient
				{
					Verbs:     sets.NewString("get", "update"),
					Resources: sets.NewString("replicationcontrollers"),
				},
				// DeploymentController.podClient
				{
					Verbs:     sets.NewString("get", "list", "create", "watch", "delete", "update"),
					Resources: sets.NewString("pods"),
				},
				// DeploymentController.recorder (EventBroadcaster)
				{
					Verbs:     sets.NewString("create", "update", "patch"),
					Resources: sets.NewString("events"),
				},
			},
		},
	)
	if err != nil {
		panic(err)
	}

	err = InfraSAs.addServiceAccount(
		InfraReplicationControllerServiceAccountName,
		authorizationapi.ClusterRole{
			ObjectMeta: kapi.ObjectMeta{
				Name: ReplicationControllerRoleName,
			},
			Rules: []authorizationapi.PolicyRule{
				// ReplicationManager.rcController.ListWatch
				{
					Verbs:     sets.NewString("list", "watch"),
					Resources: sets.NewString("replicationcontrollers"),
				},
				// ReplicationManager.syncReplicationController() -> updateReplicaCount()
				{
					// TODO: audit/remove those, 1.0 controllers needed get, update
					Verbs:     sets.NewString("get", "update"),
					Resources: sets.NewString("replicationcontrollers"),
				},
				// ReplicationManager.syncReplicationController() -> updateReplicaCount()
				{
					Verbs:     sets.NewString("update"),
					Resources: sets.NewString("replicationcontrollers/status"),
				},
				// ReplicationManager.podController.ListWatch
				{
					Verbs:     sets.NewString("list", "watch"),
					Resources: sets.NewString("pods"),
				},
				// ReplicationManager.podControl (RealPodControl)
				{
					Verbs:     sets.NewString("create", "delete"),
					Resources: sets.NewString("pods"),
				},
				// ReplicationManager.podControl.recorder
				{
					Verbs:     sets.NewString("create", "update", "patch"),
					Resources: sets.NewString("events"),
				},
			},
		},
	)
	if err != nil {
		panic(err)
	}

	err = InfraSAs.addServiceAccount(
		InfraJobControllerServiceAccountName,
		authorizationapi.ClusterRole{
			ObjectMeta: kapi.ObjectMeta{
				Name: JobControllerRoleName,
			},
			Rules: []authorizationapi.PolicyRule{
				// JobController.jobController.ListWatch
				{
					APIGroups: []string{extensions.GroupName, batch.GroupName},
					Verbs:     sets.NewString("list", "watch"),
					Resources: sets.NewString("jobs"),
				},
				// JobController.syncJob() -> updateJobStatus()
				{
					APIGroups: []string{extensions.GroupName, batch.GroupName},
					Verbs:     sets.NewString("update"),
					Resources: sets.NewString("jobs/status"),
				},
				// JobController.podController.ListWatch
				{
					Verbs:     sets.NewString("list", "watch"),
					Resources: sets.NewString("pods"),
				},
				// JobController.podControl (RealPodControl)
				{
					Verbs:     sets.NewString("create", "delete"),
					Resources: sets.NewString("pods"),
				},
				// JobController.podControl.recorder
				{
					Verbs:     sets.NewString("create", "update", "patch"),
					Resources: sets.NewString("events"),
				},
			},
		},
	)
	if err != nil {
		panic(err)
	}

	err = InfraSAs.addServiceAccount(
		InfraHPAControllerServiceAccountName,
		authorizationapi.ClusterRole{
			ObjectMeta: kapi.ObjectMeta{
				Name: HPAControllerRoleName,
			},
			Rules: []authorizationapi.PolicyRule{
				// HPA Controller
				{
					APIGroups: []string{extensions.GroupName, autoscaling.GroupName},
					Verbs:     sets.NewString("get", "list", "watch"),
					Resources: sets.NewString("horizontalpodautoscalers"),
				},
				{
					APIGroups: []string{extensions.GroupName, autoscaling.GroupName},
					Verbs:     sets.NewString("update"),
					Resources: sets.NewString("horizontalpodautoscalers/status"),
				},
				{
					APIGroups: []string{extensions.GroupName, kapi.GroupName},
					Verbs:     sets.NewString("get", "update"),
					Resources: sets.NewString("replicationcontrollers/scale"),
				},
				{
					Verbs:     sets.NewString("get", "update"),
					Resources: sets.NewString("deploymentconfigs/scale"),
				},
				{
					Verbs:     sets.NewString("create", "update", "patch"),
					Resources: sets.NewString("events"),
				},
				// Heapster MetricsClient
				{
					Verbs:     sets.NewString("list"),
					Resources: sets.NewString("pods"),
				},
				{
					// TODO: fix MetricsClient to no longer require root proxy access
					// TODO: restrict this to the appropriate namespace
					Verbs:         sets.NewString("proxy"),
					Resources:     sets.NewString("services"),
					ResourceNames: sets.NewString("https:heapster:"),
				},
			},
		},
	)
	if err != nil {
		panic(err)
	}

	err = InfraSAs.addServiceAccount(
		InfraPersistentVolumeRecyclerControllerServiceAccountName,
		authorizationapi.ClusterRole{
			ObjectMeta: kapi.ObjectMeta{
				Name: PersistentVolumeRecyclerControllerRoleName,
			},
			Rules: []authorizationapi.PolicyRule{
				// PersistentVolumeRecycler.volumeController.ListWatch
				{
					Verbs:     sets.NewString("list", "watch"),
					Resources: sets.NewString("persistentvolumes"),
				},
				// PersistentVolumeRecycler.syncVolume()
				{
					Verbs:     sets.NewString("get", "update", "create", "delete"),
					Resources: sets.NewString("persistentvolumes"),
				},
				// PersistentVolumeRecycler.syncVolume()
				{
					Verbs:     sets.NewString("update"),
					Resources: sets.NewString("persistentvolumes/status"),
				},
				// PersistentVolumeRecycler.claimController.ListWatch
				{
					Verbs:     sets.NewString("list", "watch"),
					Resources: sets.NewString("persistentvolumeclaims"),
				},
				// PersistentVolumeRecycler.syncClaim()
				{
					Verbs:     sets.NewString("get", "update"),
					Resources: sets.NewString("persistentvolumeclaims"),
				},
				// PersistentVolumeRecycler.syncClaim()
				{
					Verbs:     sets.NewString("update"),
					Resources: sets.NewString("persistentvolumeclaims/status"),
				},
				// PersistentVolumeRecycler.reclaimVolume() -> handleRecycle()
				{
					Verbs:     sets.NewString("list", "watch"),
					Resources: sets.NewString("pods"),
				},
				// PersistentVolumeRecycler.reclaimVolume() -> handleRecycle()
				{
					Verbs:     sets.NewString("get", "create", "delete"),
					Resources: sets.NewString("pods"),
				},
				// PersistentVolumeRecycler.reclaimVolume() -> handleRecycle()
				{
					Verbs:     sets.NewString("create", "update", "patch"),
					Resources: sets.NewString("events"),
				},
			},
		},
	)
	if err != nil {
		panic(err)
	}

	err = InfraSAs.addServiceAccount(
		InfraPersistentVolumeBinderControllerServiceAccountName,
		authorizationapi.ClusterRole{
			ObjectMeta: kapi.ObjectMeta{
				Name: PersistentVolumeBinderControllerRoleName,
			},
			Rules: []authorizationapi.PolicyRule{
				// PersistentVolumeBinder.volumeController.ListWatch
				{
					Verbs:     sets.NewString("list", "watch"),
					Resources: sets.NewString("persistentvolumes"),
				},
				// PersistentVolumeBinder.syncVolume()
				{
					Verbs:     sets.NewString("get", "update", "create", "delete"),
					Resources: sets.NewString("persistentvolumes"),
				},
				// PersistentVolumeBinder.syncVolume()
				{
					Verbs:     sets.NewString("update"),
					Resources: sets.NewString("persistentvolumes/status"),
				},
				// PersistentVolumeBinder.claimController.ListWatch
				{
					Verbs:     sets.NewString("list", "watch"),
					Resources: sets.NewString("persistentvolumeclaims"),
				},
				// PersistentVolumeBinder.syncClaim()
				{
					Verbs:     sets.NewString("get", "update"),
					Resources: sets.NewString("persistentvolumeclaims"),
				},
				// PersistentVolumeBinder.syncClaim()
				{
					Verbs:     sets.NewString("update"),
					Resources: sets.NewString("persistentvolumeclaims/status"),
				},
			},
		},
	)
	if err != nil {
		panic(err)
	}

	err = InfraSAs.addServiceAccount(
		InfraPersistentVolumeProvisionerControllerServiceAccountName,
		authorizationapi.ClusterRole{
			ObjectMeta: kapi.ObjectMeta{
				Name: PersistentVolumeProvisionerControllerRoleName,
			},
			Rules: []authorizationapi.PolicyRule{
				// PersistentVolumeProvisioner.volumeController.ListWatch
				{
					Verbs:     sets.NewString("list", "watch"),
					Resources: sets.NewString("persistentvolumes"),
				},
				// PersistentVolumeProvisioner.syncVolume()
				{
					Verbs:     sets.NewString("get", "update", "create", "delete"),
					Resources: sets.NewString("persistentvolumes"),
				},
				// PersistentVolumeProvisioner.syncVolume()
				{
					Verbs:     sets.NewString("update"),
					Resources: sets.NewString("persistentvolumes/status"),
				},
				// PersistentVolumeProvisioner.claimController.ListWatch
				{
					Verbs:     sets.NewString("list", "watch"),
					Resources: sets.NewString("persistentvolumeclaims"),
				},
				// PersistentVolumeProvisioner.syncClaim()
				{
					Verbs:     sets.NewString("get", "update"),
					Resources: sets.NewString("persistentvolumeclaims"),
				},
				// PersistentVolumeProvisioner.syncClaim()
				{
					Verbs:     sets.NewString("update"),
					Resources: sets.NewString("persistentvolumeclaims/status"),
				},
			},
		},
	)
	if err != nil {
		panic(err)
	}

	err = InfraSAs.addServiceAccount(
		InfraDaemonSetControllerServiceAccountName,
		authorizationapi.ClusterRole{
			ObjectMeta: kapi.ObjectMeta{
				Name: DaemonSetControllerRoleName,
			},
			Rules: []authorizationapi.PolicyRule{
				// DaemonSetsController.dsStore.ListWatch
				{
					APIGroups: []string{extensions.GroupName},
					Verbs:     sets.NewString("list", "watch"),
					Resources: sets.NewString("daemonsets"),
				},
				// DaemonSetsController.podStore.ListWatch
				{
					Verbs:     sets.NewString("list", "watch"),
					Resources: sets.NewString("pods"),
				},
				// DaemonSetsController.nodeStore.ListWatch
				{
					Verbs:     sets.NewString("list", "watch"),
					Resources: sets.NewString("nodes"),
				},
				// DaemonSetsController.storeDaemonSetStatus
				{
					APIGroups: []string{extensions.GroupName},
					Verbs:     sets.NewString("update"),
					Resources: sets.NewString("daemonsets/status"),
				},
				// DaemonSetsController.podControl (RealPodControl)
				{
					Verbs:     sets.NewString("create", "delete"),
					Resources: sets.NewString("pods"),
				},
				{
					APIGroups: []string{kapi.GroupName},
					Verbs:     sets.NewString("create"),
					Resources: sets.NewString("pods/binding"),
				},
				// DaemonSetsController.podControl.recorder
				{
					Verbs:     sets.NewString("create", "update", "patch"),
					Resources: sets.NewString("events"),
				},
			},
		},
	)
	if err != nil {
		panic(err)
	}

	err = InfraSAs.addServiceAccount(
		InfraNamespaceControllerServiceAccountName,
		authorizationapi.ClusterRole{
			ObjectMeta: kapi.ObjectMeta{
				Name: NamespaceControllerRoleName,
			},
			Rules: []authorizationapi.PolicyRule{
				// Watching/deleting namespaces
				{
					APIGroups: []string{kapi.GroupName},
					Verbs:     sets.NewString("get", "list", "watch", "delete"),
					Resources: sets.NewString("namespaces"),
				},
				// Updating status to terminating, updating finalizer list
				{
					APIGroups: []string{kapi.GroupName},
					Verbs:     sets.NewString("update"),
					Resources: sets.NewString("namespaces/finalize", "namespaces/status"),
				},

				// Ability to delete resources
				{
					APIGroups: []string{"*"},
					Verbs:     sets.NewString("get", "list", "delete", "deletecollection"),
					Resources: sets.NewString("*"),
				},
			},
		},
	)
	if err != nil {
		panic(err)
	}

	err = InfraSAs.addServiceAccount(
		InfraGCControllerServiceAccountName,
		authorizationapi.ClusterRole{
			ObjectMeta: kapi.ObjectMeta{
				Name: GCControllerRoleName,
			},
			Rules: []authorizationapi.PolicyRule{
				// GCController.podStore.ListWatch
				{
					APIGroups: []string{kapi.GroupName},
					Verbs:     sets.NewString("list", "watch"),
					Resources: sets.NewString("pods"),
				},
				// GCController.deletePod
				{
					APIGroups: []string{kapi.GroupName},
					Verbs:     sets.NewString("delete"),
					Resources: sets.NewString("pods"),
				},
			},
		},
	)
	if err != nil {
		panic(err)
	}

	err = InfraSAs.addServiceAccount(
		InfraServiceLoadBalancerControllerServiceAccountName,
		authorizationapi.ClusterRole{
			ObjectMeta: kapi.ObjectMeta{
				Name: ServiceLoadBalancerControllerRoleName,
			},
			Rules: []authorizationapi.PolicyRule{
				// ServiceController.cache.ListWatch
				{
					APIGroups: []string{kapi.GroupName},
					Verbs:     sets.NewString("list", "watch"),
					Resources: sets.NewString("services"),
				},
				// ServiceController.processDelta needs to fetch the latest service
				{
					APIGroups: []string{kapi.GroupName},
					Verbs:     sets.NewString("get"),
					Resources: sets.NewString("services"),
				},
				// ServiceController.persistUpdate changes the status of the service
				{
					APIGroups: []string{kapi.GroupName},
					Verbs:     sets.NewString("update"),
					Resources: sets.NewString("services/status"),
				},
				// ServiceController.nodeLister.ListWatch
				{
					APIGroups: []string{kapi.GroupName},
					Verbs:     sets.NewString("list", "watch"),
					Resources: sets.NewString("nodes"),
				},
				// ServiceController.eventRecorder
				{
					Verbs:     sets.NewString("create", "update", "patch"),
					Resources: sets.NewString("events"),
				},
			},
		},
	)
	if err != nil {
		panic(err)
	}

	err = InfraSAs.addServiceAccount(
		ServiceServingCertServiceAccountName,
		authorizationapi.ClusterRole{
			ObjectMeta: kapi.ObjectMeta{
				Name: ServiceServingCertControllerRoleName,
			},
			Rules: []authorizationapi.PolicyRule{
				{
					APIGroups: []string{kapi.GroupName},
					Verbs:     sets.NewString("list", "watch", "update"),
					Resources: sets.NewString("services"),
				},
				{
					APIGroups: []string{kapi.GroupName},
					Verbs:     sets.NewString("get", "create"),
					Resources: sets.NewString("secrets"),
				},
			},
		},
	)
	if err != nil {
		panic(err)
	}

}


text:
app.factory('httpInterceptorService', ['$q', '$injector','$location', '$window',  function ($q, $injector, $location, $window) {
    return {
    // optional method
    'request': function(config) {
        config.headers = config.headers || {};
        //TO DO
        return config;
    },

    'response': function(response) {

         // successful response
        return response; // or $q.when(config);
    },
    'requestError': function(rejection) {

        // an error happened on the request
        // if we can recover from the error
        // we can return a new request
        // or promise
        //return response; // or new promise
        // Otherwise, we can reject the next
        // by returning a rejection
        return $q.reject(rejection);
    },
    'responseError': function(rejection) {
    	if(rejection.status == '401'){
    		//console.log($injector.authService)
    		//$injector.get('authService').logout();
    		//$location.path('/login');
    	}
        // an error happened on the request
        // if we can recover from the error
        // we can return a new response
        // or promise
        //return rejection; // or new promise
       // Otherwise, we can reject the next
       // by returning a rejection
        return $q.reject(rejection);
    }

  };

}]);


text:
package org.osehra.vista.example.cxf.jaxrs;

import org.osehra.vista.example.cxf.jaxrs.resources.MedicalRecords;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;

public final class JAXWSClient {
    private MedicalRecords emr;

    public JAXWSClient() {
        JaxWsProxyFactoryBean cfb = new JaxWsProxyFactoryBean();
        cfb.setServiceClass(MedicalRecords.class);
        cfb.setAddress("http://localhost:" + System.getProperty("soapEndpointPort") + "/soap");
        emr = (MedicalRecords) cfb.create();
    }

    public MedicalRecords getMedicalRecords() {
        return emr;
    }

}


text:
layout: post
title: "6. Les facteurs ordonnés"
category: posts
group: factor
---

Les facteurs ordonnés

vitesse_vector doit être converti en un facteur ordinal puisque ses niveaux ont un ordre naturel. Par défaut, la fonction factor() transforme vitesse_vector en un factor non ordonné. Pour créer un factor ordonné, vous devez ajouter deux arguments supplémentaires: ordered et levels.

factor(un_vector, ordered = TRUE, levels = c("Level_1", "Level_2"...))

En définissant l'argument ordered à TRUE dans la fonction factor(), vous indiquez que le factor est ordonné. Avec l'argument levels vous donnez les valeurs du factor dans l'ordre correct, par exemple

levels = c("Faible", "Moyen", "Fort").

L'exemple de code ci-dessus permet de définir une variable factor_vitesse_vector en tenant compte du fait qu'il y a un ordre spécifique pour les niveaux de facteur. Ne changez rien aux autres lignes de code, cela imprimera le facteur dans la console et générera un résumé de celui-ci.

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

vitesse_vector <- c("Rapide", "Lent", "Lent", "Rapide", "Ultra-Rapide")

# Rajoutez votre code ci dessous
factor_vitesse_vector <- factor(vitesse_vector, ordered = TRUE, levels= c("Lent", "Rapide", "Ultra-Rapide"))

# Visualisation
factor_vitesse_vector

# R affiche automatiquement le bon ordre
summary(factor_vitesse_vector)