Skip to content
Snippets Groups Projects
Select Git revision
  • 3cd3865b509e928e17d8a5a58841a1996532390b
  • master default protected
  • exec_auto_adjust_trace
  • let_variables
  • v1.4.1
  • v1.4.0
  • v1.3.0
  • v1.2.0
  • v1.1.0
  • v1.0.0
10 results

help.ipynb

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    LoadFileCommand.java 5.59 KiB
    package de.prob2.jupyter.commands;
    
    import java.io.IOException;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    import java.util.Collections;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.stream.Collectors;
    import java.util.stream.Stream;
    
    import com.google.inject.Inject;
    import com.google.inject.Injector;
    
    import de.prob.scripting.CSPFactory;
    import de.prob.scripting.ClassicalBFactory;
    import de.prob.scripting.EventBFactory;
    import de.prob.scripting.ModelFactory;
    import de.prob.scripting.ModelTranslationError;
    import de.prob.scripting.TLAFactory;
    import de.prob.statespace.AnimationSelector;
    import de.prob.statespace.Trace;
    
    import de.prob2.jupyter.UserErrorException;
    
    import io.github.spencerpark.jupyter.kernel.ReplacementOptions;
    import io.github.spencerpark.jupyter.kernel.display.DisplayData;
    
    import org.jetbrains.annotations.NotNull;
    import org.jetbrains.annotations.Nullable;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public final class LoadFileCommand implements Command {
    	private static final @NotNull Logger LOGGER = LoggerFactory.getLogger(LoadFileCommand.class);
    	
    	private static final @NotNull Map<@NotNull String, @NotNull Class<? extends ModelFactory<?>>> EXTENSION_TO_FACTORY_MAP;
    	static {
    		final Map<String, Class<? extends ModelFactory<?>>> extensionToFactoryMap = new HashMap<>();
    		extensionToFactoryMap.put("mch", ClassicalBFactory.class);
    		extensionToFactoryMap.put("ref", ClassicalBFactory.class);
    		extensionToFactoryMap.put("imp", ClassicalBFactory.class);
    		extensionToFactoryMap.put("eventb", EventBFactory.class);
    		extensionToFactoryMap.put("bum", EventBFactory.class);
    		extensionToFactoryMap.put("buc", EventBFactory.class);
    		extensionToFactoryMap.put("csp", CSPFactory.class);
    		extensionToFactoryMap.put("cspm", CSPFactory.class);
    		extensionToFactoryMap.put("tla", TLAFactory.class);
    		// FIXME Not currently possible, because RulesModelFactory does not implement the ModelFactory interface
    		//extensionToFactoryMap.put("rmch", RulesModelFactory.class);
    		EXTENSION_TO_FACTORY_MAP = Collections.unmodifiableMap(extensionToFactoryMap);
    	}
    	
    	private final @NotNull Injector injector;
    	private final @NotNull AnimationSelector animationSelector;
    	
    	@Inject
    	private LoadFileCommand(final @NotNull Injector injector, final @NotNull AnimationSelector animationSelector) {
    		super();
    		
    		this.injector = injector;
    		this.animationSelector = animationSelector;
    	}
    	
    	@Override
    	public @NotNull String getSyntax() {
    		return ":load FILENAME [PREF=VALUE ...]";
    	}
    	
    	@Override
    	public @NotNull String getShortHelp() {
    		return "Load the machine from the given path.";
    	}
    	
    	@Override
    	public @NotNull String getHelpBody() {
    		return "The path is relative to the kernel's current directory (i. e. the directory in which the notebook is located).\n\n"
    			+ "Any number of preference assignments may be included after the file path. Preferences can also be changed on a loaded machine using the `:pref` command, however certain preferences do not take full effect when set using `:pref` and must be set when the machine is loaded.";
    	}
    	
    	@Override
    	public @NotNull DisplayData run(final @NotNull String argString) {
    		final List<String> args = CommandUtils.splitArgs(argString);
    		if (args.isEmpty()) {
    			throw new UserErrorException("Missing machine file name");
    		}
    		
    		final String fileName = args.get(0);
    		final int dotIndex = fileName.lastIndexOf('.');
    		if (dotIndex == -1) {
    			throw new UserErrorException("File has no extension, unable to determine language: " + fileName);
    		}
    		final String extension = fileName.substring(dotIndex+1);
    		if (!EXTENSION_TO_FACTORY_MAP.containsKey(extension)) {
    			throw new UserErrorException("Unsupported file type: ." + extension);
    		}
    		final Map<String, String> preferences = CommandUtils.parsePreferences(args.subList(1, args.size()));
    		
    		try {
    			final ModelFactory<?> factory = this.injector.getInstance(EXTENSION_TO_FACTORY_MAP.get(extension));
    			this.animationSelector.changeCurrentAnimation(new Trace(factory.extract(fileName).load(preferences)));
    		} catch (IOException | ModelTranslationError e) {
    			throw new RuntimeException(e);
    		}
    		return new DisplayData("Loaded machine: " + this.animationSelector.getCurrentTrace().getStateSpace().getMainComponent());
    	}
    	
    	@Override
    	public @Nullable DisplayData inspect(final @NotNull String argString, final int at) {
    		return CommandUtils.inspectArgs(
    			argString, at,
    			(filename, at0) -> null,
    			CommandUtils.preferencesInspector(this.animationSelector.getCurrentTrace())
    		);
    	}
    	
    	@Override
    	public @Nullable ReplacementOptions complete(final @NotNull String argString, final int at) {
    		return CommandUtils.completeArgs(
    			argString, at,
    			(filename, at0) -> {
    				final String prefix = filename.substring(0, at0);
    				final List<String> fileNames;
    				try (final Stream<Path> list = Files.list(Paths.get(""))) {
    					fileNames = list
    						.map(Path::getFileName)
    						.map(Object::toString)
    						.filter(s -> s.startsWith(prefix))
    						.filter(s -> {
    							final int dotIndex = s.lastIndexOf('.');
    							if (dotIndex == -1) {
    								return false;
    							}
    							final String extension = s.substring(dotIndex+1);
    							return EXTENSION_TO_FACTORY_MAP.containsKey(extension);
    						})
    						.collect(Collectors.toList());
    				} catch (final IOException e) {
    					LOGGER.warn("Could not list contents of the current directory, cannot provide file name completions for :load", e);
    					return null;
    				}
    				return new ReplacementOptions(fileNames, 0, filename.length());
    			},
    			CommandUtils.preferencesCompleter(this.animationSelector.getCurrentTrace())
    		);
    	}
    }