text:
package org.apache.jackrabbit.oak.plugins.index;

import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.Arrays.asList;
import static org.apache.jackrabbit.JcrConstants.NT_BASE;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.ASYNC_PROPERTY_NAME;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.ASYNC_REINDEX_VALUE;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEXING_MODE_NRT;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_CONTENT_NODE_NAME;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_ASYNC_PROPERTY_NAME;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_COUNT;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_PROPERTY_NAME;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_DISABLED;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME;
import static org.apache.jackrabbit.oak.plugins.index.IndexUpdateCallback.NOOP;
import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.createIndexDefinition;
import static org.apache.jackrabbit.oak.InitialContentHelper.INITIAL_CONTENT;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.Calendar;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

import ch.qos.logback.classic.Level;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.commons.junit.LogCustomizer;
import org.apache.jackrabbit.oak.plugins.index.IndexUpdate.MissingIndexProviderStrategy;
import org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexEditorProvider;
import org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexLookup;
import org.apache.jackrabbit.oak.plugins.index.reference.ReferenceEditorProvider;
import org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState;
import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore;
import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
import org.apache.jackrabbit.oak.plugins.memory.PropertyValues;
import org.apache.jackrabbit.oak.query.NodeStateNodeTypeInfoProvider;
import org.apache.jackrabbit.oak.query.QueryEngineSettings;
import org.apache.jackrabbit.oak.query.ast.NodeTypeInfo;
import org.apache.jackrabbit.oak.query.ast.NodeTypeInfoProvider;
import org.apache.jackrabbit.oak.query.ast.SelectorImpl;
import org.apache.jackrabbit.oak.query.index.FilterImpl;
import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
import org.apache.jackrabbit.oak.spi.commit.Editor;
import org.apache.jackrabbit.oak.spi.commit.EditorHook;
import org.apache.jackrabbit.oak.spi.commit.EditorProvider;
import org.apache.jackrabbit.oak.spi.filter.PathFilter;
import org.apache.jackrabbit.oak.spi.query.Filter;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.NodeStateUtils;
import org.apache.jackrabbit.oak.spi.state.NodeStore;
import org.apache.jackrabbit.util.ISO8601;
import org.hamcrest.core.IsCollectionContaining;
import org.jetbrains.annotations.NotNull;
import org.junit.Assert;
import org.junit.Test;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;

public class IndexUpdateTest {

    private static final EditorHook HOOK = new EditorHook(
            new IndexUpdateProvider(new PropertyIndexEditorProvider()));

    private NodeState root = INITIAL_CONTENT;

    private NodeBuilder builder = root.builder();

    /**
     * Simple Test
     *

     *
Add an index definition

     *
Add some content

     *
Search & verify

     *

     *
     */
    @Test
    public void test() throws Exception {
        createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "rootIndex", true, false, ImmutableSet.of("foo"), null);
        createIndexDefinition(
                builder.child("newchild").child("other")
                        .child(INDEX_DEFINITIONS_NAME), "subIndex", true,
                false, ImmutableSet.of("foo"), null);

        NodeState before = builder.getNodeState();

        // Add nodes
        builder.child("testRoot").setProperty("foo", "abc");
        builder.child("newchild").child("other").child("testChild")
                .setProperty("foo", "xyz");

        NodeState after = builder.getNodeState();

        NodeState indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);

        // first check that the index content nodes exist
        checkPathExists(indexed, INDEX_DEFINITIONS_NAME, "rootIndex",
                INDEX_CONTENT_NODE_NAME);
        checkPathExists(indexed, "newchild", "other", INDEX_DEFINITIONS_NAME,
                "subIndex", INDEX_CONTENT_NODE_NAME);

        PropertyIndexLookup lookup = new PropertyIndexLookup(indexed);
        assertEquals(ImmutableSet.of("testRoot"), find(lookup, "foo", "abc"));

        PropertyIndexLookup lookupChild = new PropertyIndexLookup(indexed
                .getChildNode("newchild").getChildNode("other"));
        assertEquals(ImmutableSet.of("testChild"),
                find(lookupChild, "foo", "xyz"));
        assertEquals(ImmutableSet.of(), find(lookupChild, "foo", "abc"));

    }

    /**
     * Reindex Test
     *

     *
Add some content

     *
Add an index definition with the reindex flag set

     *
Search & verify

     *

     */
    @Test
    public void testReindex() throws Exception {
        builder.child("testRoot").setProperty("foo", "abc");
        NodeState before = builder.getNodeState();
        createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "rootIndex", true, false, ImmutableSet.of("foo"), null);

        NodeState after = builder.getNodeState();

        NodeState indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);

        // first check that the index content nodes exist
        NodeState ns = checkPathExists(indexed, INDEX_DEFINITIONS_NAME,
                "rootIndex");
        checkPathExists(ns, INDEX_CONTENT_NODE_NAME);
        PropertyState ps = ns.getProperty(REINDEX_PROPERTY_NAME);
        assertNotNull(ps);
        assertFalse(ps.getValue(Type.BOOLEAN));

        // next, lookup
        PropertyIndexLookup lookup = new PropertyIndexLookup(indexed);
        assertEquals(ImmutableSet.of("testRoot"), find(lookup, "foo", "abc"));
    }

    /**
     * Reindex Test
     *

     *
Add some content & an index definition

     *
Update the index def by setting the reindex flag to true

     *
Search & verify

     *

     */
    @Test
    public void testReindex2() throws Exception {
        builder.child("testRoot").setProperty("foo", "abc");

        createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "rootIndex", true, false, ImmutableSet.of("foo"), null)
                .removeProperty("reindex");

        NodeState before = builder.getNodeState();
        builder.child(INDEX_DEFINITIONS_NAME).child("rootIndex")
                .setProperty(REINDEX_PROPERTY_NAME, true);
        NodeState after = builder.getNodeState();

        NodeState indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);

        // first check that the index content nodes exist
        NodeState ns = checkPathExists(indexed, INDEX_DEFINITIONS_NAME,
                "rootIndex");
        checkPathExists(ns, INDEX_CONTENT_NODE_NAME);
        PropertyState ps = ns.getProperty(REINDEX_PROPERTY_NAME);
        assertNotNull(ps);
        assertFalse(ps.getValue(Type.BOOLEAN));

        // next, lookup
        PropertyIndexLookup lookup = new PropertyIndexLookup(indexed);
        assertEquals(ImmutableSet.of("testRoot"), find(lookup, "foo", "abc"));
    }

    /**
     * Auto Reindex Test
     *

     *
Add some content

     *
Add an index definition without a reindex flag (see OAK-1874)

     *
Search & verify

     *

     */
    @Test
    public void testReindexAuto() throws Exception {
        builder.child("testRoot").setProperty("foo", "abc");
        NodeState before = builder.getNodeState();

        createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "rootIndex", false, false, ImmutableSet.of("foo"), null);

        NodeState after = builder.getNodeState();

        NodeState indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);

        // first check that the index content nodes exist
        NodeState ns = checkPathExists(indexed, INDEX_DEFINITIONS_NAME,
                "rootIndex");
        checkPathExists(ns, INDEX_CONTENT_NODE_NAME);
        PropertyState ps = ns.getProperty(REINDEX_PROPERTY_NAME);
        assertNotNull(ps);
        assertFalse(ps.getValue(Type.BOOLEAN));

        // next, lookup
        PropertyIndexLookup lookup = new PropertyIndexLookup(indexed);
        assertEquals(ImmutableSet.of("testRoot"), find(lookup, "foo", "abc"));
    }

    @Test
    public void testReindexAuto_ImportCase() throws Exception{
        NodeState before = builder.getNodeState();

        NodeBuilder idx = createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "rootIndex", false, false, ImmutableSet.of("foo"), null);
        idx.child(":index");

        NodeState after = builder.getNodeState();

        NodeState indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);
        NodeState ns = checkPathExists(indexed, INDEX_DEFINITIONS_NAME,
                "rootIndex");

        assertEquals(0, ns.getLong("reindexCount"));
        PropertyState ps = ns.getProperty(REINDEX_PROPERTY_NAME);
        assertNotNull(ps);
        assertFalse(ps.getValue(Type.BOOLEAN));
    }

    @Test
    public void testReindexHidden() throws Exception {
        NodeState before = EmptyNodeState.EMPTY_NODE;
        NodeBuilder builder = before.builder();
        builder.child(":testRoot").setProperty("foo", "abc");
        createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "rootIndex", false, false, ImmutableSet.of("foo"), null);
        NodeState after = builder.getNodeState();
        NodeState indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);

        // first check that the index content nodes exist
        NodeState ns = checkPathExists(indexed, INDEX_DEFINITIONS_NAME,
                "rootIndex");
        NodeState index = checkPathExists(ns, INDEX_CONTENT_NODE_NAME);
        PropertyState ps = ns.getProperty(REINDEX_PROPERTY_NAME);
        assertNotNull(ps);
        assertFalse(ps.getValue(Type.BOOLEAN));
        assertFalse(index.getChildNodeCount(1) > 0);

        before = indexed;
        builder = before.builder();
        builder.child(INDEX_DEFINITIONS_NAME).child("rootIndex")
                .setProperty("reindex", true);
        after = builder.getNodeState();
        indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);
        index = checkPathExists(ns, INDEX_CONTENT_NODE_NAME);
        ps = ns.getProperty(REINDEX_PROPERTY_NAME);
        assertNotNull(ps);
        assertFalse(ps.getValue(Type.BOOLEAN));
        assertFalse(index.getChildNodeCount(1) > 0);
    }

    @Test
    public void testIndexDefinitions() throws Exception {
        createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "existing", true, false, ImmutableSet.of("foo"), null);

        NodeState before = builder.getNodeState();
        NodeBuilder other = builder.child("test").child("other");
        // Add index definition
        createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME), "foo",
                true, false, ImmutableSet.of("foo"), null);
        createIndexDefinition(
                other.child(INDEX_DEFINITIONS_NAME), "index2", true, false,
                ImmutableSet.of("foo"), null);
        NodeState after = builder.getNodeState();

        NodeState indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);

        // check that the index content nodes exist
        checkPathExists(indexed, INDEX_DEFINITIONS_NAME, "existing",
                INDEX_CONTENT_NODE_NAME);
        checkPathExists(indexed, "test", "other", INDEX_DEFINITIONS_NAME,
                "index2", INDEX_CONTENT_NODE_NAME);
    }

    @Test
    public void reindexAndIndexDefnChildRemoval_OAK_2117() throws Exception{
        builder.child("testRoot").setProperty("foo", "abc");
        NodeState before = builder.getNodeState();

        NodeBuilder nb = createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "rootIndex", false, false, ImmutableSet.of("foo"), null);
        nb.child("prop1").setProperty("foo", "bar");

        NodeState after = builder.getNodeState();

        NodeState indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);

        // first check that the index content nodes exist
        NodeState ns = checkPathExists(indexed, INDEX_DEFINITIONS_NAME,
                "rootIndex");

        //Check index defn child node exist
        checkPathExists(ns, "prop1");
        checkPathExists(ns, INDEX_CONTENT_NODE_NAME);

        // next, lookup
        PropertyIndexLookup lookup = new PropertyIndexLookup(indexed);
        assertEquals(ImmutableSet.of("testRoot"), find(lookup, "foo", "abc"));

    }

    /**
     * Tests that with explicit reindex i.e. reindex=true those hidden nodes
     * which have IndexConstants.REINDEX_RETAIN set to true are not removed
     */
    @Test
    public void reindexSkipRemovalOfRetainedNodes() throws Exception{
        builder.child("testRoot").setProperty("foo", "abc");
        NodeState before = builder.getNodeState();

        NodeBuilder nb = createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "rootIndex", true, false, ImmutableSet.of("foo"), null);
        nb.child(":hidden-node-1").setProperty("foo", "bar");
        nb.child(":hidden-node-2").setProperty(IndexConstants.REINDEX_RETAIN, true);
        nb.child("visible-node");

        NodeState after = builder.getNodeState();

        NodeState indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);

        // first check that the index content nodes exist
        NodeState ns = checkPathExists(indexed, INDEX_DEFINITIONS_NAME, "rootIndex");
        checkPathExists(ns, "visible-node");
        checkPathExists(ns, ":hidden-node-2");
        assertFalse(ns.getChildNode(":hidden-node-1").exists());
        assertEquals(1, ns.getLong(REINDEX_COUNT));
    }

    /**
     * Test that an index is still reindexed if it has hidden nodes but with all such
     * hidden nodes having IndexConstants.REINDEX_RETAIN set to true i.e. this index
     * does not yet have any hidden nodes corresponding to persisted index like lucene
     */
    @Test
    public void reindexSkipRemovalOfRetainedNodes_FreshIndex() throws Exception{
        builder.child("testRoot").setProperty("foo", "abc");
        NodeState before = builder.getNodeState();

        NodeBuilder nb = createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "rootIndex", false, false, ImmutableSet.of("foo"), null);
        nb.child(":hidden-node-2").setProperty(IndexConstants.REINDEX_RETAIN, true);
        nb.child("visible-node");

        NodeState after = builder.getNodeState();

        NodeState indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);

        // first check that the index content nodes exist
        NodeState ns = checkPathExists(indexed, INDEX_DEFINITIONS_NAME, "rootIndex");
        checkPathExists(ns, "visible-node");
        checkPathExists(ns, ":hidden-node-2");
        assertEquals(1, ns.getLong(REINDEX_COUNT));
    }

    /**
     * Async Reindex Test (OAK-2174)
     *

     *
Add some content

     *
Add an index definition with the reindex flag and the reindex-async flag set

     *
Run the background async job manually

     *
Search & verify

     *

     */
    @Test
    public void testReindexAsync() throws Exception {
        IndexEditorProvider provider = new PropertyIndexEditorProvider();
        EditorHook hook = new EditorHook(new IndexUpdateProvider(provider));

        NodeStore store = new MemoryNodeStore();
        NodeBuilder builder = store.getRoot().builder();

        createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "rootIndex", true, false, ImmutableSet.of("foo"), null)
                .setProperty(REINDEX_ASYNC_PROPERTY_NAME, true);
        builder.child("testRoot").setProperty("foo", "abc");

        // merge it back in
        store.merge(builder, hook, CommitInfo.EMPTY);

        // first check that the async flag exist
        NodeState ns1 = checkPathExists(store.getRoot(),
                INDEX_DEFINITIONS_NAME, "rootIndex");
        assertTrue(ns1.getProperty(REINDEX_PROPERTY_NAME)
                .getValue(Type.BOOLEAN));
        assertTrue(ns1.getProperty(REINDEX_ASYNC_PROPERTY_NAME).getValue(
                Type.BOOLEAN));
        assertEquals(ASYNC_REINDEX_VALUE, ns1.getString(ASYNC_PROPERTY_NAME));

        AsyncIndexUpdate async = new AsyncIndexUpdate(ASYNC_REINDEX_VALUE,
                store, provider, true);
        int max = 5;
        // same behaviour as PropertyIndexAsyncReindex mbean
        boolean done = false;
        int count = 0;
        while (!done || count >= max) {
            async.run();
            done = async.isFinished();
            count++;
        }

        // first check that the index content nodes exist
        NodeState ns = checkPathExists(store.getRoot(), INDEX_DEFINITIONS_NAME,
                "rootIndex");
        checkPathExists(ns, INDEX_CONTENT_NODE_NAME);
        assertFalse(ns.getProperty(REINDEX_PROPERTY_NAME)
                .getValue(Type.BOOLEAN));
        assertNull(ns.getProperty(ASYNC_PROPERTY_NAME));

        // next, lookup
        PropertyIndexLookup lookup = new PropertyIndexLookup(store.getRoot());
        assertEquals(ImmutableSet.of("testRoot"), find(lookup, "foo",
        "abc"));
    }

    /**
     * OAK-2203 Test reindex behavior on a sync index when the index provider is missing
     * for a given type
     */
    @Test
    public void testReindexSyncMissingProvider() throws Exception {
        EditorHook hook = new EditorHook(new IndexUpdateProvider(
                emptyProvider()));
        NodeState before = builder.getNodeState();

        createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "rootIndex", true, false, ImmutableSet.of("foo"), null);
        builder.child(INDEX_DEFINITIONS_NAME).child("azerty");
        builder.child("testRoot").setProperty("foo", "abc");
        NodeState after = builder.getNodeState();

        NodeState indexed = hook.processCommit(before, after, CommitInfo.EMPTY);
        NodeState rootIndex = checkPathExists(indexed, INDEX_DEFINITIONS_NAME,
                "rootIndex");
        PropertyState ps = rootIndex.getProperty(REINDEX_PROPERTY_NAME);
        assertNotNull(ps);
        assertTrue(ps.getValue(Type.BOOLEAN));

        NodeState azerty = checkPathExists(indexed, INDEX_DEFINITIONS_NAME,
                "azerty");
        assertNull("Node should be ignored by reindexer",
                azerty.getProperty(REINDEX_PROPERTY_NAME));
    }

    /**
     * OAK-3505 Provide an optionally stricter policy for missing synchronous
     * index editor providers
     */
    @Test
    public void testMissingProviderFailsCommit() throws Exception {

        final IndexUpdateCallback noop = new IndexUpdateCallback() {
            @Override
            public void indexUpdate() {
            }
        };
        final MissingIndexProviderStrategy mips = new MissingIndexProviderStrategy();
        mips.setFailOnMissingIndexProvider(true);

        EditorHook hook = new EditorHook(new EditorProvider() {
            @Override
            public Editor getRootEditor(NodeState before, NodeState after,
                    NodeBuilder builder, CommitInfo info)
                    throws CommitFailedException {
                return new IndexUpdate(emptyProvider(), null, after, builder,
                        noop).withMissingProviderStrategy(mips);
            }
        });

        NodeState before = builder.getNodeState();

        createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "rootIndex", true, false, ImmutableSet.of("foo"), null);
        builder.child(INDEX_DEFINITIONS_NAME).child("azerty");
        builder.child("testRoot").setProperty("foo", "abc");
        NodeState after = builder.getNodeState();

        try {
            hook.processCommit(before, after, CommitInfo.EMPTY);
            fail("commit should fail on missing index provider");
        } catch (CommitFailedException ex) {
            // expected
        }
    }

    /**
     * OAK-7686: async def with nrt/sync def should fail on missing provider only when running in
     * context of an async cycle
     */
    @Test
    public void testMissingProviderWithAsyncDef() throws Exception {
        final MissingIndexProviderStrategy mips = new MissingIndexProviderStrategy();
        mips.setFailOnMissingIndexProvider(true);

        // prepare different hooks for different types indexing cycles
        EditorHook syncHook = new EditorHook((before, after, builder, info) ->
                new IndexUpdate(emptyProvider(), null, after, builder, NOOP)
                        .withMissingProviderStrategy(mips));
        EditorHook asyncHook = new EditorHook((before, after, builder, info) ->
                new IndexUpdate(emptyProvider(), "async-run", after, builder, NOOP)
                        .withMissingProviderStrategy(mips));
        EditorHook otherAsyncHook = new EditorHook((before, after, builder, info) ->
                new IndexUpdate(emptyProvider(), "other-async-run", after, builder, NOOP)
                        .withMissingProviderStrategy(mips));

        builder = EmptyNodeState.EMPTY_NODE.builder();

        // create async defs with nrt and sync mixed in
        createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "asyncIndex", true, false, ImmutableSet.of("foo"), null)
                .setProperty(ASYNC_PROPERTY_NAME, ImmutableList.of("async-run"), Type.STRINGS)
                .setProperty(REINDEX_PROPERTY_NAME, false);
        createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "nrtIndex", true, false, ImmutableSet.of("foo"), null)
                .setProperty(ASYNC_PROPERTY_NAME, ImmutableList.of("async-run", "nrt"), Type.STRINGS)
                .setProperty(REINDEX_PROPERTY_NAME, false);
        createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "asyncSyncIndex", true, false, ImmutableSet.of("foo"), null)
                .setProperty(ASYNC_PROPERTY_NAME, ImmutableList.of("async-run", "sync"), Type.STRINGS)
                .setProperty(REINDEX_PROPERTY_NAME, false);

        // node states to run hook on
        NodeState before = builder.getNodeState();
        builder.child("testRoot").setProperty("foo", "abc");
        NodeState after = builder.getNodeState();

        // sync run should be ok with missing provider for an async def
        syncHook.processCommit(before, after, CommitInfo.EMPTY);

        // unrelated async run should be ok with missing provider
        otherAsyncHook.processCommit(before, after, CommitInfo.EMPTY);

        // async run matching the def async lane still should fail
        try {
            asyncHook.processCommit(before, after, CommitInfo.EMPTY);
            fail("commit should fail on missing index provider");
        } catch (CommitFailedException ex) {
            // expected
        }
    }

    @Test
    public void testReindexCount() throws Exception{
        builder.child("testRoot").setProperty("foo", "abc");
        NodeState before = builder.getNodeState();

        createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "rootIndex", false, false, ImmutableSet.of("foo"), null);

        NodeState after = builder.getNodeState();

        NodeState indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);
        long t1 = getReindexCount(indexed);

        NodeBuilder b2 = indexed.builder();
        b2.child(INDEX_DEFINITIONS_NAME).child("rootIndex").setProperty(IndexConstants.REINDEX_PROPERTY_NAME, true);
        indexed = HOOK.processCommit(indexed, b2.getNodeState(), CommitInfo.EMPTY);
        long t2 = getReindexCount(indexed);

        assertTrue(t2 > t1);
    }

    @Test
    public void contextAwareCallback() throws Exception{
        NodeState before = builder.getNodeState();
        createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "rootIndex", true, false, ImmutableSet.of("foo"), null);

        NodeState after = builder.getNodeState();

        CallbackCapturingProvider provider = new CallbackCapturingProvider();
        EditorHook hook = new EditorHook(new IndexUpdateProvider(provider));

        CommitInfo info = new CommitInfo("foo", "bar");
        NodeState indexed = hook.processCommit(before, after, info);

        assertNotNull(provider.callback);
        assertThat(provider.callback, instanceOf(ContextAwareCallback.class));
        ContextAwareCallback contextualCallback = (ContextAwareCallback) provider.callback;
        IndexingContext context = contextualCallback.getIndexingContext();

        assertNotNull(context);
        assertEquals("/oak:index/rootIndex", context.getIndexPath());
        assertTrue(context.isReindexing());
        assertFalse(context.isAsync());
        assertSame(info, context.getCommitInfo());

        before = indexed;
        builder = indexed.builder();
        builder.child("a").setProperty("foo", "bar");
        after = builder.getNodeState();

        hook.processCommit(before, after, info);
        assertFalse(((ContextAwareCallback)provider.callback).getIndexingContext().isReindexing());
    }

    @Test
    public void contextAwareCallback_async() throws Exception{
        NodeState before = builder.getNodeState();
        NodeBuilder idx = createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "rootIndex", true, false, ImmutableSet.of("foo"), null);
        idx.setProperty("async", asList("sync", "async"), Type.STRINGS);

        NodeState after = builder.getNodeState();

        CallbackCapturingProvider provider = new CallbackCapturingProvider();
        EditorHook hook = new EditorHook(new IndexUpdateProvider(provider, "async", false));

        hook.processCommit(before, after, CommitInfo.EMPTY);

        assertTrue(((ContextAwareCallback)provider.callback).getIndexingContext().isAsync());
    }

    private static class CallbackCapturingProvider extends PropertyIndexEditorProvider {
        private Map<String, IndexingContext> callbacks = Maps.newHashMap();
        IndexUpdateCallback callback;

        @Override
        public Editor getIndexEditor(@NotNull String type, @NotNull NodeBuilder definition,
                                     @NotNull NodeState root, @NotNull IndexUpdateCallback callback) {
            Editor editor = super.getIndexEditor(type, definition, root, callback);
            if (editor != null){
                this.callback = callback;
                if (callback instanceof ContextAwareCallback){
                    IndexingContext context = ((ContextAwareCallback) callback).getIndexingContext();
                    callbacks.put(context.getIndexPath(), context);
                }
            }
            return editor;
        }

        public void reset(){
            callback = null;
            callbacks.clear();
        }

        public IndexingContext getContext(String indexPath){
            return callbacks.get(indexPath);
        }
    }

    long getReindexCount(NodeState indexed) {
        return indexed.getChildNode(INDEX_DEFINITIONS_NAME)
                .getChildNode("rootIndex")
                .getProperty(IndexConstants.REINDEX_COUNT).getValue(Type.LONG);
    }

    private static IndexEditorProvider emptyProvider() {
        return new IndexEditorProvider() {
            @Override
            public Editor getIndexEditor(@NotNull String type, @NotNull NodeBuilder definition,
                    @NotNull NodeState root, @NotNull IndexUpdateCallback callback)
                    throws CommitFailedException {
                return null;
            }
        };
    }

    private Set<String> find(PropertyIndexLookup lookup, String name,
            String value) {
        NodeTypeInfoProvider nodeTypes = new NodeStateNodeTypeInfoProvider(root);
        NodeTypeInfo type = nodeTypes.getNodeTypeInfo(NT_BASE);
        SelectorImpl selector = new SelectorImpl(type, NT_BASE);
        Filter filter = new FilterImpl(selector, "SELECT * FROM [nt:base]", new QueryEngineSettings());
        return Sets.newHashSet(lookup.query(filter, name,
                PropertyValues.newString(value)));
    }

    static NodeState checkPathExists(NodeState state, String... verify) {
        NodeState c = state;
        for (String p : verify) {
            c = c.getChildNode(p);
            assertTrue(c.exists());
        }
        return c;
    }

    @Test
    public void testAsyncMVPDefinition() throws Exception {
        NodeBuilder base;

        // async null
        base = EmptyNodeState.EMPTY_NODE.builder();
        assertTrue(IndexUpdate.isIncluded(null, base));
        assertFalse(IndexUpdate.isIncluded("async", base));

        // async single value
        base = EmptyNodeState.EMPTY_NODE.builder().setProperty(
                ASYNC_PROPERTY_NAME, "async");
        assertFalse(IndexUpdate.isIncluded(null, base));
        assertTrue(IndexUpdate.isIncluded("async", base));

        // async multiple values: "" for sync
        base = EmptyNodeState.EMPTY_NODE.builder()
                .setProperty(ASYNC_PROPERTY_NAME, Sets.newHashSet(INDEXING_MODE_NRT, "async"),
                        Type.STRINGS);
        assertTrue(IndexUpdate.isIncluded(null, base));
        assertTrue(IndexUpdate.isIncluded("async", base));
        assertFalse(IndexUpdate.isIncluded("async-other", base));

        // async multiple values: "sync" for sync
        base = EmptyNodeState.EMPTY_NODE.builder().setProperty(
                ASYNC_PROPERTY_NAME, Sets.newHashSet("sync", "async"),
                Type.STRINGS);
        assertTrue(IndexUpdate.isIncluded(null, base));
        assertTrue(IndexUpdate.isIncluded("async", base));
        assertFalse(IndexUpdate.isIncluded("async-other", base));

        // async multiple values: no sync present
        base = EmptyNodeState.EMPTY_NODE.builder().setProperty(
                ASYNC_PROPERTY_NAME, Sets.newHashSet("async", "async-other"),
                Type.STRINGS);
        assertFalse(IndexUpdate.isIncluded(null, base));
        assertTrue(IndexUpdate.isIncluded("async", base));
        assertTrue(IndexUpdate.isIncluded("async-other", base));
    }

    @Test
    public void corruptIndexSkipped() throws Exception{
        NodeState before = builder.getNodeState();
        createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "rootIndex", true, false, ImmutableSet.of("foo"), null);

        NodeState after = builder.getNodeState();

        CallbackCapturingProvider provider = new CallbackCapturingProvider();
        EditorHook hook = new EditorHook(new IndexUpdateProvider(provider));

        //1. Basic sanity - provider gets invoked
        NodeState indexed = hook.processCommit(before, after, CommitInfo.EMPTY);
        String indexPath = "/oak:index/rootIndex";
        assertNotNull(provider.getContext(indexPath));

        //2. Mark as corrupt and assert that editor is not invoked
        builder = indexed.builder();
        before = indexed;
        builder.child("testRoot").setProperty("foo", "abc");
        markCorrupt(builder, "rootIndex");
        after = builder.getNodeState();

        provider.reset();
        indexed = hook.processCommit(before, after, CommitInfo.EMPTY);
        assertNull(provider.getContext(indexPath));

        //3. Now reindex and that should reset corrupt flag
        builder = indexed.builder();
        before = indexed;
        child(builder, indexPath).setProperty(IndexConstants.REINDEX_PROPERTY_NAME, true);
        after = builder.getNodeState();
        provider.reset();
        indexed = hook.processCommit(before, after, CommitInfo.EMPTY);

        assertFalse(NodeStateUtils.getNode(indexed, indexPath).hasProperty(IndexConstants.CORRUPT_PROPERTY_NAME));
        assertNotNull(provider.getContext(indexPath));
    }

    @Test
    public void ignoreReindexingFlag() throws Exception{
        String indexPath = "/oak:index/rootIndex";
        CallbackCapturingProvider provider = new CallbackCapturingProvider();

        IndexUpdateProvider indexUpdate = new IndexUpdateProvider(provider);
        EditorHook hook = new EditorHook(indexUpdate);

        NodeState before = builder.getNodeState();
        createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "rootIndex", true, false, ImmutableSet.of("foo"), null);

        builder.child("a").setProperty("foo", "abc");
        NodeState after = builder.getNodeState();

        NodeState indexed = hook.processCommit(before, after, CommitInfo.EMPTY);
        assertTrue(provider.getContext(indexPath).isReindexing());

        before = indexed;
        builder = before.builder();
        builder.child("b").setProperty("foo", "xyz");
        child(builder, indexPath).setProperty(IndexConstants.REINDEX_PROPERTY_NAME, true);
        after = builder.getNodeState();

        provider.reset();
        indexed = hook.processCommit(before, after, CommitInfo.EMPTY);
        assertTrue(provider.getContext(indexPath).isReindexing());

        //Now set IndexUpdate to ignore the reindex flag
        indexUpdate.setIgnoreReindexFlags(true);
        indexed = hook.processCommit(before, after, CommitInfo.EMPTY);
        assertFalse(provider.getContext(indexPath).isReindexing());

        //Despite reindex flag set to true and reindexing not done new
        //content should still get picked up
        PropertyIndexLookup lookup = new PropertyIndexLookup(indexed);
        assertFalse(find(lookup, "foo", "xyz").isEmpty());
    }

    @Test
    public void shouldNotReindexAsyncIndexInSyncMode() throws Exception{
        String indexPath = "/oak:index/rootIndex";
        CallbackCapturingProvider provider = new CallbackCapturingProvider();

        IndexUpdateProvider indexUpdate = new IndexUpdateProvider(provider);
        EditorHook hook = new EditorHook(indexUpdate);

        NodeState before = builder.getNodeState();
        NodeBuilder idx = createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "rootIndex", true, false, ImmutableSet.of("foo"), null);
        idx.setProperty("async", asList("async", "sync"), Type.STRINGS);

        builder.child("a").setProperty("foo", "abc");
        NodeState after = builder.getNodeState();

        NodeState indexed = hook.processCommit(before, after, CommitInfo.EMPTY);
        assertFalse(provider.getContext(indexPath).isReindexing());
    }

    @Test
    public void indexUpdateToleratesMalignCommitProgressCallback() throws Exception {
        final IndexUpdateCallback noop = new IndexUpdateCallback() {
            @Override
            public void indexUpdate() {
            }
        };

        NodeState before = builder.getNodeState();
        createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "rootIndex", true, false, ImmutableSet.of("foo"), null);
        NodeState after = builder.getNodeState();

        CallbackCapturingProvider provider = new CallbackCapturingProvider();
        IndexUpdate indexUpdate = new IndexUpdate(provider, null, after, builder,
                noop);
        indexUpdate.enter(before, after);

        ContextAwareCallback contextualCallback = (ContextAwareCallback) provider.callback;
        IndexingContext context = contextualCallback.getIndexingContext();

        context.registerIndexCommitCallback(new IndexCommitCallback() {
            @Override
            public void commitProgress(IndexProgress indexProgress) {
                throw new NullPointerException("Malign callback");
            }
        });

        indexUpdate.commitProgress(IndexCommitCallback.IndexProgress.COMMIT_SUCCEDED);
    }

    @Test
    public void commitProgressCallback() throws Exception {
        final IndexUpdateCallback noop = new IndexUpdateCallback() {
            @Override
            public void indexUpdate() {
            }
        };

        NodeState before = builder.getNodeState();
        createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "rootIndex", true, false, ImmutableSet.of("foo"), null);
        NodeState after = builder.getNodeState();

        CallbackCapturingProvider provider = new CallbackCapturingProvider();
        IndexUpdate indexUpdate = new IndexUpdate(provider, null, after, builder,
                noop);
        indexUpdate.enter(before, after);

        ContextAwareCallback contextualCallback = (ContextAwareCallback) provider.callback;
        IndexingContext context = contextualCallback.getIndexingContext();

        final AtomicInteger numCallbacks = new AtomicInteger();
        IndexCommitCallback callback1 = new IndexCommitCallback() {
            @Override
            public void commitProgress(IndexProgress indexProgress) {
                numCallbacks.incrementAndGet();
            }
        };
        IndexCommitCallback callback2 = new IndexCommitCallback() {
            @Override
            public void commitProgress(IndexProgress indexProgress) {
                numCallbacks.incrementAndGet();
            }
        };

        context.registerIndexCommitCallback(callback1);
        context.registerIndexCommitCallback(callback2);
        context.registerIndexCommitCallback(callback1);//intentionally adding same one twice

        for (IndexCommitCallback.IndexProgress progress : IndexCommitCallback.IndexProgress.values()) {
            numCallbacks.set(0);
            indexUpdate.commitProgress(IndexCommitCallback.IndexProgress.COMMIT_SUCCEDED);
            assertEquals("Either not all callbacks are called OR same callback got called twice for " + progress,
                    2, numCallbacks.get());
        }
    }

    @Test
    public void indexesDisabled() throws Exception{
        NodeState before = builder.getNodeState();
        createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "fooIndex", true, false, ImmutableSet.of("foo"), null);
        createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "barIndex", true, false, ImmutableSet.of("bar"), null);
        builder.child("testRoot").setProperty("foo", "abc");
        NodeState after = builder.getNodeState();

        NodeState indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);

        before = indexed;
        builder = indexed.builder();
        NodeBuilder newIndex = createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "newIndex", true, false, ImmutableSet.of("bar"), null);
        newIndex.setProperty(IndexConstants.SUPERSEDED_INDEX_PATHS, asList("/oak:index/fooIndex"), Type.STRINGS);

        after = builder.getNodeState();
        indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);

        //Post reindex also index should not be disabled
        assertEquals("property", indexed.getChildNode("oak:index").getChildNode("fooIndex").getString(TYPE_PROPERTY_NAME));
        assertTrue(indexed.getChildNode("oak:index").getChildNode("newIndex").getBoolean(IndexConstants.DISABLE_INDEXES_ON_NEXT_CYCLE));

        before = indexed;
        builder = indexed.builder();
        builder.child("testRoot2").setProperty("foo", "abc");
        after = builder.getNodeState();
        indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);

        //Index only disabled after next cycle
        assertEquals(IndexConstants.TYPE_DISABLED, indexed.getChildNode("oak:index").getChildNode("fooIndex").getString(TYPE_PROPERTY_NAME));
        assertFalse(indexed.getChildNode("oak:index").getChildNode("newIndex").getBoolean(IndexConstants.DISABLE_INDEXES_ON_NEXT_CYCLE));
    }

    @Test
    public void reindexForDisabledIndexes() throws Exception{
        EditorHook hook = new EditorHook(
                new IndexUpdateProvider(new CompositeIndexEditorProvider(
                        new PropertyIndexEditorProvider(),
                        new ReferenceEditorProvider()
                )));

        NodeState before = builder.getNodeState();
        createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                "fooIndex", true, false, ImmutableSet.of("foo"), null);
        builder.child("testRoot").setProperty("foo", "abc");
        NodeState after = builder.getNodeState();

        NodeState indexed = hook.processCommit(before, after, CommitInfo.EMPTY);

        before = indexed;
        builder = before.builder();
        builder.getChildNode("oak:index").getChildNode("fooIndex").setProperty(TYPE_PROPERTY_NAME, TYPE_DISABLED);
        builder.getChildNode("oak:index").getChildNode("fooIndex").setProperty(REINDEX_PROPERTY_NAME, true);
        after = builder.getNodeState();

        LogCustomizer customLogs = LogCustomizer.forLogger(IndexUpdate.class.getName()).filter(Level.INFO).create();
        customLogs.starting();

        before = after;
        builder = before.builder();
        builder.child("testRoot2").setProperty("foo", "abc");
        after = builder.getNodeState();
        indexed = hook.processCommit(before, after, CommitInfo.EMPTY);

        assertTrue(customLogs.getLogs().isEmpty());
        customLogs.finished();

    }

     /*
     Given 2 index defintions - one with a config error and another ok , the content under second should get indexed
     while the first with error gets ignored with an error message logged.
      */
     @Test
     public void testConfigErrorInIndexDefintion() throws Exception{
         LogCustomizer customLogs = LogCustomizer.forLogger(IndexUpdate.class.getName()).enable(Level.ERROR).create();
         builder.child("testRoot").setProperty("foo", "abc");
         //Create 2 index def - one with config related error and one without

         NodeBuilder index1 = createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                 "rootIndex1", true, false, ImmutableSet.of("foo"), null);

         index1.setProperty(PropertyStates.createProperty(
                 PathFilter.PROP_INCLUDED_PATHS, ImmutableSet.of("/test/a/b"), Type.STRINGS));
         index1.setProperty(PropertyStates.createProperty(
                 PathFilter.PROP_EXCLUDED_PATHS, ImmutableSet.of("/test/a"), Type.STRINGS));

         createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
                 "rootIndex2", true, false, ImmutableSet.of("foo2"), null);

         NodeState before = builder.getNodeState();

         // Add some content and process it through the property index hook (for index1)
         builder.child("test").child("a").setProperty("foo", "abc");
         builder.child("test").child("a").child("b").setProperty("foo", "abc");
         //Now for  for index2
         builder.child("test").child("b").setProperty("foo2","abc");
         builder.child("test").child("a").child("b").setProperty("foo2", "abc");

         NodeState after = builder.getNodeState();
         NodeState indexed;
         try{
             customLogs.starting();
             String expectedLogMessage = "Unable to get Index Editor for index at /oak:index/rootIndex1 . " +
                     "Please correct the index definition and reindex after correction. " +
                     "Additional Info : No valid include provided. Includes [/test/a/b], Excludes [/test/a]";
             indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);
             Assert.assertThat(customLogs.getLogs(), IsCollectionContaining.hasItems(expectedLogMessage));
         } finally {
             customLogs.finished();
         }

         // Now check that the index content nodes doesn't exists and the reindex flag is still set(Since it got skipped)
         NodeState ns = checkPathExists(indexed, INDEX_DEFINITIONS_NAME,
                 "rootIndex1");
         assertFalse(ns.getChildNode(INDEX_CONTENT_NODE_NAME).exists());
         PropertyState ps = ns.getProperty(REINDEX_PROPERTY_NAME);
         assertNotNull(ps);
         assertTrue(ps.getValue(Type.BOOLEAN));

         //Now check everything is fine with index2 - indexed data node exists and reindex flag is false
         NodeState ns2 = checkPathExists(indexed, INDEX_DEFINITIONS_NAME,
                 "rootIndex2");
         checkPathExists(ns2,INDEX_CONTENT_NODE_NAME);
         PropertyState ps2 = ns2.getProperty(REINDEX_PROPERTY_NAME);
         assertNotNull(ps2);
         assertFalse(ps2.getValue(Type.BOOLEAN));

         // next, lookup should work for the index def  2 which did not have any config errors
         PropertyIndexLookup lookup = new PropertyIndexLookup(indexed);
         assertEquals(ImmutableSet.of("test/b","test/a/b"), find(lookup, "foo2", "abc"));

    }

    private static void markCorrupt(NodeBuilder builder, String indexName) {
        builder.getChildNode(INDEX_DEFINITIONS_NAME).getChildNode(indexName)
                .setProperty(IndexConstants.CORRUPT_PROPERTY_NAME, ISO8601.format(Calendar.getInstance()));
    }

    private static NodeBuilder child(NodeBuilder nb, String path){
        for (String name : PathUtils.elements(checkNotNull(path))) {
            nb = nb.child(name);
        }
        return nb;
    }

}


text:
package edu.rpi.tw.data.rdf.sesame.string;

import java.util.Comparator;

import org.openrdf.model.Statement;

public class StatementComparator implements Comparator<Statement> {

   public int compare(Statement s1, Statement s2) {
      return s1.getPredicate().stringValue().compareTo(s2.getPredicate().stringValue());
   }

   public static Comparator<Statement> bySPO() {
      return new Comparator<Statement>() {
         public int compare(Statement s1, Statement s2) {
            int compVal = s1.getSubject().stringValue().compareTo(s2.getSubject().stringValue());
            if( compVal == 0 ) {
               compVal = s1.getPredicate().stringValue().compareTo(s2.getPredicate().stringValue());
               if( compVal == 0 ) {
                  compVal = s1.getObject().stringValue().compareTo(s2.getObject().stringValue());
               }
            }
            return compVal;
         }
      };
   }

   public static Comparator<Statement> byPredicate() {
      return new Comparator<Statement>() { public int compare(Statement s1, Statement s2) {
         return s1.getPredicate().stringValue().compareTo(s2.getPredicate().stringValue());}};
   }
}

redpajama_set_name: RedPajamaGithub


text: require 'validation_sets'


text:
This project was made to serve as a reuseable skeleton for web-application projects.

It comes with a lot of technology presets:

* Angular4 for frontend
* Python for backend
    * Note that the python backend not only serves as API, but also _serves_ the javascrip application bundle! No need to set up an NGINX just to serve files.
* Backend uses `asyncio` for all libraries, going as far as monkeypatching/subclassing existing libraries to become non-blocking
* Google account for authentication. The user just need to log in with their google account to be authenticated.
    * I usually rely heavily on google services anyways which requires user to grant permission to access drive/calendar etc.
    * Web tokens are obtained by frontend and forwarded to backend with all calls to the API. Tokens are verified in backend. No need to manage creation of session token etc.
* Google Datastore for database-as-a-service.
* GraphQL + Graphene + aiohttp for backend API. GraphQL especially has a slightly nasty learning curve, but I wanted something other than REST.
* All settings managed by environment variables and environment files.

## Setting up a project.

### Name your project
In this section I will use APPID in place of the name you choose for your project.
If I use "*" in a file name, it is because there may be several files that I want to refer to.

Clone the repository: `git clone https://github.com/emillynge/pyangular.git APPID`

Change the default project name in:
* `backend/.app.env`
* `frontend/environments*.ts`

### Make your own github repo
Make a new repository (I wouldn't recommend a fork, as you are not going to be pushing back to the skeleton project.) called _APPID_.
Rename the current remote  "origin" (pointing to emillynge/pyangular) to upstream, and add your own repo as the new origin.
```
git remote rename origin upstream
git remote add origin https://YOURACCOUNT/APPID.git
git fetch origin
```

next, rebase  or merge local master onto/into origin/master and push back to your own github repo.

If any improvements are made to the skeleton project at a later point in time, you will be able to fetch upstream/master and merge into your project.

### Google Credentials
Create a google project at  [https://console.developers.google.com/projectcreate]()

Set up a service account [https://console.developers.google.com/apis/credentials/serviceaccountkey]()
Set up a Oauth client ID [https://console.developers.google.com/apis/credentials/oauthclient]()

Download credentials for both, save service account creds as `backend/client_sercret.json` and Oauth creds at `backend/webapp_client_secret.json`.

If you choose other locations, change `backend/.test.env` accordingly.

The client_id from `webapp_client_secrets` also has to be pasted into the file `frontend/src/environments/environment.*.ts` like so:
```
# frontend/src/environments/environment.dev.ts
export const environment = {
  applicationName: "APPID"
  production: false,
  googleClientId: 'YOUR_CLIEND_ID',
};
```

**Remember to always check that any files containing secrets like these are gitignored when committing code.**

Enable Google Datatore API for your project.
### fetch
## Running app in development mode
When developing you app, you can run the command `make autobuild-dev` from the root of the project.
This will make sure to continually rebuild you angular app any time you make changes to the code. __You should not use this bundle
for production, since it is optimized for fast compilation, not fast execution.__

To serve the compiled code, execute the script `runmain.py`.


text:
namespace chromeos {

class ScreenLocker;
class WebUILoginDisplay;

namespace test {
class WebUIScreenLockerTester;
}

// This version of ScreenLockerDelegate displays a WebUI lock screen based on
// the Oobe account picker screen.
class WebUIScreenLocker : public WebUILoginView,
                          public LoginDisplay::Delegate,
                          public ScreenLockerDelegate,
                          public LockWindow::Observer {
 public:
  explicit WebUIScreenLocker(ScreenLocker* screen_locker);

  // ScreenLockerDelegate implementation:
  virtual void LockScreen(bool unlock_on_input) OVERRIDE;
  virtual void ScreenLockReady() OVERRIDE;
  virtual void OnAuthenticate() OVERRIDE;
  virtual void SetInputEnabled(bool enabled) OVERRIDE;
  virtual void ShowErrorMessage(
      int error_msg_id,
      HelpAppLauncher::HelpTopic help_topic_id) OVERRIDE;
  virtual void ClearErrors() OVERRIDE;
  virtual gfx::NativeWindow GetNativeWindow() const OVERRIDE;

  // LoginDisplay::Delegate: implementation
  virtual void CreateAccount() OVERRIDE;
  virtual string16 GetConnectedNetworkName() OVERRIDE;
  virtual void SetDisplayEmail(const std::string& email) OVERRIDE;
  virtual void CompleteLogin(const std::string& username,
                             const std::string& password) OVERRIDE;
  virtual void Login(const std::string& username,
                     const std::string& password) OVERRIDE;
  virtual void LoginAsDemoUser() OVERRIDE;
  virtual void LoginAsGuest() OVERRIDE;
  virtual void Signout() OVERRIDE;
  virtual void OnUserSelected(const std::string& username) OVERRIDE;
  virtual void OnStartEnterpriseEnrollment() OVERRIDE;

  // content::NotificationObserver (via WebUILoginView) implementation.
  virtual void Observe(int type,
                       const content::NotificationSource& source,
                       const content::NotificationDetails& details) OVERRIDE;

  // LockWindow::Observer implementation.
  virtual void OnLockWindowReady() OVERRIDE;

 private:
  friend class test::WebUIScreenLockerTester;

  virtual ~WebUIScreenLocker();

  // The screen locker window.
  views::Widget* lock_window_;

  // Login UI implementation instance.
  scoped_ptr<WebUILoginDisplay> login_display_;

  // Used for user image changed notifications.
  content::NotificationRegistrar registrar_;

  // Tracks when the lock window is displayed and ready.
  bool lock_ready_;

  // Tracks when the WebUI finishes loading.
  bool webui_ready_;

  // Time when lock was initiated, required for metrics.
  base::TimeTicks lock_time_;

  DISALLOW_COPY_AND_ASSIGN(WebUIScreenLocker);
};

}  // namespace chromeos

#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_WEBUI_SCREEN_LOCKER_H_


text:
import gradientVertexShader from "./shaders/gradient.vert";
import gradientFragmentShaders from "./shaders/gradient.frag";

Crafty.extend({
  defaultGradientShader(shader) {
    if (!shader) {
      if (this._defaultGradientShader === undefined) {
        this._defaultGradientShader = new Crafty.WebGLShader(
          gradientVertexShader,
          gradientFragmentShaders,
          [
            { name: "aPosition", width: 2 },
            { name: "aOrientation", width: 3 },
            { name: "aLayer", width: 2 },
            { name: "aColor", width: 4 }
          ],
          function() {}
        );
      }
      return this._defaultGradientShader;
    }
    return (this._defaultGradientShader = shader);
  }
});

Crafty.c("Gradient", {
  init() {
    // Declaring the vars here instead as class attributes
    // make them unique for each instance
    this._topColor = {
      _red: 0,
      _green: 0,
      _blue: 0,
      _strength: 1.0
    };
    this._bottomColor = {
      _red: 0,
      _green: 0,
      _blue: 0,
      _strength: 1.0
    };
    this.ready = true;

    this.bind("Draw", this._drawGradient);
    if (this.has("WebGL")) {
      this._establishShader("Gradient", Crafty.defaultGradientShader());
    }
    this.trigger("Invalidate");
  },

  remove() {
    this.unbind("Draw", this._drawGradient);
    if (this.has("DOM")) {
      this._element.style.backgroundColor = "transparent";
    }
    this.trigger("Invalidate");
  },

  _drawGradient(e) {
    if (e.type === "webgl") {
      e.program.writeVector(
        "aColor",
        this._topColor._red / 255,
        this._topColor._green / 255,
        this._topColor._blue / 255,
        this._topColor._strength,

        this._bottomColor._red / 255,
        this._bottomColor._green / 255,
        this._bottomColor._blue / 255,
        this._bottomColor._strength
      );
    }
  },

  topColor(color, strength) {
    if (color) {
      this._setColor(this._topColor, color, strength);
      return this;
    }
    return this._topColor;
  },

  bottomColor(color, strength) {
    if (color) {
      this._setColor(this._bottomColor, color, strength);
      return this;
    }
    return this._bottomColor;
  },

  _setColor(varColor, color, strength) {
    if (typeof color === "string") {
      Crafty.assignColor(color, varColor);
    } else {
      varColor._red = color[0];
      varColor._green = color[1];
      varColor._blue = color[2];
    }
    if (strength !== undefined) {
      varColor._strength = strength;
    }
    this.trigger("Invalidate");
  }
});


text:
TestApp::Application.routes.draw do

  match '/answers/fire_object_search' => 'answers#fire_object_search'
  match '/answers/fire_populate_drop_down' => 'answers#fire_populate_drop_down'

  chain_template_routes = lambda do
    scope "/:context(/:question_id)" do
      resources :answers, :only => [:new, :create, :index] do
        collection do
           post :fire_populate_drop_down
           post :fire_object_search
         end
      end
    end
    scope "/:context" do
      resources :answers, :only => [:edit, :update, :show] do
        collection do
           post :fire_populate_drop_down
           post :fire_object_search
         end
      end
    end
  end

  resources :containers do
    chain_template_routes.call
  end

  root :to => "home#index"
end


text:
import { createReducer } from '../utils';
import Immutable from 'immutable';
import _ from 'underscore';
import { dummyResume,
         blankBulletBlock,
         blankNoBulletBlock } from 'utils/dummyResume';

import { ADD_BLOCK,
         ADD_BULLET,
         CLIENT_IS_DIRTY_UPDATE,
         HIDE_BLOCK,
         HIDE_BULLET,
         MOVE_BLOCK,
         MOVE_BULLET,
         POPULATE_DATA_FROM_LINKEDIN,
         RESET_RESUME,
         SERVER_IS_SAVING_UPDATE,
         UPDATE_LOCAL_STATE,
         UPDATE_LOCAL_STATE_BLOCKS,
         UPDATE_LOCAL_STATE_BULLETS,
         UPDATE_LOCAL_STATE_FOOTER,
         UPDATE_LOCAL_STATE_HEADER,
         UPDATE_LOCAL_STATE_SAVEPRINT,
         UPDATE_RESUME_WITH_SERVER_RESPONSE,
         UPDATE_THESAURUS_RESULTS,
         WORD_SEARCH } from 'constants/resumeConstants';

// resumeState.resumeTitle is what the front end sees; req.body.resumeTitle is what the server sees.
const initialState = dummyResume;

export default createReducer(initialState, {

  [ADD_BLOCK]: (state, payload) => {
    const newState = { ...state };
    let newBlock;

    if (payload === 'bullets') {
      newBlock = blankBulletBlock();
    } else if (payload === 'no bullets') {
      newBlock = blankNoBulletBlock();
    }

    newState.blockChildren.push(newBlock);
    return newState;
  },

  [ADD_BULLET]: (state, payload) => {
    const newState = { ...state };
    const newBullet = {
      bulletId: Date.now(),
      archived: false,
      parentBlockId: payload,
      text: 'New Bullet'
    };
    const targetBlock = _.filter(newState.blockChildren, child => child.blockId === payload);
    targetBlock[0].bulletChildren.push(newBullet);
    return newState;
  },

  [CLIENT_IS_DIRTY_UPDATE]: (state, payload) => {
    const newState = Object.assign({}, state);
    newState.clientFormIsDirty = payload;
    return newState;
  },

  [HIDE_BLOCK]: (state, payload) => {
    const newState = { ...state };
    const targetBlock = _.filter(newState.blockChildren, child => child.blockId === payload);
    targetBlock[0].archived = true;
    return newState;
  },

  [HIDE_BULLET]: (state, payload) => {
    const newState = { ...state };
    const targetBullet = _.chain(newState.blockChildren)
                          .map(block => block.bulletChildren)
                          .flatten()
                          .filter(bullet => bullet.bulletId === payload)
                          .value();
    targetBullet[0].archived = true;
    return newState;
  },

  [MOVE_BLOCK]: (state, payload) => {
    const immutableBlockChildren = Immutable.List(state.blockChildren);

    return Object.assign({}, state, {
      blockChildren: immutableBlockChildren.splice(payload.blockIndex, 1).splice(payload.atIndex, 0, payload.block).toJS()
    });
  },

  [MOVE_BULLET]: (state, payload) => {
    const parentBlock = payload.blockChildren[payload.parentBlockIndex];
    const immutableBulletChildren = Immutable.List(parentBlock.bulletChildren);

    const newState = Object.assign({}, state);
    newState.blockChildren[payload.parentBlockIndex].bulletChildren = immutableBulletChildren.splice(payload.bulletIndex, 1).splice(payload.atIndex, 0, payload.bullet).toJS();
    return newState;
  },

  [POPULATE_DATA_FROM_LINKEDIN]: (state,payload) => {

    if(payload.positions._total){
      var _companyName  = payload.positions.values[0].company.name || '[company name]';
      var _jobTitle = payload.positions.values[0].company.title || '[job title]';
      var _text = payload.positions.values[0].summary ||  '[contribution to project]';
      var _startYear = payload.positions.values[0].startDate.year ||  '[enter start year]';
      if(payload.positions.values[0].isCurrent) {
        var _endYear = new Date().getFullYear()
      } else {
        var _endYear = payload.positions.values[0].endDate.year || '[enter end year]';
      }
    }else {
      var _companyName =  '[company name]';
      var _jobTitle = '[job title]';
      var _text = '[contribution to project]';
      var _startYear = '[enter start year]';
      var _endYear = '[enter end year]';
    }

    const newState = Object.assign({}, state);
    newState.resumeHeader = {
        name: (payload.firstName || 'Your') + ' ' + (payload.lastName || 'Full Name'),
        webLinkedin: payload.publicProfileUrl || 'LinkedIn.com/in/YourLinkedIn',
        displayEmail: payload.emailAddress || 'LinkedIn.com/in/YourLinkedIn',
        city: payload.location.name || 'Your City'
    };
    newState.blockChildren[2]= {
        blockId: 3,
        blockType: 'bullets',
        archived: false,
        companyName: _companyName,
        jobTitle: _jobTitle,
        bulletChildren: [{
            bulletId: 105,
            archived: false,
            parentBlockId: 3,
            text: _text
        }, {
            bulletId: 106,
            archived: false,
            parentBlockId: 3,
            text: '[contribution to project]'
        }],

        years: _endYear + '-' + _startYear,
        location: '[enter location]'
    };
    return newState;
  },

  [RESET_RESUME]: (state, payload) => {
    return Object.assign({}, state, dummyResume);
  },

  [SERVER_IS_SAVING_UPDATE]: (state, payload) => {
    const newState = Object.assign({}, state);
    newState.serverIsSaving = payload;
    return newState;
  },

  [UPDATE_LOCAL_STATE]: (state, payload) => {
    const newProperty = {};
    newProperty[payload.textFieldName] = payload.userInput;
    return Object.assign({}, state,
      newProperty);
  },

  [UPDATE_LOCAL_STATE_BLOCKS]: (state, payload) => {
    const newState = Object.assign({}, state);
    newState.blockChildren[payload.blockIndex][payload.textFieldName] = payload.userInput;
    return newState;
  },

  [UPDATE_LOCAL_STATE_BULLETS]: (state, payload) => {
    const newState = Object.assign({}, state);
    newState.blockChildren[payload.parentBlockIndex].bulletChildren[payload.bulletIndex][payload.textFieldName] = payload.userInput;
    return newState;
  },

  [UPDATE_LOCAL_STATE_FOOTER]: (state, payload) => {
    const newState = Object.assign({}, state);
    if (payload.textFieldName.slice(0, 6) === 'school') {
      newState.resumeFooter[payload.textFieldName.slice(0, 7)][payload.textFieldName.slice(8)] = payload.userInput;
    } else {
      newState.resumeFooter[payload.textFieldName] = payload.userInput;
    }
    return newState;
  },

  [UPDATE_LOCAL_STATE_HEADER]: (state, payload) => {
    const newState = Object.assign({}, state);
    newState.resumeHeader[payload.textFieldName] = payload.userInput;
    return newState;
  },

  [UPDATE_LOCAL_STATE_SAVEPRINT]: (state, payload) => {
    const newState = Object.assign({}, state);
    newState[payload.textFieldName] = payload.userInput;
    return newState;
  },

  [UPDATE_THESAURUS_RESULTS]: (state, payload) => {
    let thesaurusResults = {};

    if (payload.error !== undefined) {
      _.extend(thesaurusResults, payload);
    } else {
      _.each(payload, (type, key) => {
        if (type.syn !== undefined) {
          if (type.syn.length > 20) {
            type.syn = _.first(type.syn, 20);
          }
          thesaurusResults[key] = type.syn.join(', ');
        }
      });
    }

    return {
      ...state,
      thesaurusResults
    };
  },

  [UPDATE_RESUME_WITH_SERVER_RESPONSE]: (state, payload) => {
    return {
      ...state,
      ...payload
    };
  },

  [WORD_SEARCH]: (state, payload) => {
    const searchResults = _.chain(state.blockChildren)
                           .map(block => block.bulletChildren)
                           .flatten()
                           .filter(bullet => bullet.archived === false)
                           .map(bullet => bullet.text)
                           .map(snippet => snippet.toLowerCase().split(' '))
                           .flatten()
                           .filter(word => word.indexOf(payload) !== -1)
                           .value();
    return {
      ...state,
      wordCount: searchResults.length
    };
  }

});


text:
@implementation UITextField (Additions)
- (BOOL)resignFirstResponderAndMoveToNextFieldWithDoneBlock:(void(^)(void))block
{
    [self resignFirstResponder];
    UIView *_nextTextField = [self.superview viewWithTag:self.tag+1];
    if (_nextTextField)
        [_nextTextField becomeFirstResponder];
    else if (block)
        block();
    return YES;
}

- (void)updateLeftAccessoryImage:(UIImage*)image
{
    if ([self.leftView isKindOfClass:[UIImageView class]] == NO)
    {
        self.leftView = [[UIImageView alloc] initWithImage:image];
        self.leftView.contentMode = UIViewContentModeCenter;
        self.leftViewMode = UITextFieldViewModeAlways;
        self.leftView.width += 10;
    }
    else
        [(UIImageView*)self.leftView setImage:image];
}
@end


text:
<%if(title){%>

<%=title%>-<%=label%>

<%}%>
  <%for(var i in config){%>

<%=config[i].name%>

      <input class="default-status-input" placeholder="空" value="<%=status[i]%>">

  <%}%>
REFRESH
SET


text:
   <div ng-init="days = [
      {name:'Thursday', date:'21-11-2013', boxOffice: 0, admissions : [{name:'Paid Adm.', value: 0}, {name:'Compl. Adm.', value: 0}]},
      {name:'Friday', date:'22-11-2013', boxOffice: 0, admissions : [{name:'Paid Adm.', value: 0}, {name:'Compl. Adm.', value: 0}]},
      {name:'Saturday', date:'23-11-2013', boxOffice: 0, admissions : [{name:'Paid Adm.', value: 0}, {name:'Compl. Adm.', value: 0}]},
      {name:'Sunday', date:'24-11-2013', boxOffice: 0, admissions : [{name:'Paid Adm.', value: 0}, {name:'Compl. Adm.', value: 0}]},
      {name:'Monday', date:'25-11-2013', boxOffice: 0, admissions : [{name:'Paid Adm.', value: 0}, {name:'Compl. Adm.', value: 0}]},
      {name:'Tuesday', date:'26-11-2013', boxOffice: 0, admissions : [{name:'Paid Adm.', value: 0}, {name:'Compl. Adm.', value: 0}]},
      {name:'Wednesday', date:'27-11-2013', boxOffice: 0, admissions : [{name:'Paid Adm.', value: 0}, {name:'Compl. Adm.', value: 0}]}
    ]">

    <form class="css-form">

          Box Office

             {{admission.name}}

          Total Adm.

          {{day.name}}
          {{day.date}}
          <input type="text" ng-model="day.boxOffice" amount select-on-click/>

             <input type="text" style="padding:0;" ng-model="admission.value" integer select-on-click/>

          {{day.admissions | total:'value'}}

          Total:
          {{days | total:'boxOffice'}}

             {{days | total:'admissions.value':$index}}

     </form>


text:
#ifndef _INC_BIN_SUPPORT_
#define _INC_BIN_SUPPORT_

/*
 * get the version number from the cmake build file
 */
#include "buildConfig.h"

/**
 * @file bin_support.h
 * \brief contains the fns needed for the estimator and emulator binaries,
 * shouldn't contain anything vital for the actual statistical code
 */

void print_usage_estimator(void);
void print_usage_emulator(void);

/**
 * read the args from the cmdline input, setup sensible defaults from defaults.h
 * and then try and overwrite all the ones we can. This needs some serious improvement
 */
void parse_arguments(int argc, char** argv, optstruct* options);

/**
 * sets the covariance_fn pointer in the optstruct, this is used deep in libEmu
 */
void setup_cov_fn(optstruct *options);
/**
 * fills in the grad_ranges struct in the optstruct, vital for the estimator
 */
void setup_optimization_ranges(optstruct* options, modelstruct* model);

#endif


text:
<?php

namespace CommerceGuys\Enum\Tests;

/**
 * @coversDefaultClass \CommerceGuys\Enum\AbstractEnum
 */
class AbstractEnumTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @covers ::getAll
     */
    public function testGetAll()
    {
        $expectedValues = ['FIRST' => 'first', 'SECOND' => 'second'];
        $values = DummyEnum::getAll();
        $this->assertEquals($expectedValues, $values);
    }

    /**
     * @covers ::getKey
     * @uses \CommerceGuys\Enum\AbstractEnum::getAll
     */
    public function testGetKey()
    {
        $key = DummyEnum::getKey('first');
        $this->assertEquals('FIRST', $key);

        $key = DummyEnum::getKey('invalid');
        $this->assertEquals(false, $key);
    }

    /**
     * @covers ::exists
     * @uses \CommerceGuys\Enum\AbstractEnum::getAll
     */
    public function testExists()
    {
        $result = DummyEnum::exists('second');
        $this->assertEquals(true, $result);

        $result = DummyEnum::exists('invalid');
        $this->assertEquals(false, $result);
    }

    /**
     * @covers ::assertExists
     * @uses \CommerceGuys\Enum\AbstractEnum::getAll
     * @uses \CommerceGuys\Enum\AbstractEnum::exists
     * @expectedException \InvalidArgumentException
     * @expectedExceptionMessage "invalid" is not a valid DummyEnum value.
     */
    public function testAssertExists()
    {
        $result = DummyEnum::assertExists('invalid');
    }

    /**
     * @covers ::assertAllExist
     * @uses \CommerceGuys\Enum\AbstractEnum::getAll
     * @uses \CommerceGuys\Enum\AbstractEnum::exists
     * @uses \CommerceGuys\Enum\AbstractEnum::assertExists
     * @expectedException \InvalidArgumentException
     * @expectedExceptionMessage "invalid" is not a valid DummyEnum value.
     */
    public function testAssertAllExist()
    {
        $result = DummyEnum::assertAllExist(['second', 'invalid']);
    }

}


text:
"""
Django settings for phoenix project.

Generated by 'django-admin startproject' using Django 1.8.

For more information on this file, see
https://docs.djangoproject.com/en/1.8/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.8/ref/settings/
"""

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
import json
import dj_database_url

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/

ALLOWED_HOSTS = ['*']

# Application definition

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # third pary apps
    'crispy_forms',
    'storages',
    'django_cleanup',
    'djcelery_email',
    'rest_framework',
    'rest_framework.authtoken',
    'captcha',
    'guardian',
    # allauth
    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    'allauth.socialaccount.providers.facebook',
    #'allauth.socialaccount.providers.google',
    'allauth.socialaccount.providers.twitter',
    'allauth.socialaccount.providers.github',
    # my apps
    'content',
    'mytwitter',
    'agenda',
    'vault',
    'whiteboard',
    'boothcrawl'
)

SITE_ID = 1

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
)

# Authentication backends Setting
AUTHENTICATION_BACKENDS = (
    # Needed to login by username in Django admin, regardless of `allauth`
    'django.contrib.auth.backends.ModelBackend',
    # `allauth` specific authentication methods, such as login by e-mail
    'allauth.account.auth_backends.AuthenticationBackend',
    'guardian.backends.ObjectPermissionBackend',
)

ROOT_URLCONF = 'phoenix.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, "templates")],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',

                # `allauth` needs this from django
                'django.template.context_processors.request',
            ],
        },
    },
]

WSGI_APPLICATION = 'phoenix.wsgi.application'
if "VCAP_SERVICES" in os.environ:
    #conn_max_age will keep connection open, which is good but bad for Dev databases with limited allowed connections
    #DATABASES = {'default': dj_database_url.config(conn_max_age=600)}
    DATABASES = {'default': dj_database_url.config()}
else:
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': 'db.sqlite.db',
        }
    }

# Internationalization
# https://docs.djangoproject.com/en/1.8/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'Europe/Berlin'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.8/howto/static-files/

# disable cache by default and only enable later with either memcached or redis in VCAP_SERVICES
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
    }
}

# default URL, will be overwritten by django-storages
STATIC_URL = "/static/"
MEDIA_URL = "/media/"

# Load VCAP_SERVICES
if "VCAP_SERVICES" in os.environ:
    VCAP_SERVICES = json.loads(os.environ['VCAP_SERVICES'])
    for group in VCAP_SERVICES:
        for service in VCAP_SERVICES[group]:
            if "ecs" in service['name']:
                AWS_S3_ENDPOINT_URL = service['credentials']['AWS_S3_ENDPOINT_URL']
                AWS_ACCESS_KEY_ID = service['credentials']['ACCESS_KEY_ID']
                AWS_SECRET_ACCESS_KEY = service['credentials']['SECRET_ACCESS_KEY']
                STATIC_BUCKET_NAME = service['credentials']['STATIC_BUCKET']
                MEDIA_BUCKET_NAME = service['credentials']['MEDIA_BUCKET']
                SECURE_BUCKET_NAME = service['credentials']['SECURE_BUCKET']
                SECURE_BUCKET_EXPIRE = 1800 #seconds has to be larger than the highest cache value

                # add S3 compatible storge
                STATICFILES_STORAGE = 'phoenix.custom_storages.StaticStorage'
                DEFAULT_FILE_STORAGE = 'phoenix.custom_storages.MediaStorage'
                SECURE_FILE_STORAGE = 'phoenix.custom_storages.SecureStorage'

                # django-storages settings
                AWS_AUTO_CREATE_BUCKET = True
                AWS_S3_SECURE_URLS = False
                AWS_QUERYSTRING_AUTH = False

            elif "mail" in service['name']:
                EMAIL_HOST = service['credentials']['HOST']
                EMAIL_HOST_USER = service['credentials']['USER']
                EMAIL_HOST_PASSWORD = service['credentials']['PASSWORD']
                EMAIL_PORT = int(service['credentials']['PORT'])
                if service['credentials']['TLS'] == 'True':
                    EMAIL_USE_TLS = True
                else:
                    EMAIL_USE_TLS = False
            # sendgrid does override "mail" and will use sendgrid web API
            elif "sendgrid" in service['name']:
                CELERY_EMAIL_BACKEND = "sgbackend.SendGridBackend"
                #SENDGRID_USER = service['credentials']['username']
                #SENDGRID_PASSWORD = service['credentials']['password']

            elif "rabbitmq" in service['name']:
                BROKER_URL = service['credentials']['uri']
                EMAIL_BACKEND = 'djcelery_email.backends.CeleryEmailBackend'

                CELERY_EMAIL_TASK_CONFIG = {
                    'rate_limit': '100/m',  # * CELERY_EMAIL_CHUNK_SIZE (default: 10) limit to X per minute
                }

                if "cloudamqp" in VCAP_SERVICES[group]:
                    # https://www.cloudamqp.com/docs/celery.html
                    BROKER_POOL_LIMIT = 1 # Will decrease connection usage
                    BROKER_HEARTBEAT = 30 # Will detect stale connections faster
                    BROKER_CONNECTION_TIMEOUT = 30 # May require a long timeout due to Linux DNS timeouts etc
                    CELERY_RESULT_BACKEND = None
                    CELERY_SEND_EVENTS = False # Will not create celeryev.* queues
                    CELERY_EVENT_QUEUE_EXPIRES = 60 # Will delete all celeryev. queues without consumers after 1 minute.

            elif "twitter" in service['name']:
                TWITTER_CONSUMER_KEY = service['credentials']['CONSUMER_KEY']
                TWITTER_CONSUMER_SECRET = service['credentials']['CONSUMER_SECRET']
                TWITTER_ACCESS_TOKEN = service['credentials']['ACCESS_TOKEN']
                TWITTER_ACCESS_TOKEN_SECRET = service['credentials']['ACCESS_TOKEN_SECRET']

            elif "config" in service['name']:
                SECRET_KEY = service['credentials']['SECRET_KEY']
                if service['credentials']['DEBUG'] == 'True':
                    DEBUG = True
                else:
                    DEBUG = False
                if service['credentials']['SECURE_SSL_REDIRECT'] == 'True':
                    SECURE_SSL_REDIRECT = True
                    SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
                else:
                    SECURE_SSL_REDIRECT = False
                DEFAULT_FROM_EMAIL = service['credentials']['DEFAULT_FROM_EMAIL']
                DEFAULT_TO_EMAIL = service['credentials']['DEFAULT_TO_EMAIL']
                SERVER_EMAIL = service['credentials']['SERVER_EMAIL']
                SENDGRID_API_KEY = service['credentials']['SENDGRID_API_KEY']
                import ast
                ADMINS = ast.literal_eval(service['credentials']['ADMINS'])

            elif "memcach" in service['name']:
                SESSION_ENGINE = "django.contrib.sessions.backends.cache"
                SESSION_CACHE_ALIAS = "default"
                if "credentials" in service:
                    CACHES = {
                             'default': {
                                'BACKEND': 'django_pylibmc.memcached.PyLibMCCache',
                                'BINARY': True,
                                'LOCATION': service['credentials']['servers'].replace(',', ';'),
                                'USERNAME': service['credentials']['username'],
                                'PASSWORD': service['credentials']['password'],
                                'OPTIONS': {
                                    'ketama': True,
                                    'tcp_nodelay': True,
                                }
                             }
                    }
                else:
                    CACHES = {
                             'default': {
                                'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
                             }
                    }
            elif "redis" in service['name']:
                SESSION_ENGINE = "django.contrib.sessions.backends.cache"
                SESSION_CACHE_ALIAS = "default"
                if service['credentials']['password']:
                    redis_location = "redis://" + service['credentials']['password'] + '@' + service['credentials']['hostname'] + ':' + service['credentials']['port'] + '/0'
                else:
                    redis_location = "redis://" + service['credentials']['hostname'] + ':' + service['credentials']['port'] + '/0'

                CACHES = {
                    "default": {
                        "BACKEND": "django_redis.cache.RedisCache",
                        "LOCATION": redis_location,
                        "OPTIONS": {
                            "CLIENT_CLASS": "django_redis.client.DefaultClient",
                        }
                    }
                }

else:
    # for development, don't run migrations!
    print("No VCAP_SERVICES loaded!")
    DEBUG = True
    SECRET_KEY = "DEVELOPMENT"
    STATIC_ROOT = os.path.join(BASE_DIR, 'static')
    MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
    SECURE_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'
    # custom_storages.py is referenced in migrations
    STATIC_BUCKET_NAME = None
    STATIC_CUSTOM_DOMAIN = None
    MEDIA_BUCKET_NAME = None
    MEDIA_CUSTOM_DOMAIN = None
    SECURE_BUCKET_NAME = None
    SECURE_BUCKET_EXPIRE = 1800 #seconds has to be larger than the highest cache value

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static_custom'),
)

# crispy
CRISPY_TEMPLATE_PACK = 'bootstrap3'
CRISPY_FAIL_SILENTLY = not DEBUG

# REST
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAdminUser',),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
    ),
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
    'PAGE_SIZE': 25
}

#captcha
CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.random_char_challenge'

# allauth
ACCOUNT_ADAPTER = "phoenix.adapter.AccountAdapter"
ACCOUNT_AUTHENTICATION_METHOD = 'username_email' #username_email
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_EMAIL_VERIFICATION = 'mandatory'
ACCOUNT_SIGNUP_FORM_CLASS = 'phoenix.forms.SignupForm'
ACCOUNT_SIGNUP_PASSWORD_VERIFICATION = False
ACCOUNT_USERNAME_MIN_LENGTH = 6
ACCOUNT_PASSWORD_MIN_LENGTH = 8
ACCOUNT_USERNAME_REQUIRED = True
ACCOUNT_EMAIL_REQUIRED = True
SOCIALACCOUNT_AUTO_SIGNUP = False
#ACCOUNT_PRESERVE_USERNAME_CASING = False
#SOCIALACCOUNT_QUERY_EMAIL = False
SOCIALACCOUNT_PROVIDERS = \
    {
    'github':
        {   'SCOPE': ['user:email'],
            'VERIFIED_EMAIL': True,
        },
    'facebook':
        {#'METHOD': 'js_sdk',
            'SCOPE': ['email', 'public_profile'],
            'VERIFIED_EMAIL': True,
        },
    }
LOGIN_REDIRECT_URL = '/'

#: Only add pickle to this list if your broker is secured
#: from unwanted access (see userguide/security.html)
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
#1h task limit
CELERYD_TASK_TIME_LIMIT = 3600

# django-resized
DJANGORESIZED_DEFAULT_SIZE = [1024, 1024]
DJANGORESIZED_DEFAULT_QUALITY = 75
DJANGORESIZED_DEFAULT_KEEP_META = True

# restrict access to certain domains
ALLOWED_DOMAINS = ['dell.com','emc.com', 'vmware.com', 'vce.com', 'rsa.com', 'virtustream.com', 'pivotal.io']


text:
title: Tab Vs Shape
page_title: TabVsShape- Telerik Presentation Framework
description: This article shows how you can create and use the supported shapes.
slug: winforms-telerik-presentation-framework-tab-vs-shape
tags: tab-shape
published: True
position: 1
---

# TabVsShape

The following image shows the __TabVsShape__ applied to a RadPanel:

![tab-vs-shape001](images/tab-vs-shape001.png)

The following code shows how you can create and apply a __TabVsShape__:

{{source=..\SamplesCS\TPF\Shapes\ShapesCode.cs region=TabVsShape}}
{{source=..\SamplesVB\TPF\Shapes\ShapesCode.vb region=TabVsShape}}
````C#
TabVsShape tabVsShape = new TabVsShape();
radPanel1.BackColor = Color.ForestGreen;
this.radPanel1.RootElement.Shape = tabVsShape;
this.radPanel1.RootElement.ApplyShapeToControl = true;

````
````VB.NET
Dim tabVsShape As TabVsShape = New TabVsShape()
radPanel1.BackColor = Color.ForestGreen
Me.radPanel1.RootElement.Shape = tabVsShape
Me.radPanel1.RootElement.ApplyShapeToControl = True

````

{{endregion}}

### Properties

* __RightToLeft__: A property of type __bool__ that gets or sets the orientation of this shape.
* __CloseFigure__: A property of type __bool__ that apply the close figure.

# See Also
* [Custom Shapes]({%slug winforms/telerik-presentation-framework/diamond-shape%})

* [Diamond Shape]({%slug winforms/telerik-presentation-framework/diamond-shape%})

* [Donut Shape]({%slug winforms/telerik-presentation-framework/donut-shape%})

* [Ellipse Shape]({%slug winforms/telerik-presentation-framework/ellipse-shape%})

* [Heart Shape]({%slug winforms/telerik-presentation-framework/heart-shape%})

* [Media Shape]({%slug winforms/telerik-presentation-framework/media-shape%})

* [Overview]({%slug winforms/telerik-presentation-framework/shapes%})

* [RoundRect Shape]({%slug winforms/telerik-presentation-framework/roundrect-shape%})


text:
def get_material_by_name(name, materials):
    '''
        :param str name: name of the wanted material
        :returns: a material with strName as name or non if not found
        :rtype: Material  or None if not found
    '''
    for m in materials:
        if m.name == name:
            return m
    return None

class Material:
    ''' it's a material
    '''

    def __init__(self, name, ambient_color, diffuse_color,
                 specular_color, phong_specular_exponent,
                 reflection_color):
        self.name = name
        self.ambient_color = ambient_color
        self.diffuse_color = diffuse_color
        self.specular_color = specular_color
        self.phong_specular_exponent = phong_specular_exponent
        self.reflection_color = reflection_color


text:
import type { Looker31SDK, Looker40SDK } from '@looker/sdk'
import {
  registerCore31SDK,
  getCore31SDK,
  unregisterCore31SDK,
} from './core_sdk_31'
import {
  registerCore40SDK,
  getCore40SDK,
  unregisterCore40SDK,
} from './core_sdk_40'
import { registerCoreSDK2, getCoreSDK2, unregisterCoreSDK2 } from './core_sdk2'
import { getCoreSDK } from './core_sdk'

describe('coreSDK', () => {
  beforeEach(() => {
    unregisterCore31SDK()
    unregisterCore40SDK()
  })

  it('errors when not initialized', () => {
    try {
      getCore31SDK()
      fail()
    } catch (err) {
      // success - getCoreSDK should fail if not registered
    }
  })

  it('returns sdk', () => {
    const fakeSdk = jest.fn() as unknown
    try {
      registerCore31SDK(fakeSdk as Looker31SDK)
      expect(getCore31SDK()).toStrictEqual(fakeSdk)
      expect(getCoreSDK()).toStrictEqual(fakeSdk)
    } catch (err) {
      fail(err)
    }
  })

  it('does not allow multiple registrations', () => {
    const fakeSdk = jest.fn() as unknown
    try {
      registerCore31SDK(fakeSdk as Looker31SDK)
      expect(getCore31SDK()).toStrictEqual(fakeSdk)
      registerCore31SDK(fakeSdk as Looker31SDK)
      fail()
    } catch (err) {
      // success - register should fail if called multiple times
    }
  })

  it('unregisters', () => {
    const fakeSdk = jest.fn() as unknown
    try {
      registerCore31SDK(fakeSdk as Looker31SDK)
      expect(getCore31SDK()).toStrictEqual(fakeSdk)
      unregisterCore31SDK()
      getCore31SDK()
      fail()
    } catch (err) {
      // success - getCoreSDK should fail unregister
    }
  })

  it('errors when not initialized', () => {
    try {
      getCore40SDK()
      fail()
    } catch (err) {
      // success - getCoreSDK should fail if not registered
    }
  })

  it('returns sdk', () => {
    const fakeSdk = jest.fn() as unknown
    const fake31Sdk = jest.fn() as unknown
    try {
      registerCore31SDK(fake31Sdk as Looker31SDK)
      registerCore40SDK(fakeSdk as Looker40SDK)
      expect(getCore40SDK()).toStrictEqual(fakeSdk)
      expect(getCoreSDK()).toStrictEqual(fake31Sdk)
    } catch (err) {
      fail(err)
    }
  })

  it('does not allow multiple registrations', () => {
    const fakeSdk = jest.fn() as unknown
    try {
      registerCore40SDK(fakeSdk as Looker40SDK)
      expect(getCore40SDK()).toStrictEqual(fakeSdk)
      registerCore40SDK(fakeSdk as Looker40SDK)
      fail()
    } catch (err) {
      // success - register should fail if called multiple times
    }
  })

  it('unregisters', () => {
    const fakeSdk = jest.fn() as unknown
    try {
      registerCore40SDK(fakeSdk as Looker40SDK)
      expect(getCore40SDK()).toStrictEqual(fakeSdk)
      unregisterCore40SDK()
      getCore40SDK()
      fail()
    } catch (err) {
      // success - getCoreSDK should fail unregister
    }
  })

  it('SDK2 does not allow multiple registrations', () => {
    const fakeSdk = jest.fn() as unknown
    try {
      registerCoreSDK2(fakeSdk)
      expect(getCoreSDK2()).toStrictEqual(fakeSdk)
      registerCoreSDK2(fakeSdk)
      fail()
    } catch (err) {
      // success - register should fail if called multiple times
    }
  })

  it('SDK2 unregisters', () => {
    const fakeSdk = jest.fn() as unknown
    try {
      registerCoreSDK2(fakeSdk)
      expect(getCoreSDK2()).toStrictEqual(fakeSdk)
      unregisterCoreSDK2()
      getCoreSDK2()
      fail()
    } catch (err) {
      // success - getCoreSDK2 should fail unregister
    }
  })
})


text:
void collectorMenu(VoteProcessor* vp)
{
	cout << "\n1.Results in percent\n2.Results in numbers\n3.Results based on Age\n4.Results based on name\n5.Results based on Ethnos\n6.Results based on Living city/village\n" << endl;
	int choice;
	cin >> choice;

	while (choice != 0)
	{
		string input;
		switch (choice)
		{
		case 1:vp->printResult(vp->filterVotes(FilterItem::all, ""), PrintType::percentPrint); break;
		case 2:vp->printResult(vp->filterVotes(FilterItem::all, ""), PrintType::numbersPrint); break;
		case 3:cout << "Enter age:";
			cin >> input;
			vp->getVotes(input, FilterItem::age, PrintType::numbersPrint);
			break;
		case 4: cout << "Enter name:";
			cin >> input;
			vp->getVotes(input, FilterItem::name, PrintType::numbersPrint);
			break;
		case 5: cout << "Enter ethnos:";
			cin >> input;
			vp->getVotes(input, FilterItem::ethnos, PrintType::numbersPrint);
			break;
		case 6: cout << "Enter city:";
			cin >> input;
			vp->getVotes(input, FilterItem::city, PrintType::numbersPrint);
			break;
		default: cout << "Sorry, no such operation"; break;
		}

		cout << "\nChoose another operation or enter 0" << endl;
		cin >> choice;
	}
}

int main()
{
	Voter* v1 = new Voter("Pesho", 25, Gender::Male, "English", "London", true);
	Voter* v2 = new Voter("Jane", 36, Gender::Female, "Irish", "London", false);
	Voter* v3 = new Voter("John", 25, Gender::Male, "Irish", "Manchester", false);
	VoteProcessor vp = VoteProcessor();
	vp.addVote(v1);
	vp.addVote(v2);
	vp.addVote(v3);
	Voter* newVoter = new Voter();

	cout << "1.Vote or\nEnter password" << endl;
	int choice;
	cin >> choice;
	switch (choice)
	{
	case 12344321: collectorMenu(&vp); break;
	case 1: newVoter = &Voter::getInput();
		vp.addVote(newVoter);
		cout << "Your vote is recorded!" << endl; break;
	default:cout << "Wrong choice" << endl; break;
	}

	return 0;
}


text:
/**
 * Client program requesting current date from server.
 *
 * Figure 3.22
 *
 * @author Silberschatz, Gagne and Galvin
 * Operating System Concepts  - Eighth Edition
 */

import java.net.*;
import java.io.*;

public class DateClient
{
	public static void main(String[] args)  {
		try {
			// this could be changed to an IP name or address other than the localhost
			Socket sock = new Socket("127.0.0.1",6013);
			InputStream in = sock.getInputStream();
			BufferedReader bin = new BufferedReader(new InputStreamReader(in));

			String line;
			while( (line = bin.readLine()) != null)
				System.out.println(line);

			sock.close();
		}
		catch (IOException ioe) {
				System.err.println(ioe);
		}
	}
}


text:
package org.thinkinghub.gateway.oauth.service;

import com.github.scribejava.core.builder.ServiceBuilder;
import com.github.scribejava.core.model.Response;
import com.github.scribejava.core.oauth.OAuth20Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thinkinghub.gateway.api.LinkedInApi;
import org.thinkinghub.gateway.oauth.config.LinkedInConfig;
import org.thinkinghub.gateway.oauth.entity.ServiceType;
import org.thinkinghub.gateway.oauth.exception.UserCancelOAuthException;
import org.thinkinghub.gateway.oauth.registry.ExtractorRegistry;
import org.thinkinghub.gateway.oauth.response.ErrorResponse;
import org.thinkinghub.gateway.oauth.response.GatewayResponse;

import javax.annotation.PostConstruct;

@Service
@Slf4j
public class LinkedInService extends AbstractOAuthService {
    @Autowired
    private LinkedInConfig linkedInConfig;

    @PostConstruct
    public void initialize() {
        log.info(linkedInConfig.toString());
    }

    @Override
    protected OAuth20Service getOAuthServiceProvider(String state) {
        OAuth20Service service = new ServiceBuilder().apiKey(linkedInConfig.getApiKey())
                .apiSecret(linkedInConfig.getApiSecret()).callback(linkedInConfig.getCallback())
                .state(state).scope(linkedInConfig.getScope()).build(LinkedInApi.instance());
        return service;
    }

    @Override
    protected String getUserInfoUrl() {
        return "https://api.linkedin.com/v1/people/~?format=json";
    }

    @Override
    protected GatewayResponse parseUserInfoResponse(Response response) {
        return ExtractorRegistry.getExtractor(ServiceType.LINKEDIN).extract(response);
    }

    @Override
    public ServiceType supportedOAuthType() {
        return ServiceType.LINKEDIN;
    }

    public void handleOAuthError(ErrorResponse er, String state){
        if(er.getOauthErrorCode().equals("user_cancelled_login")
                || er.getOauthErrorCode().equals("user_cancelled_authorize ")){
            throw new UserCancelOAuthException(er.getOauthErrorCode(), er.getOauthErrorMessage());
        }
        super.handleOAuthError(er, state);
    }
}