/* * 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. */ /* * ProgramManager.java * Created: Feb 19, 2003 at 12:15:13 PM * By: Raymond Cypher */ package org.openquark.cal.machine; import java.util.Collections; import java.util.List; import java.util.Set; import org.openquark.cal.compiler.EntryPointGenerator; import org.openquark.cal.compiler.ModuleName; import org.openquark.cal.compiler.ModuleTypeInfo; import org.openquark.cal.compiler.ProgramModifier; import org.openquark.cal.compiler.QualifiedName; import org.openquark.cal.compiler.TypeCheckerImpl; import org.openquark.cal.machine.Program.ProgramException; import org.openquark.cal.runtime.ExecutionContext; import org.openquark.cal.runtime.ExecutionContextProperties; import org.openquark.cal.runtime.MachineConfiguration; import org.openquark.cal.runtime.MachineType; import org.openquark.cal.runtime.ResourceAccess; /** * This is the ProgramManager class. * * This is a factory class used to create a machine specific * ProgramModifier, EntryPointGenerator or TypeCheckerImpl. * <p> * Created: Feb 19, 2003 at 12:15:13 PM * @author Raymond Cypher * @author Joseph Wong */ public abstract class ProgramManager { /** * The copy of the machine specific program. The scope of this field is * protected so as to allow subclasses to access it. It is never meant to be * made available to external clients. */ protected final Program theProgram; /** * Provides access to the resources of the current environment (e.g. from the workspace, or from Eclipse). */ protected final ResourceAccess resourceAccess; /** * Protected constructor for this abstract ProgramManager class. * * @param program * the Program object to be encapsulated by this ProgramManager * instance. * @param resourceAccess * the ResourceAccess instance to provide access to the resources of the current * environment (e.g. from the workspace, or from Eclipse). */ protected ProgramManager(Program program, ResourceAccess resourceAccess) { if (program == null) { throw new IllegalArgumentException("ProgramManager: the program must not be null"); } if (resourceAccess == null) { throw new IllegalArgumentException("ProgramManager: the resourceAccess must not be null"); } theProgram = program; this.resourceAccess = resourceAccess; } /** * Factory method for a workspace manager. * The default machine type will be used, unless otherwise specified by the system property. * @param resourceAccess * the ResourceAccess instance to provide access to the resources of the current * environment (e.g. from the workspace, or from Eclipse). * @return the ProgramManager for this workspace. */ public static ProgramManager getProgramManager(ProgramResourceRepository.Provider resourceRepositoryProvider, ResourceAccess resourceAccess) { // the machine type system property is fetched on a per-call basis rather than during // initialization, allowing a determined client (e.g. ICE) to set the property // at an opportune time before this method is called. String machineTypeProperty = System.getProperty(MachineConfiguration.MACHINE_TYPE_PROP); // Lecc is the default machine type. boolean useGMachine = machineTypeProperty != null && machineTypeProperty.equals(MachineType.G.toString()); MachineType machineType = useGMachine ? MachineType.G : MachineType.LECC; return getProgramManager(machineType, resourceRepositoryProvider, resourceAccess); } /** * Factory method for a workspace manager. * Note that specification of the machine type is intended as "internal" public. * Clients will always use the default machine type, unless they are intended to have "special" * knowledge that other machine types are available. * * @param machineType the machine type. * @param resourceAccess * the ResourceAccess instance to provide access to the resources of the current * environment (e.g. from the workspace, or from Eclipse). */ public static ProgramManager getProgramManager(MachineType machineType, ProgramResourceRepository.Provider resourceRepositoryProvider, ResourceAccess resourceAccess) { if (machineType == MachineType.G) { return org.openquark.cal.internal.machine.g.ProgramManager.makeInstance(resourceAccess); } else if (machineType == MachineType.LECC) { return org.openquark.cal.internal.machine.lecc.ProgramManager.makeInstance(resourceRepositoryProvider.getRepository(machineType), resourceAccess); } else { throw new IllegalArgumentException("Unknown machine type: " + machineType.toString()); } } /** * Returns the machine type associated with this ProgramManager. * * @return the machine type. */ public abstract MachineType getMachineType(); /** * Factory method for creating a machine-specific ProgramModifier. * * @return a new ProgramModifier instance. */ public abstract ProgramModifier makeProgramModifier(); /** * Factory method for creating a machine-specific EntryPointGenerator. * * @return a new EntryPointGenerator instance. */ public abstract EntryPointGenerator makeEntryPointGenerator(); /** * Factory method for creating a machine-specific TypeCheckerImpl. * * @return a new TypeCheckerImpl instance. */ public abstract TypeCheckerImpl makeTypeCheckerImpl(); /** * Factory method for creating a machine-specific execution context. * @param properties the ExecutionContextProperties instance encapsulating an immutable map of key-value pairs which is exposed * as system properties from within CAL. * * @return a new CALExecutor.Context instance. */ public abstract ExecutionContext makeExecutionContext(ExecutionContextProperties properties); /** * Factory method for creating a machine-specific executor. * * @param context * the execution context to be used by the executor. * @return a new CALExecutor instance. */ public abstract CALExecutor makeExecutor(ExecutionContext context); /** * Discards any cached (memoized) results in this program. * * @param context * the context with which the cached results are associated. */ public void resetCachedResults(ExecutionContext context) { theProgram.resetCachedResults(context); } /** * Discards any cached (memoized) results in the named module and any * dependent modules. * * @param moduleName * the name of the module whose cached results, and whose * dependents' cached results, are to be discarded. * @param context * the context with which the cached results are associated. */ public void resetCachedResults(ModuleName moduleName, ExecutionContext context) { theProgram.resetCachedResults(moduleName, context); } /** * Discards the machine state, including any cached (memoized) results in this program. * * @param context * the context with which the machine state is associated. */ public void resetMachineState(ExecutionContext context) { theProgram.resetMachineState(context); } /** * Discards the machine state, including any cached (memoized) results in the named module and any * dependent modules. * * @param moduleName * the name of the module whose machine state, and whose * dependents' machine state, are to be discarded. * @param context * the context with which the machine state associated. */ public void resetMachineState(ModuleName moduleName, ExecutionContext context) { theProgram.resetMachineState(moduleName, context); } /** * Returns true iff the specified module is in the Program instance * encapsulated by this ProgramManager. * * @param moduleName * the name of the module to check. * @return true iff the specified module is in the program. */ public boolean containsModule(ModuleName moduleName) { return theProgram.getModule(moduleName) != null; } /** * Returns the names of the modules contained by the Program instance * encapsulated by this ProgramManager. * * @return an array of module names for the modules in the program. */ public ModuleName[] getModuleNames() { return theProgram.getModuleNames(); } /** * Return a list of Module object for modules contained the Program instance * encapsulated by this ProgramManager. * * @return a list of Module objects for the modules in this program. */ public List<Module> getModules() { return theProgram.getModules(); } /** * Gets the module with a given moduleName. * @return the module with a given module name * @param name the module name */ public Module getModule(ModuleName name) { return theProgram.getModule(name); } /** * Generates a list of all modules that depend on the named module either * directly or indirectly. * * @param dependeeModulename * the name of the dependee module. * @param returnEmptySetIfNonexistent * if true, this method returns an empty list if the module is * not in the program. Otherwise it returns null in such a case. * @return A list of names of all dependent modules. */ public Set<ModuleName> getSetOfDependentModuleNames(ModuleName dependeeModulename, boolean returnEmptySetIfNonexistent) { Set<ModuleName> set = theProgram.getDependentModules(dependeeModulename); if (set == null) { return returnEmptySetIfNonexistent ? Collections.<ModuleName>emptySet() : null; } else { return set; } } /** * Returns the type info for the specified module. * * @param moduleName * the name of the module whose type info is requested. * @return the type info for the specified module, or null if the module is * not in the program. */ public ModuleTypeInfo getModuleTypeInfo(ModuleName moduleName) { Module module = theProgram.getModule(moduleName); if (module != null) { return module.getModuleTypeInfo(); } else { return null; } } /** * Returns the number of functions in the specified module. * * @param moduleName * the name of the module. * @return the number of functions in the specified module, or 0 if the * module is not in the program. */ public int getNFunctionsInModule(ModuleName moduleName) { Module module = theProgram.getModule(moduleName); if (module != null) { return module.getNFunctions(); } else { return 0; } } /** * Retrieves the specified machine function. * * @param functionName * the qualified name of the function. * @return the specified machine function, or null if it does not exist. * @throws ProgramException * if the program does not contain the module for the function. */ public MachineFunction getMachineFunction(QualifiedName functionName) throws ProgramException { return theProgram.getCodeLabel(functionName); } /** * @param useOptimizer True iff the CAL based optimizer should be used during compilation. */ public void useOptimizer(boolean useOptimizer){ theProgram.useOptimizer(useOptimizer); } /** * @return the repository for program resources, or null if none. */ public abstract ProgramResourceRepository getProgramResourceRepository(); /** * @return the machine statistics associated with this program. */ public abstract MachineStatistics getMachineStatistics(); /** * @param moduleName * @return the machine statistics associated with the given module. */ public abstract MachineStatistics getMachineStatisticsForModule(ModuleName moduleName); }