package org.myjaphoo.gui.scripting;
import groovy.lang.Closure;
import groovy.lang.DelegatesTo;
import groovy.lang.Script;
import io.vavr.collection.Seq;
import org.mlsoft.common.acitivity.ChannelManager;
import org.myjaphoo.CommonMovieFilter;
import org.myjaphoo.FilterResult;
import org.myjaphoo.MyjaphooController;
import org.myjaphoo.gui.MainApplicationController;
import org.myjaphoo.gui.action.scriptactions.BookmarkContextAction;
import org.myjaphoo.gui.action.scriptactions.CommonAction;
import org.myjaphoo.gui.action.scriptactions.DatabaseConfigurationContextAction;
import org.myjaphoo.gui.action.scriptactions.EntryContextAction;
import org.myjaphoo.gui.action.scriptactions.MetatagContextAction;
import org.myjaphoo.gui.action.scriptactions.MovieStructureNodeContextAction;
import org.myjaphoo.gui.action.scriptactions.SavedScriptContextAction;
import org.myjaphoo.gui.action.scriptactions.TagContextAction;
import org.myjaphoo.model.cache.EntityCacheActor;
import org.myjaphoo.model.cache.ImmutableMetaToken;
import org.myjaphoo.model.cache.ImmutableMovieEntry;
import org.myjaphoo.model.cache.ImmutableToken;
import org.myjaphoo.model.db.MetaToken;
import org.myjaphoo.model.db.MovieEntry;
import org.myjaphoo.model.db.SavedGroovyScript;
import org.myjaphoo.model.db.Token;
import org.myjaphoo.model.filterparser.ParserException;
import org.myjaphoo.model.filterparser.expr.JoinedDataRow;
import org.myjaphoo.model.filterparser.processing.ProcessingRequirementInformation;
import org.myjaphoo.plugin.Components;
import javax.xml.bind.JAXBException;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Base class for groovy scripts that contains all predefined commands.
* Theses commands are mainly the same that the CacheManager provides to list and manipulate the data.
*/
public abstract class MJScriptBaseClass extends Script {
private static final ProcessingRequirementInformation NOGROUPING = new ProcessingRequirementInformation() {
@Override
public boolean needsTagRelation() {
return false;
}
@Override
public boolean needsMetaTagRelation() {
return false;
}
};
private static String[] methHelpList = {
"help: prints all commands",
"movies(): returns all movies",
"tags(): return all tags",
"metaTags(): return all meta tags",
"print(): prints a object",
"assignMetaTokenToToken: assignes a meta tag to a tag",
"assignToken2MovieEntry: assigns a tag to a movie",
"createMetaToken: creates a new meta tag",
"createToken: creates a tag",
"editMetaToken: edit a meta tag",
"editMovie: edit a movie",
"editToken: edit a tag",
"moveMetaTokens: move a meta tag in its hierarchy",
"moveToken: move tag in its hierarchy",
"removeMetaToken: remove meta tag",
"removeToken: remove tag",
"unAssignMetaTokenFromToken: unassign meta tag from tag",
"unassignTokenFromMovies: unassign tag from movies",
"removeMovieEntry: remove movie entry",
"newMovie: create new movie",
"extractMovieInfos: extract movie infos",
"query: query movies by filter language",
};
/**
* to let call "help" without parenthesis...
*/
public String[] help = methHelpList;
public String[] help() {
return help;
}
/**
* Executes a filter language query and returns all matching entries.
*
* @param filterExpression
*
* @return
* @throws ParserException
*/
public Set<ImmutableMovieEntry> query(String filterExpression) throws ParserException {
FilterResult result = CommonMovieFilter.filter(
getMainController().createCommonFilterContext(),
filterExpression,
NOGROUPING
);
return condenseResult(result);
}
private Set<ImmutableMovieEntry> condenseResult(FilterResult result) {
HashSet<ImmutableMovieEntry> mSet = new HashSet<>();
for (JoinedDataRow jdr : result.filteredRows) {
mSet.add(jdr.getEntry());
}
return mSet;
}
/**
* Returns all movies as a list of MovieEntry objects from the cache.
* <p/>
* Returns all movies as a list of MovieEntry objects from the cache.
* <p/>
*
* @return all movie entries
*/
public Seq<ImmutableMovieEntry> movies() {
return getCacheActor().getImmutableModel().getEntryList();
}
/**
* Returns all tags as a list of Token objects from the cache.
*
* @return
*/
public Seq<ImmutableToken> tags() {
return getCacheActor().getImmutableModel().getTokenTree().getValues();
}
/**
* Returns all metatags as a list of MetaToken objects from the cache.
*/
public Seq<ImmutableMetaToken> metaTags() {
return getCacheActor().getImmutableModel().getMetaTokenTree().getValues();
}
public void print(ImmutableMovieEntry entry) {
System.out.printf("%s: %s\n", entry.getName(), entry.getCanonicalDir());
}
public void print(Token tag) {
System.out.printf("%s: %s\n", tag.getName(), tag.getDescription());
}
public void print(MetaToken mtag) {
System.out.printf("%s: %s\n", mtag.getName(), mtag.getDescription());
}
public void accumulateEvents() {
getCacheActor().accumulateEvents();
}
public void fireAllAccumulatedEvents() {
getCacheActor().fireAllAccumulatedEvents();
}
public void assignMetaTokenToToken(ImmutableMetaToken metaToken, ImmutableToken token) {
getCacheActor().assignMetaTokenToToken(metaToken, token);
}
public void assignToken2MovieEntry(ImmutableToken token, List<ImmutableMovieEntry> movies) {
getCacheActor().assignToken2MovieEntry(token, movies);
}
public void createMetaToken(MetaToken mt, ImmutableMetaToken parentToken) {
getCacheActor().createMetaToken(mt, parentToken);
}
public void createToken(Token token, ImmutableToken parentToken) {
getCacheActor().createToken(token, parentToken);
}
public void editMetaToken(MetaToken mt) {
getCacheActor().editMetaToken(mt);
}
public void editMovie(MovieEntry entry) throws Exception {
getCacheActor().editMovie(entry);
}
public void editToken(Token token) {
getCacheActor().editToken(token);
}
public void moveMetaTokens(ImmutableMetaToken tokenParent, ImmutableMetaToken token2Move) {
getCacheActor().moveMetaTokens(tokenParent, token2Move);
}
public void moveToken(ImmutableToken newParent, ImmutableToken token2Move) {
getCacheActor().moveToken(newParent, token2Move);
}
public void removeMetaToken(ImmutableMetaToken mt) {
getCacheActor().removeMetaToken(mt);
}
public void removeToken(final ImmutableToken currentSelectedToken) {
getCacheActor().removeToken(currentSelectedToken);
}
public void unAssignMetaTokenFromToken(ImmutableMetaToken currMetaToken, List<ImmutableToken> toks2Remove) {
getCacheActor().unAssignMetaTokenFromToken(currMetaToken, toks2Remove);
}
public void unassignTokenFromMovies(ImmutableToken token, final Collection<ImmutableMovieEntry> movies) {
getCacheActor().unassignTokenFromMovies(token, movies);
}
public void removeMovieEntry(ImmutableMovieEntry movieEntry) {
getCacheActor().removeMovieEntry(movieEntry);
}
public void newMovie(MovieEntry movieEntry) {
getCacheActor().newMovie(movieEntry);
}
public void extractMovieInfos(List<ImmutableMovieEntry> entries) throws IOException, JAXBException {
MyjaphooController controller = getController();
controller.extractMovieInfos(entries);
}
private MyjaphooController getController() {
MyjaphooController controller = (MyjaphooController) getBinding().getVariable("controller");
if (controller != null) {
return controller;
} else {
throw new RuntimeException("internal scripting error! no controller variable set!");
}
}
private MainApplicationController getMainController() {
return getController().getMainController();
}
private EntityCacheActor getCacheActor() {
return getController().getProject().cacheActor;
}
public List getSavedScripts() {
return getMainController().getScriptList();
}
public void editScript(SavedGroovyScript script) {
MyjaphooController controller = getController();
controller.updateScript(script);
}
public void addScript(SavedGroovyScript script) {
MyjaphooController controller = getController();
controller.addScript(script);
}
/**
* script example:
*
* movies().each { if (it.canonicalDir.startsWith("L:\\blubb")) {
it.setRating(org.myjaphoo.model.db.Rating.VERY_GOOD);
editMovie(it);
}}
*/
/**
* user defined Action definition for a tag context action
*
* @param key
* @param actionDef
*/
public void defTagContextAction(String key, @DelegatesTo(TagContextAction.class) Closure actionDef) {
Components.defTagContextAction(key, actionDef);
}
public void defMetaTagContextAction(String key, @DelegatesTo(MetatagContextAction.class) Closure actionDef) {
Components.defMetaTagContextAction(key, actionDef);
}
public void defMovieEntryContextAction(String key, @DelegatesTo(EntryContextAction.class) Closure actionDef) {
Components.defMovieEntryContextAction(key, actionDef);
}
public void defBookMarkContextAction(String key, @DelegatesTo(BookmarkContextAction.class) Closure actionDef) {
Components.defBookMarkContextAction(key, actionDef);
}
public void defSavedScriptContextAction(
String key, @DelegatesTo(SavedScriptContextAction.class) Closure actionDef
) {
Components.defSavedScriptContextAction(key, actionDef);
}
public void defDatabaseConfigurationContextAction(
String key, @DelegatesTo(DatabaseConfigurationContextAction.class) Closure actionDef
) {
Components.defDatabaseConfigurationContextAction(key, actionDef);
}
public void defMovieStructureNodeContextAction(
String key, @DelegatesTo(MovieStructureNodeContextAction.class) Closure actionDef
) {
Components.defMovieStructureNodeContextAction(key, actionDef);
}
public void defCommonAction(String key, @DelegatesTo(CommonAction.class) Closure actionDef) {
Components.defCommonAction(key, actionDef);
}
/**
* executes a closure with a channel to display progress and messages within scripts.
* The channel is an argument for the closure
*
* @param activityName the activity name for the new channel
* @param steps the expected steps for the progress
* @param closure the closure to execute
*/
public void withProgress(String activityName, int steps, Closure closure) {
ChannelManager.withProgress(activityName, steps, channel -> closure.call(channel));
}
}