Package org.openquark.cal.services

Source Code of org.openquark.cal.services.BasicCALServices$Config

/*
* Copyright (c) 2007 BUSINESS OBJECTS SOFTWARE LIMITED
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*     * Redistributions of source code must retain the above copyright notice,
*       this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of Business Objects nor the names of its contributors
*       may be used to endorse or promote products derived from this software
*       without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/


/*
* BasicCALServices.java
* Creation date: Feb 23, 2005.
* By: Edward Lam
*/
package org.openquark.cal.services;

import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.openquark.cal.compiler.Compiler;
import org.openquark.cal.compiler.CompilerMessage;
import org.openquark.cal.compiler.CompilerMessageLogger;
import org.openquark.cal.compiler.MessageLogger;
import org.openquark.cal.compiler.ModuleName;
import org.openquark.cal.compiler.ModuleSourceDefinition;
import org.openquark.cal.compiler.ModuleTypeInfo;
import org.openquark.cal.compiler.PreludeTypeConstants;
import org.openquark.cal.compiler.QualifiedName;
import org.openquark.cal.compiler.Scope;
import org.openquark.cal.compiler.SourceModel;
import org.openquark.cal.compiler.SourceModelModuleSource;
import org.openquark.cal.compiler.SourceModelUtilities;
import org.openquark.cal.compiler.TypeChecker;
import org.openquark.cal.compiler.TypeExpr;
import org.openquark.cal.compiler.TypeChecker.TypeCheckInfo;
import org.openquark.cal.compiler.io.EntryPointSpec;
import org.openquark.cal.machine.StatusListener;
import org.openquark.cal.module.Cal.Core.CAL_Prelude;
import org.openquark.cal.runtime.CALExecutorException;
import org.openquark.cal.runtime.ExecutionContext;
import org.openquark.cal.runtime.MachineType;
import org.openquark.cal.services.ProgramModelManager.CompilationOptions;



/**
* This is a helper class to assist CAL clients with creating and using some of the basic CAL services.
* It handles initialization and compilation of a workspace, provision of some basic CAL service objects, and contains
* some helper methods for filtering gems and running code.
*
* @author Edward Lam
* @author Rick Cameron
* @author mbyne
*/
public final class BasicCALServices {

    /** this is the default BasicCALServices configuration*/
    private static final Config DEFAULT_CONFIG = makeConfig();

    /** The associated workspace manager.*/
    private final WorkspaceManager workspaceManager;
              
    /** handy TypeExpr constants for common Prelude types. */
    private PreludeTypeConstants preludeTypeConstants;
          
    /** The provider from which the workspace manager will be initialized. */
    private final WorkspaceDeclaration.StreamProvider workspaceDeclarationProvider;
   
    /** the default compilation options */
    private CompilationOptions compilerOptions = makeDefaultCompilationOptions();
   
    /** used to cache entry points to reduce recompilation */
    private final EntryPointCache entryPointCache;


    /**
     * This class is used to encapsulate BasicCALServices configuration properties.
     *
     * @author Magnus Byne
     */
    public final static class Config {
       
        /**this defines the machine type used by the basic cal services*/
        private MachineType machineType = MachineType.LECC;

        /** this defines the root provider - directory where lecc files are output*/
        private WorkspaceManager.SourceGenerationRootOverrideProvider rootProvider = WorkspaceManager.DEFAULT_ROOT_OVERRIDER;

        /** this limits the number of entry points that can be cached per module*/
        private int entryPointCacheSize = 10;
       
        /** this limits the number of modules for which entry points are cached*/
        private int moduleCacheSize = 5;
       
        /**
         * Config cannot be instantiated directly - the factory method makeConfig in the containing
         * class must be used
         */
        private Config() {}
       
        /**
         * Set the machine type of the configuration.
         * This option is limited to the package scope.
         * @param machineType
         */
        void setMachineType(MachineType machineType) {
            this.machineType = machineType;
        }
       
        /**
         * Set the maximum number of entry points that can be cached for a particular module
         * @param entryPointCacheSize
         */
        public void setEntryPointCacheSize(int entryPointCacheSize) {
            this.entryPointCacheSize = entryPointCacheSize;
        }
        /**
         * Set the maximum number of modules for which entry points will be cached
         * @param moduleCacheSize the number of modules to cache entry points for
         */
        public void setModuleCacheSize(int moduleCacheSize) {
            this.moduleCacheSize = moduleCacheSize;
        }
          
        /**
         * Set the root directory provider - this controls where compiled modules are stored.
         * @param rootProvider
         */
        public void setSourceRootProvider(WorkspaceManager.SourceGenerationRootOverrideProvider rootProvider) {
            this.rootProvider = rootProvider;
        }
       
    }
       
    /**
     * Constructor for a BasicCALServices object
     * @param workspaceManager The workspace manager to be used.
     * @param workspaceFileProperty
     *   If non-null, the value of this system property represents the file system pathname of the workspace file
     *     to be used to instantiate the workspace.
     *   If null, defaultWorkspaceFileName will be used.
     * @param defaultWorkspaceFileName This workspace file from the StandardVault will be used if the workspaceFileProperty
     *   system property is not set.
     */
    private BasicCALServices (WorkspaceManager workspaceManager,
        String workspaceFileProperty,
        String defaultWorkspaceFileName,
        Config config) {

        if (workspaceManager == null) {
            throw new NullPointerException("Argument workspaceManager may not be null.");
        }
      
        this.workspaceDeclarationProvider =  DefaultWorkspaceDeclarationProvider.getDefaultWorkspaceDeclarationProvider(workspaceFileProperty, defaultWorkspaceFileName);
        this.workspaceManager = workspaceManager;
       
        workspaceManager.getProgramManager();
        workspaceManager.getProgramManager();
       
        this.entryPointCache = new EntryPointCache(workspaceManager, config.entryPointCacheSize, config.moduleCacheSize);
    }

    /** 
     * The simplest factory method to create a BasicCALServices instance.
     * @param workspaceFileName name of the workspace from the StandardVault e.g. "cal.platform.test.cws"
     *   
     * @return the BasicCALServices instance, or null if initialization failed
     */
    public static BasicCALServices make (String workspaceFileName) {

        return make(null, workspaceFileName, null);
    }        
   
    /**
     * The simplest factory method to create a BasicCALServices instance.
     * It ensures that the CAL workspace is compiled and ready to use.
     * This is all that is needed in most cases.
     * @param workspaceFileName
     * @param messageLogger all messages created during the compilation of the workspace are appended to the messageLogger
     * @return the compiled CAL services, or null if initialization or compilation failed
     */
    public static BasicCALServices makeCompiled (String workspaceFileName, CompilerMessageLogger messageLogger) {

        BasicCALServices res =  make(workspaceFileName);       
        if (res == null) {
            return null;
        }
       
        boolean compiled = res.compileWorkspace(null, messageLogger);
       
        if (!compiled) {
            return null;
        }
       
        return res;
    }
   
    /**
     * Factory method for this class.
     * @param workspaceFileProperty
     *   If non-null, the value of this system property represents the file system pathname of the workspace file
     *     to be used to instantiate the workspace.
     *   If null, defaultWorkspaceFileName will be used.
     * @param defaultWorkspaceFileName This workspace file from the StandardVault will be used if the workspaceFileProperty
     *   system property is not set.
     * @param defaultWorkspaceClientID a string identifying the default client for this workspace.
     *   Client id's are used to refer to specific workspaces.  This id will be used, unless the property
     *   indicated by CALWorkspace.WORKSPACE_PROP_CLIENT_ID is set, in which case the property value will be used.
     *   If the client id is null, the workspace is nullary.
     *
     * @return the BasicCALServices instance, or null if initialization failed
     */
    public static BasicCALServices make (
        String workspaceFileProperty,
        String defaultWorkspaceFileName,
        String defaultWorkspaceClientID) {
       
        return make(workspaceFileProperty, defaultWorkspaceFileName, defaultWorkspaceClientID, DEFAULT_CONFIG);
    }   
   
    /**
     * Factory method for this class.
     * @param workspaceFileProperty
     *   If non-null, the value of this system property represents the file system pathname of the workspace file
     *     to be used to instantiate the workspace.
     *   If null, defaultWorkspaceFileName will be used.
     * @param defaultWorkspaceFileName This workspace file from the StandardVault will be used if the workspaceFileProperty
     *   system property is not set.
     * @param defaultWorkspaceClientID a string identifying the default client for this workspace.
     *   Client id's are used to refer to specific workspaces.  This id will be used, unless the property
     *   indicated by CALWorkspace.WORKSPACE_PROP_CLIENT_ID is set, in which case the property value will be used.
     *   If the client id is null, the workspace is nullary.
     * @param config this parameter controls the configuration of the BasicCALServices that is created
     * @return the BasicCALServices instance, or null if initialization failed
     */
    public static BasicCALServices make (
        String workspaceFileProperty,
        String defaultWorkspaceFileName,
        String defaultWorkspaceClientID,
        Config config) {
       
       
        String clientID = WorkspaceConfiguration.getDiscreteWorkspaceID(defaultWorkspaceClientID);

        WorkspaceManager workspaceManager = WorkspaceManager.getWorkspaceManager(clientID, config.machineType, config.rootProvider);

        if (workspaceManager ==null) {
            return null;
        } else {
            return new BasicCALServices(workspaceManager, workspaceFileProperty, defaultWorkspaceFileName, config);
        }
    }
   
    /** makes a new BasicCALServices configuarion with default properties
     * @return a new default config
     */
    public static Config makeConfig() {
        return new Config();
    }

    /**
     * @return the workspace manager.
     */
    public WorkspaceManager getWorkspaceManager() {
        return workspaceManager;
    }

    /** 
     * Note: must have a compiled workspace in hand before these will be available. 
     * @return handy TypeExpr constants for common Prelude types.
     */
    public PreludeTypeConstants getPreludeTypeConstants() {
       
        if (preludeTypeConstants == null) {
           
            ModuleTypeInfo preludeModuleTypeInfo = workspaceManager.getModuleTypeInfo(CAL_Prelude.MODULE_NAME);
            if (preludeModuleTypeInfo == null) {
                throw new IllegalStateException("Must have a successfully compiled Cal.Core.Prelude module before getPreludeTypeConstants can be called.");
            }
           
            preludeTypeConstants = new PreludeTypeConstants(preludeModuleTypeInfo);          
        }
       
        return preludeTypeConstants;
    }   

    /**
     * Compile the workspace.
     *
     * @param programStatusListener if non-null, the listener on the status of the compilation.
     * @param logger the logger used to log error messages during compilation.
     * @return true if the compilation was successful
     */
    public boolean compileWorkspace(StatusListener programStatusListener, CompilerMessageLogger logger) {
       
        entryPointCache.lockCache();
        try {
            entryPointCache.flush();

            // Load default prelude.
            if (logger == null) {
                logger = new MessageLogger ();
            }

            Status compileStatus = new Status("Compile status.");

            // Initialize the workspace.
            workspaceManager.initWorkspace(workspaceDeclarationProvider, compileStatus);

            if (compileStatus.getSeverity() != Status.Severity.OK) {
                logger.logMessage(compileStatus.asCompilerMessage());
                return false;
            }

            boolean programCompilationSuccessful = makeProgram (this.workspaceManager, logger, programStatusListener);

            return programCompilationSuccessful;
        } finally {
            entryPointCache.unlockCache();
        }
    }
   
    /**
     * Recompile the workspace.
     * @return true if the compilation was successful, false otherwise.
     */
    public boolean recompileWorkspace (CompilerMessageLogger logger) {
        entryPointCache.lockCache();
        try {
            entryPointCache.flush();
            return makeProgram (this.workspaceManager, logger, null);
        } finally {
            entryPointCache.unlockCache();
        }
    }

    /**
     * Builds the program object using the CAL file at the given location.
     * Sets the internal program member.
     * @return true if compilation was successful, false otherwise
     */
    private boolean makeProgram(WorkspaceManager workspaceManager, CompilerMessageLogger logger, StatusListener statusListener) {
   
        if (logger == null) {
            logger = new MessageLogger ();
        }
        int nErrorsBefore = logger.getNErrors();
   
        // Compile.
        workspaceManager.compile(logger, false, statusListener);

        return logger.getNErrors() == nErrorsBefore;
    }
   
    /**
     * @return the CAL workspace.
     */
    public CALWorkspace getCALWorkspace () {
        return getWorkspaceManager().getWorkspace ();
    }

    /**
     * @return an associated Compiler
     */
    public Compiler getCompiler() {
        return getWorkspaceManager().getCompiler();
    }
   
    /**
     * @return the associated TypeChecker
     */
    public TypeChecker getTypeChecker() {
        return getWorkspaceManager().getTypeChecker();
    }
   
    /**
     * Get the type info for a module
     * @param moduleName the name of the module
     * @return the type info for the module
     */
    public ModuleTypeInfo getModuleTypeInfo(ModuleName moduleName) {
        CALWorkspace workspace = getCALWorkspace();
        if (workspace == null) {
            return null;
        }
        return workspace.getMetaModule(moduleName).getTypeInfo();
    }

    /**
     * Get the type checker info for a module
     * @return the TypeCheckInfo for a module
     */
    public TypeCheckInfo getTypeCheckInfo(ModuleName moduleName) {
        return getTypeChecker ().getTypeCheckInfo (moduleName);
    }

    /**
     * Returns the entity corresponding to the specified qualified name.
     * @param gemName the name of the entity to retrieve.
     * @return the corresponding gem entity, or null if it is not found.
     */
    public GemEntity getGemEntity(QualifiedName gemName) {
        return getWorkspaceManager().getWorkspace().getGemEntity(gemName);
    }
   
    /**
     * This returns a type expression for the type represented by the qualified name
     * the type expression is evaluated within the scope of the type's defining module
     * @param name the types qualified name
     * @return type expression representing the qualified type name
     */
    public TypeExpr getTypeFromQualifiedName(QualifiedName name) {
        return getTypeFromString(name.getModuleName(), name.getQualifiedName());
    }
   
    /**
     * Returns the type expression corresponding to the specified string.
     * @param module the type string is compiled w.r.t to this module
     * @param typeString a string representation a CAL type.
     * @return a type expression object corresponding to the string, or null if the string couldn't be converted to a type.
     */
    public TypeExpr getTypeFromString(ModuleName module, String typeString) {   
        return getTypeChecker().getTypeFromString(typeString, module, null);  
    }   

    /**
     * Returns public gems in the workspace that match the given filter
     *
     * @param filter a gem filter.
     * @return public gems in the workspace which pass the filter.
     */
    public Set<GemEntity> getMatchingGems(GemFilter filter) {
        return getMatchingGems(filter, true);
    }

    /**
     * Returns public gems in the workspace that match the given filter.
     *
     * @param filter a gem filter.
     * @param sortGems If true, then the gems will be sorted alphabetically.
     * @return public gems in the workspace which pass the filter.
     */
    public Set<GemEntity> getMatchingGems(GemFilter filter, boolean sortGems) {
        GemViewer gemViewer = new GemViewer();

        // Sort the gems alphabetically, if specified.
        if (sortGems) {
            gemViewer.setSorter (new GemQualifiedNameCaseInsensitiveSorter ());
        }
   
        gemViewer.addFilter(filter);
   
        return getVisibleGemEntities(gemViewer); //perspective.getVisibleGemEntities();
    }

   
    /**
     * Get public gems in the workspace.
     * @param gemEntityViewer the gem viewer used to filter the gems returned
     * @return public gems in the workspace which visible by the given viewer
     */
    private Set<GemEntity> getVisibleGemEntities(GemViewer gemEntityViewer) {

        CALWorkspace workspace = getCALWorkspace();
       
        Set<GemEntity> visibleEntitySet = new LinkedHashSet<GemEntity>();

        // add all visible entities from visible modules
        int nVisibleModules = workspace.getNMetaModules(); //  getNVisibleMetaModules();
        for (int i = 0; i < nVisibleModules; i++) {
            MetaModule nthModule = workspace.getNthMetaModule(i);
            visibleEntitySet.addAll(getVisibleGemEntities(nthModule, gemEntityViewer));//   getVisibleGemEntities(nthModule));
        }

        // Apply the view policy if any.
        if (gemEntityViewer != null) {
            visibleEntitySet = new LinkedHashSet<GemEntity>(gemEntityViewer.view(visibleEntitySet));
        }
        return visibleEntitySet;
    }
   
    /**
     * Get the public gems in a given module.
     * @param module the module in which to look.
     * @return Set (GemEntity) the set of visible entities.
     */
    private Set<GemEntity> getVisibleGemEntities(MetaModule module, GemViewer gemEntityViewer) {
       
        // Check that module != null
        Assert.isNotNullArgument(module, "module");

        int nEntities = module.getNGemEntities();

        // Add all entities from the working module, or only public entities from non-working modules.
        Set<GemEntity> visibleEntitySet = new LinkedHashSet<GemEntity>();
        for (int i = 0; i < nEntities; i++) {

            GemEntity gemEntity = module.getNthGemEntity(i);
           
            if (gemEntity.getScope() == Scope.PUBLIC) {
                visibleEntitySet.add(gemEntity);
            }
        }

        // Apply the view policy if any.
        if (gemEntityViewer != null) {
            visibleEntitySet = new LinkedHashSet<GemEntity>(gemEntityViewer.view(visibleEntitySet));
        }

        return visibleEntitySet;
    }
   
    /**
     * Returns a Set containing the public gems in the workspace
     * which have the specified type signature.
     * @param scopeModule this is the module that is used for scope
     * @param typeName  the type signature of the gems to be found
     * @param sortGems  If true, then the gems will be sorted alphabetically.
     * @return a set of the matching gems
     */
    public Set<GemEntity> findGemsOfType(ModuleName scopeModule, String typeName, boolean sortGems) {
        // Get the type expression for the type name.
        final TypeExpr typeExpr = getTypeFromString(scopeModule, typeName);
        if (typeExpr == null) {
            return Collections.emptySet();
        }

        // Find all gems matching this type.
        final ModuleTypeInfo targetModuleTypeInfo = getModuleTypeInfo(scopeModule);
        GemFilter filter = new GemFilter() {
            @Override
            public boolean select(GemEntity gemEntity) {
                TypeExpr gemType = gemEntity.getTypeExpr();
                return TypeExpr.canPatternMatch(gemType, typeExpr, targetModuleTypeInfo);
            }
        };
        return getMatchingGems(filter, sortGems);
    }

    /**
     * Returns a set containing the public gems in the workspace which have
     * the specified return type.
     * @param scopeModule     this is the module that is used for compiling the type
     * @param returnTypeName  the type name of the return type for the gems to be found
     * @param sortGems        If true, then the gems will be sorted alphabetically.
     * @return (Set of GemEntity) a set of the matching gems
     */
    public Set<GemEntity> findGemsByReturnType(ModuleName scopeModule, String returnTypeName, boolean sortGems) {
        // Get the type expression for the type name.
        final TypeExpr returnTypeExpr = getTypeFromString(scopeModule, returnTypeName);
        if (returnTypeExpr == null) {
            return Collections.emptySet();
        }

        // Find all gems matching this type.
        final ModuleTypeInfo targetModuleTypeInfo = getModuleTypeInfo(scopeModule);
        GemFilter filter = new GemFilter() {
            @Override
            public boolean select(GemEntity gemEntity) {
                TypeExpr gemResultType = gemEntity.getTypeExpr().getResultType();
                return TypeExpr.canPatternMatch(gemResultType, returnTypeExpr, targetModuleTypeInfo);
            }
        };
        return getMatchingGems(filter, sortGems);
    }

    /**
     * Compile the source definition for a module and add it to the program
     * @param sourceDefinition the module's source definition.
     * @param logger the logger used to log error messages during compilation.
     * @return the max error severity from the compile.
     */
    public CompilerMessage.Severity addNewModule(ModuleSourceDefinition sourceDefinition,
                                                  CompilerMessageLogger logger) {

        entryPointCache.lockCache();
        try {
            entryPointCache.flush();
            return getWorkspaceManager().makeModule(sourceDefinition, logger, compilerOptions);
        } finally {
            entryPointCache.unlockCache();
        }
    }
   
    /**
     * Add a new module containing the specified function to the program.
     * Imports are computed automatically based on the function.
     * If the module already exists its' contents are replaced by the funcDefn.
     * @param newModuleName
     * @param functionDefintion
     * @return an EntryPointSpec with default input/output policies for the new function.
     * @throws GemCompilationException
     */
    public EntryPointSpec addNewModuleWithFunction(ModuleName newModuleName, SourceModel.FunctionDefn functionDefintion) throws GemCompilationException {
       
        return addNewModuleWithFunction(newModuleName, null, functionDefintion, null);
    }
   
    /**
     * Add a new module containing the specified function, type declaration and imports to the program.
     * If the module already exists its' contents are replaced by the funcDefn. 
     * @param newModuleName
     * @param imports - if this is null the imports are computed based on the function definition
     * @param functionDefinition
     * @param functionTypeDeclaration the type declaration for the function, this may be null
     * @return an EntryPointSpec, with default input/output policies, for the new function.
     * @throws GemCompilationException
     */
    public EntryPointSpec addNewModuleWithFunction(ModuleName newModuleName, SourceModel.Import[] imports, SourceModel.FunctionDefn functionDefinition, SourceModel.FunctionTypeDeclaration functionTypeDeclaration) throws GemCompilationException {
        if (newModuleName == null) {
            throw new NullPointerException("Argument newModuleName must not be null.");
        }
        if (functionDefinition == null) {
            throw new NullPointerException("Argument functionDefinition must not be null.");
        }
       
        //create the module containing the function
        SourceModel.ModuleDefn newModule = SourceModel.ModuleDefn.make(
            newModuleName,
            imports,
            functionTypeDeclaration == null ?
                    new SourceModel.TopLevelSourceElement[] { functionDefinition } :
                    new SourceModel.TopLevelSourceElement[] { functionTypeDeclaration, functionDefinition }   );
           
        //compute the necessary imports
        if (imports == null) {
            newModule = SourceModelUtilities.ImportAugmenter.augmentWithImports(newModule);
        }
       
        CompilerMessageLogger logger = new MessageLogger();
       
        //add the module to the workspace
        CompilerMessage.Severity errorLevel = addNewModule(new SourceModelModuleSource(newModule), logger);
       
        if (errorLevel.compareTo(CompilerMessage.Severity.ERROR) >= 0) {
            throw new GemCompilationException("Error adding new module", logger);
        }
               
        return EntryPointSpec.make(QualifiedName.make(newModuleName, functionDefinition.getName()));
    }

    /**
     * Runs an existing CAL function and returns the result.
     * A new default execution context is created to run the function, and then destroyed.
     * It is worthwhile to consider
     * creating an execution context separately and using it for all calls to runFunction, as this
     * can be more efficient, allowing certain results to be cached between executions.
     * @see #runFunction(EntryPointSpec, ExecutionContext, Object[])
     * 
     * @param entryPointSpec defines the function to run and the input and output policies to use.
     * @param args the arguments to pass to the function - may be null if there are no arguments
     * @return the result of running the function.
     * @throws CALExecutorException
     * @throws GemCompilationException
     */
    public Object runFunction(EntryPointSpec entryPointSpec, Object[] args) throws CALExecutorException, GemCompilationException {

        ExecutionContext executionContext = workspaceManager.makeExecutionContextWithDefaultProperties();
       
        try {           
            return runFunction(entryPointSpec, executionContext, args);
        } finally {
            workspaceManager.resetCachedResults(executionContext);
        }
    }
   
    /**
     * runs an existing function and returns the result. It uses the supplied execution context.
     * It is generally much more efficient to use this version of runFunction, as it allows
     * CAFs can be cached between calls.
     * @param entryPointSpec defines the function to run and the input and output policies to use.
     * @param args the arguments to pass to the function - may be null if there are no arguments.
     * @return the result of running the function.
     * @throws CALExecutorException
     * @throws GemCompilationException
     */
    public Object runFunction(EntryPointSpec entryPointSpec, ExecutionContext executionContext, Object[] args) throws CALExecutorException, GemCompilationException {
        if (entryPointSpec == null) {
            throw new NullPointerException("Argument entryPointSpec must not be null.");
        }
        if (executionContext == null) {
            throw new NullPointerException("Argument executionContext must not be null.");
        }
       
        return entryPointCache.runFunction(entryPointSpec, args == null ? new Object[0] : args, executionContext);
       
    }
   
    /**
     * This method pre-caches a list of entryPointSpecs for invocation with runFunction.
     * It is not necessary to use this method before using run function, but in some
     * circumstances it can improve performance. When runFunction is invoked on an
     * entryPointSpec for the first time, the CAL compiler must do some work in the target module.
     * If you intend to use many entryPointSpecs for the same module, invoking this function
     * with a list of the entryPointSpecs allows the CAL compiler to prepare them all
     * in a single step, which can be more efficient. If you run only a single function (even many times)
     * in any given module, or are not concerned by the cost of the first call to runFunction
     * for each entryPointSpec, there is no need to use this function.
     *
     * @param entryPointSpecs a list of entry point specs that will be used later by runFunction.
     * @throws GemCompilationException
     */
    public void prepareFunctions(List<EntryPointSpec> entryPointSpecs) throws GemCompilationException {
        entryPointCache.cacheEntryPoints(entryPointSpecs);
    }
   
    /**
     * Get compiler options
     */
    public CompilationOptions getCompilationOptions() {
        return new CompilationOptions(compilerOptions);
    }
   
    /**
     * set the compilation options - if they are not set default compilation options will be used
     * @param options the compilation options to use when running code.
     */
    public void setCompilationOptions(CompilationOptions options) {
        compilerOptions = new CompilationOptions(options);
    }

    /**
     * @return the default compilation options, with the for immediate use flag set to true.
     */
    private static CompilationOptions makeDefaultCompilationOptions() {
        CompilationOptions options = new CompilationOptions();
        options.setForImmediateUse(true);
        return options;
    }
}

TOP

Related Classes of org.openquark.cal.services.BasicCALServices$Config

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.