/*
* Copyright 2003-2015 JetBrains s.r.o.
*
* 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 jetbrains.mps.module;
import jetbrains.mps.classloading.ClassLoaderManager;
import jetbrains.mps.classloading.ModuleClassNotFoundException;
import jetbrains.mps.classloading.ModuleIsNotLoadableException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.mps.openapi.module.SModule;
/**
* Represents a module which can be associated with some class loader.
*
* For example suppose there is a language module L in MPS.
* Also let there be a solution S which uses the language L. Imagine that at some point you decide to
* change the language L, e.g. change the editor representation for some concept C in the language L.
* Obviously you expect MPS to change the UI appearance for the instances of the concept C in the solution S.
* Moreover you want MPS to change the UI representation right after the used language L is generated and compiled.
*
* To enable such workflow MPS introduces its own class loading subsystem. Also it brings in a notion of reloadable modules --
* such modules which can be redeployed during design-time in MPS.
* So the language L in the given example is clearly a reloadable module.
*/
public interface ReloadableModule extends SModule {
/**
* @return a class which can be obtained by calling #getclass from
* {@link #getClassLoader()} method.
* a ModuleClassLoader. ModuleClassLoader's #loadClass method yields some additional information
* about the reasons of class which could not be found.
* Clients of this API are supposed to process it on their own behalf.
*
* @see jetbrains.mps.classloading.ModuleClassNotFoundException
* @see jetbrains.mps.classloading.ModuleIsNotLoadableException
* warning: this method is lazy implemented!
*/
@NotNull
Class<?> getClass(String classFqName) throws ClassNotFoundException, ModuleClassNotFoundException, ModuleIsNotLoadableException;
/**
* @return a class which can be obtained by calling #getClass from
* {@link #getClassLoader()} method in the case when the defining class loader is
* a ModuleClassLoader.
*
* @see jetbrains.mps.classloading.ModuleClassNotFoundException
* @see jetbrains.mps.classloading.ModuleIsNotLoadableException
* @see jetbrains.mps.classloading.ModuleClassLoader
* @see jetbrains.mps.classloading.ModuleClassLoader#loadOwnClass(String)
* warning: this method is lazy implemented!
*/
@NotNull
Class<?> getOwnClass(String classFqName) throws ClassNotFoundException, ModuleClassNotFoundException, ModuleIsNotLoadableException;
/**
* @return the class loader associated with the module.
* Currently it can be either MPS ModuleClassLoader or IdeaPlugin PluginClassLoader.
*
* The latter is returned in the case when IDEA plugin manages the module's classes.
* Use it if you want to get a class from the module with IdeaPluginFacet.
* warning: this method is lazy implemented!
*/
@Nullable
ClassLoader getClassLoader();
/**
* @return so-called parent (or root) class loader. Simply returns the Idea plugin classloader in the case the module is
* bundled into an idea plugin. Will return an application classloader in the case there is no idea plugin.
* Contract: the class loader returned from #getClassLoader always depends on the root class loader.
*/
ClassLoader getRootClassLoader();
/**
* Call it to replace the old class loader of this module with a new one.
* To reload more than one module all together
* check out {@link ClassLoaderManager#reloadModules(Iterable)} method.
*/
void reload();
/**
* @return true if it will load classes.
* For some subclasses it is possible to disable class loading for <code>ReloadableModule</code>.
* E.g. solution without idea/mps facet cannot load classes
* @see jetbrains.mps.project.Solution
*/
boolean willLoad();
}