All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gerrit.server.rules.PrologEnvironment Maven / Gradle / Ivy

There is a newer version: 3.11.0-rc3
Show newest version
// Copyright (C) 2011 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.gerrit.server.rules;

import com.google.common.flogger.FluentLogger;
import com.google.gerrit.server.AnonymousUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.account.Emails;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.PluginConfigFactory;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.patch.DiffOperations;
import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.project.ProjectCache;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.google.inject.assistedinject.Assisted;
import com.googlecode.prolog_cafe.lang.BufferingPrologControl;
import com.googlecode.prolog_cafe.lang.Predicate;
import com.googlecode.prolog_cafe.lang.PredicateEncoder;
import com.googlecode.prolog_cafe.lang.Prolog;
import com.googlecode.prolog_cafe.lang.PrologMachineCopy;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.eclipse.jgit.lib.Config;

/**
 * Per-thread Prolog interpreter.
 *
 * 

This class is not thread safe. * *

A single copy of the Prolog interpreter, for the current thread. */ public class PrologEnvironment extends BufferingPrologControl { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); public interface Factory { /** * Construct a new Prolog interpreter. * * @param src the machine to template the new environment from. * @return the new interpreter. */ PrologEnvironment create(PrologMachineCopy src); } private final Args args; private final Map, Object> storedValues; private List cleanup; @Inject PrologEnvironment(Args a, @Assisted PrologMachineCopy src) { super(src); setEnabled(EnumSet.allOf(Prolog.Feature.class), false); args = a; storedValues = new HashMap<>(); cleanup = new LinkedList<>(); } public Args getArgs() { return args; } @Override public void setPredicate(Predicate goal) { super.setPredicate(goal); int reductionLimit = args.reductionLimit(goal); setReductionLimit(reductionLimit); } /** * Lookup a stored value in the interpreter's hash manager. * * @param type of stored Java object. * @param sv unique key. * @return the value; null if not stored. */ @SuppressWarnings("unchecked") public T get(StoredValue sv) { return (T) storedValues.get(sv); } /** * Set a stored value on the interpreter's hash manager. * * @param type of stored Java object. * @param sv unique key. * @param obj the value to store under {@code sv}. */ @SuppressWarnings("unchecked") public void set(StoredValue sv, T obj) { storedValues.put((StoredValue) sv, obj); } /** * Copy the stored values from another interpreter to this one. Also gets the cleanup from the * child interpreter */ public void copyStoredValues(PrologEnvironment child) { storedValues.putAll(child.storedValues); setCleanup(child.cleanup); } /** * Assign the environment a cleanup list (in order to use a centralized list) If this * enivronment's list is non-empty, append its cleanup tasks to the assigning list. */ public void setCleanup(List newCleanupList) { newCleanupList.addAll(cleanup); cleanup = newCleanupList; } /** * Adds cleanup task to run when close() is called * * @param task is run when close() is called */ public void addToCleanup(Runnable task) { cleanup.add(task); } /** Release resources stored in interpreter's hash manager. */ public void close() { for (Iterator i = cleanup.iterator(); i.hasNext(); ) { try { i.next().run(); } catch (Exception err) { logger.atSevere().withCause(err).log("Failed to execute cleanup for PrologEnvironment"); } i.remove(); } } @Singleton public static class Args { private static final Class CONSULT_STREAM_2; static { try { @SuppressWarnings("unchecked") Class c = (Class) Class.forName( PredicateEncoder.encode(Prolog.BUILTIN, "consult_stream", 2), false, RulesCache.class.getClassLoader()); CONSULT_STREAM_2 = c; } catch (ClassNotFoundException e) { throw new LinkageError("cannot find predicate consult_stream", e); } } private final ProjectCache projectCache; private final PermissionBackend permissionBackend; private final GitRepositoryManager repositoryManager; private final PluginConfigFactory pluginConfigFactory; private final DiffOperations diffOperations; private final PatchSetInfoFactory patchSetInfoFactory; private final IdentifiedUser.GenericFactory userFactory; private final Provider anonymousUser; private final int reductionLimit; private final int compileLimit; private final PatchSetUtil patchsetUtil; private Emails emails; @Inject Args( ProjectCache projectCache, PermissionBackend permissionBackend, GitRepositoryManager repositoryManager, PluginConfigFactory pluginConfigFactory, DiffOperations diffOperations, PatchSetInfoFactory patchSetInfoFactory, IdentifiedUser.GenericFactory userFactory, Provider anonymousUser, @GerritServerConfig Config config, PatchSetUtil patchsetUtil, Emails emails) { this.projectCache = projectCache; this.permissionBackend = permissionBackend; this.repositoryManager = repositoryManager; this.pluginConfigFactory = pluginConfigFactory; this.diffOperations = diffOperations; this.patchSetInfoFactory = patchSetInfoFactory; this.userFactory = userFactory; this.anonymousUser = anonymousUser; this.patchsetUtil = patchsetUtil; this.emails = emails; this.reductionLimit = RuleUtil.reductionLimit(config); this.compileLimit = RuleUtil.compileReductionLimit(config); logger.atInfo().log("reductionLimit: %d, compileLimit: %d", reductionLimit, compileLimit); } private int reductionLimit(Predicate goal) { if (goal.getClass() == CONSULT_STREAM_2) { logger.atFine().log( "predicate class is CONSULT_STREAM_2: override reductionLimit with compileLimit (%d)", compileLimit); return compileLimit; } return reductionLimit; } public ProjectCache getProjectCache() { return projectCache; } public PermissionBackend getPermissionBackend() { return permissionBackend; } public GitRepositoryManager getGitRepositoryManager() { return repositoryManager; } public PluginConfigFactory getPluginConfigFactory() { return pluginConfigFactory; } public DiffOperations getDiffOperations() { return diffOperations; } public PatchSetInfoFactory getPatchSetInfoFactory() { return patchSetInfoFactory; } public IdentifiedUser.GenericFactory getUserFactory() { return userFactory; } public AnonymousUser getAnonymousUser() { return anonymousUser.get(); } public PatchSetUtil getPatchsetUtil() { return patchsetUtil; } public Emails getEmails() { return emails; } } }