package cz.cuni.mff.d3s.been.web.pages.task; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.tapestry5.Block; import org.apache.tapestry5.annotations.Component; import org.apache.tapestry5.annotations.Property; import org.apache.tapestry5.annotations.SessionState; import org.apache.tapestry5.corelib.components.Form; import org.apache.tapestry5.ioc.annotations.Inject; import org.apache.tapestry5.services.ajax.AjaxResponseRenderer; import org.apache.tapestry5.services.ajax.JavaScriptCallback; import org.apache.tapestry5.services.javascript.JavaScriptSupport; import org.got5.tapestry5.jquery.components.Dialog; import cz.cuni.mff.d3s.been.api.BeenApiException; import cz.cuni.mff.d3s.been.bpk.BpkIdentifier; import cz.cuni.mff.d3s.been.core.task.*; import cz.cuni.mff.d3s.been.web.components.Layout; import cz.cuni.mff.d3s.been.web.model.ConversationHolder; import cz.cuni.mff.d3s.been.web.model.KeyValuePair; import cz.cuni.mff.d3s.been.web.model.TaskDescriptorInitializer; import cz.cuni.mff.d3s.been.web.pages.Index; import cz.cuni.mff.d3s.been.web.pages.Overview; import cz.cuni.mff.d3s.been.web.pages.Page; /** * @author Kuba Brecka */ @Page.Navigation(section = Layout.Section.TASK_SUBMIT) public class SubmitTaskContextDescriptor extends Page { // ----------------------------- // KEYS USED IN CONVERSATION HOLDER // ----------------------------- private static final String KEY_TASK_CONTEXT_DESCRIPTOR = "task_context_descriptor"; private static final String KEY_BPK_IDENTIFIER = "bpk_identifier"; private static final String KEY_TASK_CONTEXT_TEMPLATE_TASKS_DESCRIPTORS = "task_context_template_tasks_descriptors"; private static final String KEY_TASK_CONTEXT_TEMPLATE_TASKS_ARGS = "task_context_template_tasks_args"; private static final String KEY_TASK_CONTEXT_TEMPLATE_TASKS_JAVA_OPTS = "task_context_template_tasks_java_opts"; private static final String KEY_TASK_CONTEXT_TASKS_DESCRIPTORS = "task_context_tasks_descriptors"; private static final String KEY_TASK_CONTEXT_TASKS_ARGS = "task_context_tasks_args"; private static final String KEY_TASK_CONTEXT_TASKS_JAVA_OPTS = "task_context_tasks_java_opts"; private static final String KEY_LOOP_INDEX = "loop_index"; // ----------------------------- // CONVERSATION POLICY // ----------------------------- @SessionState(create = true) private ConversationHolder<Map<String, Object>> conversationHolder; /** * Task context descriptor loaded in onActivate() method */ @Property TaskContextDescriptor taskContextDescriptor; // ----------------------------- // TAPESTRY TEMPLATE FIELDS // ----------------------------- @Property boolean save; @Property String saveName; @Property BpkIdentifier bpkIdentifier; /** * Identifier of current conversation */ private String conversationId; /** * Injected form component for task submitting. */ @Component @SuppressWarnings("unused") private Form submitTaskContextForm; /** * loop index used in loops in template */ @Property @SuppressWarnings("unused") private Integer loopIndex; /** * List of lists of task arguments (represented by KeyValuePairs) for task * descriptor templates specified in task context descriptor */ @Property @SuppressWarnings("unused") private List<List<KeyValuePair>> taskTemplatesArgs; /** * List of lists of task java options (represented by KeyValuePairs) for task * descriptor templates specified in task context descriptor */ @Property @SuppressWarnings("unused") private List<List<KeyValuePair>> taskTemplatesJavaOpts; /** * List of task descriptor templates specified in task context descriptor. */ @Property @SuppressWarnings("unused") private List<TaskDescriptor> taskTemplatesDescriptors; /** * List of lists of task arguments (represented by KeyValuePairs) for task * descriptors specified in task context descriptor */ @Property @SuppressWarnings("unused") private List<List<KeyValuePair>> tasksArgs; /** * List of lists of task java options (represented by KeyValuePairs) for task * descriptors specified in task context descriptor */ @Property @SuppressWarnings("unused") private List<List<KeyValuePair>> tasksJavaOpts; /** * List of task descriptors specified in task context descriptor. */ @Property @SuppressWarnings("unused") private List<TaskDescriptor> tasksDescriptors; // ----------------------------- // ACTIVATION AND PASSIVATION // ----------------------------- /** * Is set to true if page has been already activated */ private boolean activated; /** * Activate page with context of conversation with given identifier. * * @param conversationId * @return null if page has been already activated or page has been correctly * activated. Redirect to {@link cz.cuni.mff.d3s.been.web.pages.Index} * page otherwise. */ Object onActivate(String conversationId) { // we have to check if page has been already activated, because we don't want // to override context of already activated pages if (activated) { return null; } if (!conversationHolder.contains(conversationId)) { // FIXME .. inform user in proper way? return Index.class; } else { taskContextDescriptor = (TaskContextDescriptor) conversationHolder.get(conversationId).get( KEY_TASK_CONTEXT_DESCRIPTOR); bpkIdentifier = (BpkIdentifier) conversationHolder.get(conversationId).get(KEY_BPK_IDENTIFIER); taskTemplatesArgs = (List<List<KeyValuePair>>) conversationHolder.get(conversationId).get( KEY_TASK_CONTEXT_TEMPLATE_TASKS_ARGS); taskTemplatesJavaOpts = (List<List<KeyValuePair>>) conversationHolder.get(conversationId).get( KEY_TASK_CONTEXT_TEMPLATE_TASKS_JAVA_OPTS); taskTemplatesDescriptors = (List<TaskDescriptor>) conversationHolder.get(conversationId).get( KEY_TASK_CONTEXT_TEMPLATE_TASKS_DESCRIPTORS); tasksArgs = (List<List<KeyValuePair>>) conversationHolder.get(conversationId).get(KEY_TASK_CONTEXT_TASKS_ARGS); tasksJavaOpts = (List<List<KeyValuePair>>) conversationHolder.get(conversationId).get( KEY_TASK_CONTEXT_TASKS_JAVA_OPTS); tasksDescriptors = (List<TaskDescriptor>) conversationHolder.get(conversationId).get( KEY_TASK_CONTEXT_TASKS_DESCRIPTORS); loopIndex = (Integer) conversationHolder.get(conversationId).get(KEY_LOOP_INDEX); /* if (!taskContextDescriptor.isSetTask()) { // FIXME .... task descriptor without tasks is should be avoided... } */ this.conversationId = conversationId; activated = true; return null; } } /** * Setup method. Loads task context descriptor (corresponding to given * parameters) using been api and sets this descriptor as editable property * for this component. * * @param groupId * group id of {@link BpkIdentifier} to which the underlying * {@link TaskDescriptor} belows * @param bpkId * bpk id of {@link BpkIdentifier} to which the underlying * {@link TaskDescriptor} belows * @param version * version id of {@link BpkIdentifier} to which the underlying * {@link TaskDescriptor} belows * @param descriptorName * name of concrete {@link TaskDescriptor} for {@link BpkIdentifier} * identified by previous parameters * @return null (see tapestry page documentation about return values from * onActivate and onPassivate methods) */ @SuppressWarnings("unused") Object onActivate(String groupId, String bpkId, String version, String descriptorName) throws BeenApiException { // load correct task context descriptor bpkIdentifier = new BpkIdentifier().withGroupId(groupId).withBpkId(bpkId).withVersion(version); this.taskContextDescriptor = getApi().getTaskContextDescriptor(bpkIdentifier, descriptorName); if (this.taskContextDescriptor == null) { this.taskContextDescriptor = getApi().getNamedContextDescriptorsForBpk(bpkIdentifier).get(descriptorName); } HashMap<String, Object> conversationArgs = new HashMap<String, Object>(); conversationArgs.put(KEY_TASK_CONTEXT_DESCRIPTOR, taskContextDescriptor); conversationArgs.put(KEY_BPK_IDENTIFIER, bpkIdentifier); this.conversationId = conversationHolder.set(conversationArgs); if (!taskContextDescriptor.isSetProperties()) { taskContextDescriptor.setProperties(new ObjectFactory().createProperties()); } taskTemplatesArgs = new ArrayList<>(); taskTemplatesJavaOpts = new ArrayList<>(); taskTemplatesDescriptors = new ArrayList<>(); tasksArgs = new ArrayList<>(); tasksJavaOpts = new ArrayList<>(); tasksDescriptors = new ArrayList<>(); if (!taskContextDescriptor.isSetTemplates()) { taskContextDescriptor.setTemplates(new ObjectFactory().createTemplates()); } for (Template template : taskContextDescriptor.getTemplates().getTemplate()) { List<KeyValuePair> args = new ArrayList<>(); List<KeyValuePair> javaOpts = new ArrayList<>(); TaskDescriptorInitializer.initialize(template.getTaskDescriptor(), args, javaOpts); taskTemplatesArgs.add(args); taskTemplatesJavaOpts.add(javaOpts); taskTemplatesDescriptors.add(template.getTaskDescriptor()); } for (Task task : taskContextDescriptor.getTask()) { if (task.getDescriptor().isSetTaskDescriptor()) { List<KeyValuePair> args = new ArrayList<>(); List<KeyValuePair> javaOpts = new ArrayList<>(); TaskDescriptorInitializer.initialize(task.getDescriptor().getTaskDescriptor(), args, javaOpts); tasksArgs.add(args); tasksJavaOpts.add(javaOpts); tasksDescriptors.add(task.getDescriptor().getTaskDescriptor()); } else { taskTemplatesArgs.add(null); taskTemplatesJavaOpts.add(null); taskTemplatesDescriptors.add(null); } } conversationArgs.put(KEY_TASK_CONTEXT_TEMPLATE_TASKS_DESCRIPTORS, taskTemplatesDescriptors); conversationArgs.put(KEY_TASK_CONTEXT_TEMPLATE_TASKS_ARGS, taskTemplatesArgs); conversationArgs.put(KEY_TASK_CONTEXT_TEMPLATE_TASKS_JAVA_OPTS, taskTemplatesJavaOpts); conversationArgs.put(KEY_TASK_CONTEXT_TASKS_DESCRIPTORS, tasksDescriptors); conversationArgs.put(KEY_TASK_CONTEXT_TASKS_ARGS, tasksArgs); conversationArgs.put(KEY_TASK_CONTEXT_TASKS_JAVA_OPTS, tasksJavaOpts); activated = true; return null; } /** * @return conversationId as passivate parameter (used on next onActivate * parameter). See tapestry documentation to get more information * about expected return values from onActivate and onPassivate * methods */ Object onPassivate() { return conversationId; } // ----------------------------- // FORM HANDLING // ----------------------------- /** * This handler is called when users click on form SUBMIT button. Submits task * to BEEN cluster using {@link cz.cuni.mff.d3s.been.api.BeenApi} * * @return redirect to {@link Overview} page */ @SuppressWarnings("unused") Object onSubmitFromSubmitTaskContextForm() throws BeenApiException { if (save) { getApi().saveNamedContextDescriptor(taskContextDescriptor, saveName, bpkIdentifier); } getApi().submitTaskContext(taskContextDescriptor); return Overview.class; } @Property private TaskDescriptor taskDescriptor; @Property private List<KeyValuePair> args; @Property private List<KeyValuePair> javaOpts; @Inject private Block taskTemplateDialogBlock; @Inject private Block taskDescriptorDialogBlock; @Component private Dialog dialog; Object onActionFromTaskTemplateDialogLink(Integer loopIndex) { displayModalDialog(loopIndex); return taskTemplateDialogBlock; } Object onActionFromTaskDescriptorDialogLink(Integer loopIndex) { displayModalDialog(loopIndex); return taskDescriptorDialogBlock; } private void displayModalDialog(Integer loopIndex) { this.loopIndex = loopIndex; conversationHolder.get(conversationId).put(KEY_LOOP_INDEX, loopIndex); ajaxResponseRenderer.addCallback(new JavaScriptCallback() { @Override public void run(JavaScriptSupport javascriptSupport) { javascriptSupport.addScript( "$('#%s').dialog('option', 'width', ($(window).width() / 100) * 95);", dialog.getClientId()); } }); } void onSubmitFromTaskTemplateForm(int loopIndex) { TaskDescriptor taskDescriptor = taskTemplatesDescriptors.get(loopIndex); List<KeyValuePair> args = taskTemplatesArgs.get(loopIndex); List<KeyValuePair> opts = taskTemplatesJavaOpts.get(loopIndex); args.remove(null); taskDescriptor.getArguments().getArgument().clear(); taskDescriptor.getJava().getJavaOptions().getJavaOption().clear(); for (KeyValuePair arg : args) { if (arg.value != null) { taskDescriptor.getArguments().getArgument().add(arg.value); } } for (KeyValuePair opt : opts) { if (opt.value != null) { taskDescriptor.getJava().getJavaOptions().getJavaOption().add(opt.value); } } ajaxResponseRenderer.addCallback(new JavaScriptCallback() { @Override public void run(JavaScriptSupport javascriptSupport) { javascriptSupport.addScript("$('#%s').dialog('close');", dialog.getClientId()); } }); } void onSubmitFromTaskDescriptorForm(int loopIndex) { TaskDescriptor taskDescriptor = tasksDescriptors.get(loopIndex); List<KeyValuePair> args = tasksArgs.get(loopIndex); List<KeyValuePair> opts = tasksJavaOpts.get(loopIndex); args.remove(null); taskDescriptor.getArguments().getArgument().clear(); taskDescriptor.getJava().getJavaOptions().getJavaOption().clear(); for (KeyValuePair arg : args) { if (arg.value != null) { taskDescriptor.getArguments().getArgument().add(arg.value); } } for (KeyValuePair opt : opts) { if (opt.value != null) { taskDescriptor.getJava().getJavaOptions().getJavaOption().add(opt.value); } } ajaxResponseRenderer.addCallback(new JavaScriptCallback() { @Override public void run(JavaScriptSupport javascriptSupport) { javascriptSupport.addScript("$('#%s').dialog('close');", dialog.getClientId()); } }); } @Inject private AjaxResponseRenderer ajaxResponseRenderer; }