Class ModelManagement<M extends IModel>

java.lang.Object
net.ssehub.easy.basics.modelManagement.ModelManagement<M>
Type Parameters:
M - the specific model type

public abstract class ModelManagement<M extends IModel> extends Object
A reusable class performing model imports, model linking etc. The central class holding all model instances and being responsible for import resolution. Model loading is done by plugins of type IModelLoader. Public access shall be synchronized (in any way) as multiple source parts and tools may access the information concurrently. Please note that specific information and settings are available via availableModels(), events(), loaders(), locale() and locations(). The model needs a loader and a location to operate. After providing this information, available models can be accessed via availableModels().
Author:
Holger Eichelberger
  • Field Details

  • Constructor Details

    • ModelManagement

      protected ModelManagement()
      Singleton.
  • Method Details

    • createRepository

      protected abstract ModelRepository<M> createRepository()
      Creates a model repository instance.
      Returns:
      the instance
    • createResolver

      protected abstract ImportResolver<M> createResolver()
      Creates a resolver instance.
      Returns:
      the resolver instance
    • locale

      public ModelLocale locale()
      Provides access to the internationalization mechanisms. For future compatibility, please store the returned instance just for temporary purposes within a method and not for long-term use in an attribute etc.
      Returns:
      the locale object
    • events

      public ModelEvents<M> events()
      Provides access to the event mechanisms. For future compatibility, please store the returned instance just for temporary purposes within a method and not for long-term use in an attribute etc.
      Returns:
      the events object
    • loaders

      public ModelLoaders<M> loaders()
      Provides access to the model loaders. For future compatibility, please store the returned instance just for temporary purposes within a method and not for long-term use in an attribute etc.
      Returns:
      the events object
    • locations

      public ModelLocations<M> locations()
      Provides access to the model location. For future compatibility, please store the returned instance just for temporary purposes within a method and not for long-term use in an attribute etc.
      Returns:
      the events object
    • availableModels

      public AvailableModels<M> availableModels()
      Returns access to the available models. For future compatibility, please store the returned instance just for temporary purposes within a method and not for long-term use in an attribute etc.
      Returns:
      the model paths object
    • repository

      protected ModelRepository<M> repository()
      Returns the repository instance.
      Returns:
      the repository instance
    • getResolverFromPool

      public ImportResolver<M> getResolverFromPool()
      Returns the current top-level resolver.
      Returns:
      the top-level resolver
      See Also:
    • releaseResolver

      public void releaseResolver(ImportResolver<M> resolver)
      Releases a given resolver instance.
      Parameters:
      resolver - the resolver to be released
      See Also:
    • updateModel

      public void updateModel(M model, URI uri, IModelLoader<M> loader)
      Add a model to this management instance. Existing models are overwritten in case of same name and version.
      Parameters:
      model - the model to be added
      uri - the URI of the model (used for unique identification)
      loader - The parser able to load model
    • notifyLoadingCompleted

      public void notifyLoadingCompleted(M model, URI uri)
      Notifies that loading the given model is completed. Calls postLoadModel(ModelInfo).
      Parameters:
      model - the model to be added
      uri - the URI of the model (used for unique identification)
    • updateModel

      public void updateModel(M model, URI uri, IModelLoader<M> loader, boolean deepReload)
      Add a model to this management instance. Existing models are overwritten in case of same name and version.
      Parameters:
      model - the model to be added
      uri - the URI of the model (used for unique identification)
      loader - The parser able to load model
      deepReload - perform a deep reload of the dependent models
    • reload

      private void reload(List<M> models)
      Loads a set of models. Errors are logged.
      Parameters:
      models - the models to be (re)loaded (entries may be null)
    • reload

      public M reload(M model)
      Update the given model by trying to reload it. Errors are logged.
      Parameters:
      model - the model to be reloaded
      Returns:
      the loaded model (may be model if no new model was loaded)
    • reload

      public M reload(M model, boolean deepReload)
      Update the given model by trying to reload it. Errors are logged.
      Parameters:
      model - the model to be reloaded
      deepReload - perform a deep reload of the dependent models
      Returns:
      the loaded model (may be model if no new model was loaded)
    • unload

      public int unload(M model, ProgressObserver observer) throws ModelManagementException
      Unloads model as well as unloadable imported models, but not the related model information. No events will be sent but event listeners will be cleared. Please note that references within model will not be modified and not managed by this class after calling this method! Please release all references to model after calling this method!
      Parameters:
      model - the model to be unloaded
      observer - an optional progress observer (use ProgressObserver.NO_OBSERVER but not null in case that no observation is intended)
      Returns:
      the number of unloaded models
      Throws:
      ModelManagementException - in case that unloading fails
    • unloadImpl

      private void unloadImpl(M model)
      Unloads a certain model.
      Parameters:
      model - the model to unload
    • updateModel

      public void updateModel(M model, URI uri)
      Add a model to this management instance. Existing models are overwritten in case of same name and version.
      Parameters:
      model - the model to be added
      uri - the URI of the model (used for unique identification)
    • setResolved

      private M setResolved(ModelInfo<M> info, M model)
      Defines the resolution for info and calls the listeners. Calls IModel.dispose() if needed.
      Parameters:
      info - the information object to be updated
      model - the resolving model
      Returns:
      the old model, before replaced by model (may be null if inconsistent or not yet loaded)
    • getModelCount

      public int getModelCount()
      Returns the number of (known) models.
      Returns:
      the number of models
    • getModel

      public M getModel(int index)
      Returns the specified model.
      Parameters:
      index - the 0-based index of the model
      Returns:
      the model
      Throws:
      IndexOutOfBoundsException - if index<=0 || index>=getModelCount()
    • resolveImports

      public List<IMessage> resolveImports(M model, URI uri, List<ModelInfo<M>> inProgress)
      Resolves the imports of the given model with transitive loading and returns messages on failures. Exceptions might be appropriate here but the caller shall be able to decide how to handle the level of detail, i.e. whether the first message shall be emitted or all. May modify model as a side effect. This method uses a new default import resolver.
      Parameters:
      model - the model to be resolved
      uri - the URI of the model to resolve (in order to find the closest model, may be null)
      inProgress - the model information objects of the models currently being processed at once (may be null)
      Returns:
      messages which occur during resolution, null or empty if none
    • resolveImports

      public List<IMessage> resolveImports(M model, URI uri, List<ModelInfo<M>> inProgress, boolean transitiveLoading)
      Resolves the imports of the given model and returns messages on failures. Exceptions might be appropriate here but the caller shall be able to decide how to handle the level of detail, i.e. whether the first message shall be emitted or all. May modify model as a side effect. This method uses a new default import resolver.
      Parameters:
      model - the model to be resolved
      uri - the URI of the model to resolve (in order to find the closest model, may be null)
      inProgress - the model information objects of the models currently being processed at once (may be null)
      transitiveLoading - with or without transitive loading (see ImportResolver)
      Returns:
      messages which occur during resolution, null or empty if none
    • resolveImports

      public List<IMessage> resolveImports(M model, URI uri, List<ModelInfo<M>> inProgress, ImportResolver<M> resolver)
      Resolves the imports of the given model with transitive loading and returns messages on failures. Exceptions might be appropriate here but the caller shall be able to decide how to handle the level of detail, i.e. whether the first message shall be emitted or all. May modify model as a side effect.
      Parameters:
      model - the model to be resolved
      uri - the URI of the model to resolve (in order to find the closest model, may be null)
      inProgress - the model information objects of the models currently being processed at once (may be null)
      resolver - the import resolver (may be null to use a new default import resolver)
      Returns:
      messages which occur during resolution, null or empty if none
    • resolveImports

      public List<IMessage> resolveImports(M model, URI uri, List<ModelInfo<M>> inProgress, ImportResolver<M> resolver, boolean transitiveLoading)
      Resolves the imports of the given model and returns messages on failures. Exceptions might be appropriate here but the caller shall be able to decide how to handle the level of detail, i.e. whether the first message shall be emitted or all. May modify model as a side effect.
      Parameters:
      model - the model to be resolved
      uri - the URI of the model to resolve (in order to find the closest model, may be null)
      inProgress - the model information objects of the models currently being processed at once (may be null)
      resolver - the import resolver (may be null to use a new default import resolver)
      transitiveLoading - with or without transitive loading (see ImportResolver)
      Returns:
      messages which occur during resolution, null or empty if none
    • resolve

      public M resolve(String modelName, IVersionRestriction restriction, URI baseURI, IRestrictionEvaluationContext evaluationContext) throws ModelManagementException
      Resolves the denoted model considering the given restrictions. This method uses a new default import resolver.
      Parameters:
      modelName - the name of the model
      restriction - the restriction (may be null if there is none)
      baseURI - the URI where to start the resolution at (may be an existing model)
      evaluationContext - the context for evaluating import restrictions (variable definitions... interpreted locally)
      Returns:
      the resolved model
      Throws:
      ModelManagementException - in case of resolution failures
    • load

      M load(ModelInfo<M> info, List<IMessage> messages)
      Loads the model related to info with a new default import resolver.
      Parameters:
      info - the model info to load the model for
      messages - the messages collected so far (modified as a side effect)
      Returns:
      the loaded model or null
    • load

      M load(ModelInfo<M> info, ImportResolver<M> resolver, List<IMessage> messages)
      Loads the model related to info.
      Parameters:
      info - the model info to load the model for
      resolver - the resolver to use (null for a new default import resolver)
      messages - the messages collected so far (modified as a side effect)
      Returns:
      the loaded model or null
    • notifyLoading

      private void notifyLoading(ModelInfo<M> info, boolean started)
      Handles the notification about model loading.
      Parameters:
      info - the information object to notify about
      started - true if loading started, false else
    • isLoading

      public boolean isLoading(ModelInfo<M> info)
      Returns whether loading the model for infois currently happening.
      Parameters:
      info - the information object to look for
      Returns:
      true if loading is currently in progress, false else
      See Also:
    • isLoading

      public boolean isLoading(URI location)
      Returns whether loading a model from location is currently happening.
      Parameters:
      location - the location to look for
      Returns:
      true if loading is currently in progress, false else
      See Also:
    • postLoadModel

      protected void postLoadModel(ModelInfo<M> info) throws IOException
      Additional code to be executed after a model was loaded.
      Parameters:
      info - the information object describing the model
      Throws:
      IOException - in case that loading fails - however, model loading will not fail
    • load

      public M load(ModelInfo<M> info) throws ModelManagementException
      Loads the specified model and resolves its imports. Be careful when calling this method from inside this class as it automatically resolves the imports. Loading an already loaded model does not cause physical reloading but returns the cached model contents.
      Parameters:
      info - the information object of the model to load
      Returns:
      the loaded model
      Throws:
      ModelManagementException - in case of any error during loading info
    • updateModelInformation

      public void updateModelInformation(File file, ProgressObserver observer) throws ModelManagementException
      Updates the model information in file.
      Parameters:
      file - the location folder to search
      observer - an optional progress observer (use ProgressObserver.NO_OBSERVER but not null in case that no observation is intended)
      Throws:
      ModelManagementException - in case that the available information may be come inconsistent due to this update
    • updateModelInformation

      public void updateModelInformation(ProgressObserver observer) throws ModelManagementException
      Updates the model information in all known locations.
      Parameters:
      observer - an optional progress observer (use ProgressObserver.NO_OBSERVER but not null in case that no observation is intended)
      Throws:
      ModelManagementException - in case that the available information may be come inconsistent due to this update
    • updateModelInformation

      private void updateModelInformation(ModelLocations.Location location, ModelInfoHolder<M> holder, ProgressObserver observer, ProgressObserver.ITask task, Set<ModelLocations.Location> done) throws ModelManagementException
      Updates the model information in the given location and the dependent locations.
      Parameters:
      location - the location to update the information for
      holder - the combined information and result collection instance
      observer - an optional progress observer (use ProgressObserver.NO_OBSERVER but not null in case that no observation is intended)
      task - the task to run in (may be null in order to start a new task)
      done - already processed locations (in order to avoid cycles)
      Throws:
      ModelManagementException - in case that the available information may be come inconsistent due to this update
    • updateForLoader

      void updateForLoader(IModelLoader<M> loader, ProgressObserver observer) throws ModelManagementException
      Registers a model loader and updates the model information provided by the loader.
      Parameters:
      loader - the model loader (must not be null)
      observer - an optional progress observer (use ProgressObserver.NO_OBSERVER but not null in case that no observation is intended)
      Throws:
      ModelManagementException - in case that the loader aims at loading inconsistent information
    • updateForLoader

      private void updateForLoader(ModelLocations.Location location, IModelLoader<M> loader, ModelInfoHolder<M> holder, ObservableTask task, Set<ModelLocations.Location> done)
      Updates location via loader.
      Parameters:
      location - the location to be updated
      loader - the specific loader to consider (may be null)
      holder - the combined information and result collection instance
      task - the task to be informed
      done - already processed locations in order to prevent loops
    • clearLocation

      void clearLocation(File file, ProgressObserver observer)
      Removes a file location, i.e. a location from where models can be loaded.
      Parameters:
      file - the file location (null is ignored)
      observer - an optional progress observer (use ProgressObserver.NO_OBSERVER but not null in case that no observation is intended)
    • getAvailable

      public List<VersionedModelInfos<M>> getAvailable(String name)
      Returns models available for a given model name.
      Parameters:
      name - the name to search for
      Returns:
      the available modelss or null
    • updateAvailableModels

      private String updateAvailableModels(ModelInfoHolder<M> holder)
      Updates the list of available models.
      Parameters:
      holder - the instance containing the results
      Returns:
      an empty string if the update was available, information about inconsistencies else
    • updateModelInformation

      private void updateModelInformation(File file, ModelInfoHolder<M> holder, ProgressObserver observer, ProgressObserver.ITask task) throws ModelManagementException
      Updates the model information in file considering known.
      Parameters:
      file - the location to search
      holder - the combined information and result collection instance
      observer - an optional progress observer (use ProgressObserver.NO_OBSERVER but not null in case that no observation is intended)
      task - the task to run in (may be null in order to start a new task)
      Throws:
      ModelManagementException - in case of model information inconsistencies
    • load

      private M load(ModelInfo<M> info, boolean force) throws ModelManagementException
      Loads the specified model and resolves its imports by calling resolveImports(M, java.net.URI, java.util.List<net.ssehub.easy.basics.modelManagement.ModelInfo<M>>). Be careful when calling this method from inside this class as it automatically resolves the imports. Loading an already loaded model does not cause physical reloading but returns the cached model contents.
      Parameters:
      info - the information object of the model to load
      force - load anyway
      Returns:
      the loaded model
      Throws:
      ModelManagementException - in case of any error during loading info
    • clear

      public void clear()
      Clears all loaded models, available models (availableModels()), and model locations (locations()). This method will not remove any IModelLoaders or ImportResolvers.

      Warning: Be careful with this method, as this may affect other parts of the tooling as the whole singleton will be cleaned up. This method is mainly designed for testing purpose.
    • clearModels

      public void clearModels()
      Calls clear() and clears all known models.
    • clearModel

      public void clearModel(M model)
      Clears model from the caches. Please handle with care.
      Parameters:
      model - the model to be cleared
    • clearModel

      public void clearModel(ModelInfo<M> info)
      Clears @link #clinfo (and the related model) from the caches. Please handle with care.
      Parameters:
      info - the info to be cleared
    • outdateAll

      public void outdateAll()
      Unresolves all models / forces reload.
    • isOutdated

      public boolean isOutdated(M model)
      Returns whether a model is outdated (will force a reload upon load(ModelInfo)).
      Parameters:
      model - the model to be tested (may be null)
      Returns:
      true if it is outdated, false else
    • isOutdated

      public boolean isOutdated(ModelInfo<M> info)
      Returns whether a model information is outdated (will force a reload upon load(ModelInfo)).
      Parameters:
      info - the object to be tested (may be null)
      Returns:
      true if it is outdated, false (also for info==null) else
    • setOutdated

      public void setOutdated(M model)
      Declears a model as outdated (will force a reload upon load(ModelInfo)).
      Parameters:
      model - the model to be tested (may be null)
    • setOutdated

      public void setOutdated(ModelInfo<M> info)
      Returns whether a model information is outdated.
      Parameters:
      info - the object to be tested (may be null)
    • getMatchingModelNames

      public List<String> getMatchingModelNames(String name)
      Returns the matching model names for a potential wildcard name.
      Parameters:
      name - the name to return the matches for
      Returns:
      if name is a wildcard name, all known matching names; else, name
    • addProjectFolder

      public static void addProjectFolder(File folder)
      Adds a project folder, which acts as common base folder for IVML, VIL and VTL models. Project folders support identifying/filtering related models. Relevant only if models from different projects are maintained together, e.g., in Eclipse.
      Parameters:
      folder - the folder, ignored if null
    • clearProjectFolders

      public static void clearProjectFolders()
      Clears all project folders.
    • isInProjectFolder

      public static boolean isInProjectFolder(URI projectUri, URI query)
      Returns whether query is in a project folder determined by projectUri.
      Parameters:
      projectUri - the URI determining the project
      query - the URI to query for
      Returns:
      true if query is in a project folder or there is no project folder, false if there are project folders but query is in none
    • removeProjectFolder

      public static void removeProjectFolder(File folder)
      Removes a project folder, which acts as common base folder for IVML, VIL and VTL models. Project folders support identifying/filtering related models. Relevant only if models from different projects are maintained together, e.g., in Eclipse.
      Parameters:
      folder - the folder, ignored if null