classdef (Abstract, Hidden) UpgradePlugin < handle
    %UPGRADEPLUGIN Abstract plugin class for a <misc> to Target Framework
    %upgrade tool. Downstream teams must provide an implementation of this
    %and register it with the Target Framework to make use of the
    %target.upgrade infrastructure.

%   Copyright 2019-2020 The MathWorks, Inc.
    
    properties (Constant)
        % Static registration of upgrade plug-ins. Consider micro services when
        % more components wish to register plug-ins (also via built-ins).
        RegisteredPlugins = containers.Map({'rtwTargetInfo',                            'sl_customization'}, ...
                                           {'RTW.TargetInfoFileTargetFrameworkUpgrade', 'SlCustomizationFileTargetFrameworkUpgrade'});
    end
    
    methods (Static)
        
        % Get the list of available up-grader parameters. This will be a
        % subset of the full list of registered up-grader parameters.
        function availableUpgraders = getAvailableUpgraderParams()
            
            availableUpgraders = {};
            registeredUpgraderParams = target.internal.UpgradePlugin.RegisteredPlugins.keys();
            registeredUpgraderClasses = target.internal.UpgradePlugin.RegisteredPlugins.values();
            for i = 1:length(registeredUpgraderClasses)
                
                upgraderParam = registeredUpgraderParams{i};
                if target.internal.UpgradePlugin.isaValid(registeredUpgraderClasses{i})
                    availableUpgraders{end+1} = upgraderParam; %#ok<AGROW>
                end
            end
        end      
        
        % Check if the specified MATLAB class is a valid target upgrade
        % plugin.
        function value = isaValid(classString)

            % Validate the class string. It needs to exist and derive from
            % target.internal.UpgradePlugin.
            pluginMetaData = meta.class.fromName(classString);    
            value = ~isempty(pluginMetaData) && ...
                    (contains('target.internal.UpgradePlugin', {pluginMetaData.SuperclassList.Name}) || ...
                    any(cellfun(@target.internal.UpgradePlugin.isaValid, {pluginMetaData.SuperclassList.Name})));
        end  
    end

    methods (Abstract)
             
        % Upgrade the specified artifacts to Target Framework objects. The
        % upgraded objects are returned from this method.
        upgradedObjects = upgrade(this, varargin);
    end    
end

