/*******************************************************************************
* Copyright (c) 2014 Open Door Logistics (www.opendoorlogistics.com)
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v3
* which accompanies this distribution, and is available at http://www.gnu.org/licenses/lgpl.txt
******************************************************************************/
package com.opendoorlogistics.studio.scripts.editor;
import java.awt.BorderLayout;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import java.util.prefs.Preferences;
import javax.swing.Icon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import javax.swing.event.InternalFrameEvent;
import javax.swing.event.InternalFrameListener;
import javax.swing.filechooser.FileNameExtensionFilter;
import org.apache.commons.io.FilenameUtils;
import com.opendoorlogistics.api.ExecutionReport;
import com.opendoorlogistics.api.ODLApi;
import com.opendoorlogistics.api.components.ComponentConfigurationEditorAPI;
import com.opendoorlogistics.api.components.ODLComponent;
import com.opendoorlogistics.api.io.ImportFileType;
import com.opendoorlogistics.api.scripts.ScriptAdapter;
import com.opendoorlogistics.api.scripts.ScriptAdapter.ScriptAdapterType;
import com.opendoorlogistics.api.scripts.ScriptAdapterTable;
import com.opendoorlogistics.api.tables.ODLColumnType;
import com.opendoorlogistics.api.tables.ODLDatastore;
import com.opendoorlogistics.api.tables.ODLListener;
import com.opendoorlogistics.api.tables.ODLTableDefinition;
import com.opendoorlogistics.core.AppConstants;
import com.opendoorlogistics.core.api.impl.scripts.ScriptOptionImpl;
import com.opendoorlogistics.core.components.ODLGlobalComponents;
import com.opendoorlogistics.core.scripts.ScriptConstants;
import com.opendoorlogistics.core.scripts.elements.AdaptedTableConfig;
import com.opendoorlogistics.core.scripts.elements.AdapterColumnConfig.SortField;
import com.opendoorlogistics.core.scripts.elements.AdapterConfig;
import com.opendoorlogistics.core.scripts.elements.InstructionConfig;
import com.opendoorlogistics.core.scripts.elements.Option;
import com.opendoorlogistics.core.scripts.elements.Script;
import com.opendoorlogistics.core.scripts.execution.ExecutionReportImpl;
import com.opendoorlogistics.core.scripts.execution.OptionsSubpath;
import com.opendoorlogistics.core.scripts.formulae.tables.EmptyTable;
import com.opendoorlogistics.core.scripts.io.ScriptIO;
import com.opendoorlogistics.core.scripts.utils.ScriptFieldsParser;
import com.opendoorlogistics.core.scripts.utils.ScriptFieldsParser.SourcedDatastore;
import com.opendoorlogistics.core.scripts.utils.ScriptFieldsParser.SourcedTable;
import com.opendoorlogistics.core.scripts.utils.ScriptUtils;
import com.opendoorlogistics.core.scripts.utils.ScriptUtils.OutputWindowSyncLevel;
import com.opendoorlogistics.core.scripts.utils.TableId;
import com.opendoorlogistics.core.utils.strings.Strings;
import com.opendoorlogistics.studio.PreferencesManager;
import com.opendoorlogistics.studio.internalframes.ODLInternalFrame;
import com.opendoorlogistics.studio.scripts.editor.adapters.QueryAvailableData;
import com.opendoorlogistics.studio.scripts.execution.ScriptUIManager;
import com.opendoorlogistics.studio.utils.RunProcessWithExecReport;
import com.opendoorlogistics.studio.utils.RunProcessWithExecReport.RunMe;
import com.opendoorlogistics.utils.ui.SimpleAction;
import com.opendoorlogistics.utils.ui.SimpleActionConfig;
public abstract class ScriptEditor extends ODLInternalFrame {
protected final Script script;
protected final ScriptUIManager runner;
//private final List<SimpleAction> actions = new ArrayList<>();
protected final JPanel contentPane;
private ScriptEditorToolbar toolBar;
protected final ODLApi api;
private final ODLListener dsStructureChangedListener = new ODLListener() {
@Override
public void tableChanged(int tableId, int firstRow, int lastRow) {
// TODO Auto-generated method stub
}
@Override
public ODLListenerType getType() {
return ODLListenerType.DATASTORE_STRUCTURE_CHANGED;
}
@Override
public void datastoreStructureChanged() {
ScriptEditor.this.datastoreStructureChanged();
}
};
protected File file;
private String lastOutputXML;
// protected final JCheckBox bottomToolbarSyncCheckbox;
protected ScriptEditorToolbar createToolbar(){
ScriptEditorToolbar ret = new ScriptEditorToolbar(true,script.isSynchronised(), true,script.isLaunchMultiple()) {
@Override
protected void syncBoxChanged(boolean isSelected) {
script.setSynchronised(isSelected);
}
@Override
protected boolean isSyncBoxEnabled() {
ArrayList<Option> path = new ArrayList<>();
path.add(script);
return ScriptUtils.getOutputWindowSyncLevel(api,path)==OutputWindowSyncLevel.MANUAL;
// // synchronised checkbox only enabled if one or more components can be synchronised
// for (InstructionConfig instruction : script.getInstructions()) {
// ODLComponent component = ScriptUtils.getComponent(instruction);
// if (component != null && (component.getFlags(api, instruction.getExecutionMode()) & ODLComponent.FLAG_OUTPUT_WINDOWS_CAN_BE_SYNCHRONISED) == ODLComponent.FLAG_OUTPUT_WINDOWS_CAN_BE_SYNCHRONISED) {
// return true;
// }
// }
// return false;
}
@Override
protected void toggleView() {
// TODO Auto-generated method stub
}
@Override
protected boolean isToggleViewEnabled() {
return false;
}
@Override
protected void launchMultipleChanged(boolean isLaunchMultiple) {
script.setLaunchMultiple(isLaunchMultiple);
}
};
ret.addAction(createSaveScriptAction());
ret.addAction(createSaveScriptAsAction());
ret.addAction(createCopyAction());
ret.addAction(createTestCompileScriptAction());
ret.addAction(createRunScriptAction());
return ret;
}
/**
* Create the frame.
*/
public ScriptEditor(ODLApi api, Script script, File file, final ScriptUIManager runner) {
super(file != null ? file.getAbsolutePath() : null);
this.script = script;
this.file = file;
this.runner = runner;
this.api = api;
Icon icon = ScriptIcons.getIcon(api,script);
if (icon != null) {
setFrameIcon(icon);
}
// save the current XML of the script
lastOutputXML = getXML();
setSize(DisplayConstants.LEVEL1_SIZE);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(new BorderLayout());
// create toolbar
reinitialiseToolbar();
// JCheckBox syncBox = createSyncCheckbox(script);
// bottomToolbarSyncCheckbox = syncBox;
// if(bottomToolbarSyncCheckbox!=null){
// bottomToolbarSyncCheckbox.addActionListener(new ActionListener() {
//
// @Override
// public void actionPerformed(ActionEvent e) {
// syncCheckboxChanged();
// }
// });
// toolBar.add(bottomToolbarSyncCheckbox);
// }
// toolBar.addSeparator();
// fillToolbar(toolBar, actions);
// override close operation
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
addInternalFrameListener(new InternalFrameListener() {
@Override
public void internalFrameOpened(InternalFrameEvent e) {
// TODO Auto-generated method stub
}
@Override
public void internalFrameIconified(InternalFrameEvent e) {
// TODO Auto-generated method stub
}
@Override
public void internalFrameDeiconified(InternalFrameEvent e) {
// TODO Auto-generated method stub
}
@Override
public void internalFrameDeactivated(InternalFrameEvent e) {
// TODO Auto-generated method stub
}
@Override
public void internalFrameClosing(InternalFrameEvent e) {
disposeWithSavePrompt();
}
@Override
public void internalFrameClosed(InternalFrameEvent e) {
// TODO Auto-generated method stub
}
@Override
public void internalFrameActivated(InternalFrameEvent e) {
// TODO Auto-generated method stub
}
});
if (runner != null) {
runner.registerDatastoreStructureChangedListener(dsStructureChangedListener);
}
toolBar.updateEnabled();
updateTitle();
}
protected void reinitialiseToolbar(){
if(toolBar!=null){
contentPane.remove(toolBar);
}
toolBar = createToolbar();
contentPane.add(toolBar,BorderLayout.SOUTH);
toolBar.updateEnabled();
}
// protected void syncCheckboxChanged(){
// ScriptEditor.this.script.setSynchronised(bottomToolbarSyncCheckbox.isSelected());
// }
// protected void fillToolbar(JToolBar toolBar, List<SimpleAction> actions) {
// for (SimpleAction action : actions) {
// toolBar.add(action);
// }
// }
// protected void createMainActions(List<SimpleAction> actions) {
// actions.add(createSaveScriptAction());
// actions.add(createSaveScriptAsAction());
// actions.add(createCopyAction());
// actions.add(createTestCompileScriptAction());
// actions.add(createRunScriptAction());
// }
protected SimpleAction createRunScriptAction() {
return new SimpleAction(SimpleActionConfig.runScript) {
@Override
public void actionPerformed(ActionEvent e) {
validateScriptData();
executeScript();
}
@Override
public void updateEnabledState() {
setEnabled(isRunScriptAllowed());
}
};
}
protected boolean isRunScriptAllowed() {
return true;
}
protected SimpleAction createTestCompileScriptAction() {
return new SimpleAction(SimpleActionConfig.testCompileScript) {
@Override
public void actionPerformed(ActionEvent e) {
validateScriptData();
testCompile(runner);
}
};
}
protected SimpleAction createSaveScriptAsAction() {
return new SimpleAction("Save as", "Save script as", "document-save-as-2-16x16.png") {
@Override
public void actionPerformed(ActionEvent e) {
validateScriptData();
JFileChooser chooser = new JFileChooser();
chooser.setFileFilter(new FileNameExtensionFilter(AppConstants.ORG_NAME + " script (" + ScriptConstants.FILE_EXT.toLowerCase() + ")", ScriptConstants.FILE_EXT));
File file = ScriptEditor.this.file;
if (file == null) {
file = createDefaultFilename();
}
if (file == null) {
file = PreferencesManager.getSingleton().getScriptsDirectory();
}
// ensure absolute
if (file != null) {
file = file.getAbsoluteFile();
}
// ensure have filename
if (file != null && file.isDirectory()) {
file = new File(file, createDefaultPathlessFilename());
}
if (file != null) {
chooser.setCurrentDirectory(file.getParentFile());
chooser.setSelectedFile(file);
}
if (chooser.showSaveDialog(ScriptEditor.this) == JFileChooser.APPROVE_OPTION) {
save(chooser.getSelectedFile());
}
}
};
}
// ret.add(new MyAction(SimpleActionConfig.copyItem.setItemName("script"),false) {
//
// @Override
// public void actionPerformed(ActionEvent e) {
// listControl.onAction("copy");
// }
//
// });
protected SimpleAction createCopyAction() {
return new SimpleAction("Copy", "Copy script to clipboard", "edit-copy-7.png") {
@Override
public void actionPerformed(ActionEvent e) {
StringSelection stringSelection = new StringSelection(getXML());
Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard();
clpbrd.setContents(stringSelection, null);
}
};
}
protected SimpleAction createSaveScriptAction() {
return new SimpleAction("Save", "Save script", "document-save-2-16x16.png") {
@Override
public void actionPerformed(ActionEvent e) {
validateScriptData();
save(ScriptEditor.this.file);
}
@Override
public void updateEnabledState() {
setEnabled(ScriptEditor.this.file != null && ScriptEditor.this.file.isFile());
}
};
}
@Override
public void setTitle(String title) {
super.setTitle(title);
}
protected void updateTitle() {
String title = ""; // script.getScriptType().getDisplayName() + " -";
String name = ScriptUtils.getDefaultScriptName(script);
if (Strings.isEmpty(name) == false) {
title += name + " - ";
}
title += "script editor - ";
if (file != null && file.isFile()) {
title += file.getAbsolutePath();
} else {
title += "untitled";
}
setTitle(title);
toolBar.updateEnabled();
}
private void save(File saveTo) {
try {
// append extension if needed
if (Strings.equalsStd(FilenameUtils.getExtension(saveTo.getAbsolutePath()), ScriptConstants.FILE_EXT) == false) {
saveTo = new File(saveTo.getAbsolutePath() + "." + ScriptConstants.FILE_EXT);
}
String str = getXML();
Strings.writeToFile(str, saveTo);
file = saveTo;
lastOutputXML = str;
// set the uuid based on the file
script.setUuid(ScriptIO.getScriptUUID(file));
} catch (Throwable e) {
showMessage("Error saving script file. Do you have write access to the directory?");
}
updateTitle();
toolBar.updateEnabled();
}
protected String getXML() {
return ScriptIO.instance().toXMLString(script);
}
protected File createDefaultFilename() {
// create default filename
File ret = PreferencesManager.getSingleton().getScriptsDirectory();
if (ret != null) {
ret = new File(ret, createDefaultPathlessFilename());
}
return ret;
}
private String createDefaultPathlessFilename() {
String name = ScriptUtils.getDefaultScriptName(script);
if (Strings.isEmpty(name)) {
name = "script";
}
return name.toLowerCase() + "." + ScriptConstants.FILE_EXT;
}
public void disposeWithSavePrompt() {
String currentXML = getXML();
if (currentXML.equals(lastOutputXML) == false) {
if (JOptionPane.showConfirmDialog(ScriptEditor.this, "Script has been modified but not saved, changes will be lost. Really close?", "Really Closing?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
ScriptEditor.this.dispose();
}
} else {
ScriptEditor.this.dispose();
}
}
@Override
public void dispose() {
super.dispose();
if (runner != null) {
runner.removerDatastoreStructureChangedListener(dsStructureChangedListener);
}
}
protected void executeScript() {
if(runner!=null){
runner.executeScript(script, null,file != null ? file.getName() : null);
}
}
// protected <T> T callWithExecutionReport(Callable<T> callable){
// try {
// T result = callable.call();
// return result;
// } catch (Exception e) {
// // TODO: handle exception
// }
// }
protected void executeAdapterResultViewer(final AdaptedTableConfig table, final boolean isMap, final AdapterConfig... includeAdapters) {
RunMe<Void> runMe = new RunMe<Void>() {
@Override
public Void runMe(ExecutionReport report) {
// get the id of the adapter containing the table
String dsid =ScriptUtils.getAdapterId(script, table);
if(dsid==null){
throw new RuntimeException();
}
// Take copy of the script and set all unsynced options.
// This will avoid problems if part of the script is set to sync incorrectly...
Script copy = ScriptIO.instance().deepCopy(script);
ScriptUtils.setAllUnsynced(copy);
// Remove other instructions from the option which are unneeded (otherwise table may appear twice etc...)
// Assume that any instructions in the option containing the target adapter table are unneeded.
// This should cover all but some very unusual circumstances...
String optionid = ScriptUtils.getOptionIdByAdapterId(copy, dsid);
Option option = ScriptUtils.getOption(copy, optionid);
option.getInstructions().clear();
// Get adapter ids
String [] adapterIds = new String[includeAdapters.length];
for(int i =0 ; i<adapterIds.length ; i++){
adapterIds[i] = includeAdapters[i].getId();
}
// Get the collapsed subset of the script
TableId tableId = new TableId(dsid, table.getName());
Script subscript = OptionsSubpath.getSubpathScript(copy, new TableId[]{tableId}, adapterIds, report);
if(report.isFailed()){
return null;
}
if(subscript.getOptions().size()>0){
// script should now be collapsed...
throw new RuntimeException();
}
// remove all other tables in the adapter containing the target table as they are definitely not needed
AdapterConfig adapterConfig = ScriptUtils.getAdapterById(subscript, dsid, true);
Iterator<AdaptedTableConfig> itTable = adapterConfig.getTables().iterator();
while(itTable.hasNext()){
if(Strings.equalsStd(itTable.next().getName(), table.getName())==false){
itTable.remove();
}
}
// if we're showing a map then rename all remaining tables (could be multiple for a union) to drawables
if(isMap){
for(AdaptedTableConfig tableConfig : adapterConfig.getTables()){
tableConfig.setName(api.standardComponents().map().getDrawableTableDefinition().getName());
}
}
// treat like a standard adapter, not a VLS
adapterConfig.setAdapterType(ScriptAdapterType.NORMAL);
// // create a single dummy adapter which just copies the table contents, excluding any sort columns
// ScriptOptionImpl builder = new ScriptOptionImpl(api,null, subscript,null);
// ScriptAdapter adapter= builder.addDataAdapter("DummyAdapter");
// final String adptId =adapter.getAdapterId();
// ScriptAdapterTable dummyTable = adapter.addEmptyTable(table.getName());
// dummyTable.setSourceTable(dsid, table.getName());
// for(int i =0;i<table.getColumnCount(); i++){
// if(table.getColumn(i).getSortField() == SortField.NO){
// dummyTable.addColumn(table.getColumnName(i), table.getColumnType(i), false, table.getColumnName(i));
// }
// }
// if(isMap){
// // set table to have "drawables" name
// dummyTable.setTableName(api.standardComponents().map().getDrawableTableDefinition().getName());
// }
//
// add instruction to the end of the script
ScriptOptionImpl builder = new ScriptOptionImpl(api,null, subscript,null);
builder.addInstruction(adapterConfig.getId(), isMap? api.standardComponents().map().getId():api.standardComponents().tableViewer().getId(), ODLComponent.MODE_DEFAULT);
// give script a unique id
String name = isMap ? "Map data" : "Table result";
UUID uuid = UUID.nameUUIDFromBytes((script.getUuid().toString() + "-" + name).getBytes());
subscript.setUuid(uuid);
// finally run the temporary script
runner.executeScript(subscript,null, "Result of data adapter table" );
return null;
}
};
// run the runnable!
RunProcessWithExecReport.runProcess((JFrame) SwingUtilities.getWindowAncestor(this), runMe);
}
// protected void executeAdapterResultViewer(AdaptedTableConfig table, boolean isMap, AdapterConfig... includeAdapters) {
// // wrap the table config in its own temporary script
// String componentId;
// if (isMap) {
// componentId = MapViewerComponent.ID;
// } else {
// componentId = QueryReadOnlyTableComponent.ID;
// }
//
// ODLComponent component = ODLGlobalComponents.getProvider().getComponent(componentId);
// Serializable componentConfig = null;
// if (component.getConfigClass() != null) {
// try {
// componentConfig = component.getConfigClass().newInstance();
// } catch (Throwable e) {
// throw new RuntimeException(e);
// }
// }
// Script tmpScript = WizardUI.createScriptFromMasterComponent(SwingUtilities.getWindowAncestor(this), component, new ODLWizardTemplateConfig(null, null, null, componentConfig), null, -1);
//
// String name = isMap ? "Map data" : "Table result";
//
// List<AdaptedTableConfig> tables = tmpScript.getAdapters().get(0).getTables();
// tables.clear();
// tables.add(table);
// UUID uuid = UUID.nameUUIDFromBytes((script.getUuid().toString() + "-" + name).getBytes());
// tmpScript.setUuid(uuid);
// tmpScript.getLastInstruction().setUuid(UUID.nameUUIDFromBytes(name.getBytes()).toString());
// tmpScript.setSynchronised(false);
// // include other adapters
// for (AdapterConfig adapter : includeAdapters) {
// tmpScript.getAdapters().add(adapter);
// }
//
// runner.executeScript(tmpScript,null, "Result of data adapter table" );
//
// }
protected void testCompile(final ScriptUIManager runner) {
runner.testCompileScript(script,null, file != null ? file.getName() : null);
}
public QueryAvailableData createAvailableOptionsQuery() {
QueryAvailableData ret = new QueryAvailableData() {
private String emptyTableDs = ScriptConstants.FORMULA_PREFIX + EmptyTable.KEYWORD + "(\"tablename\",1)";
private String emptyTableName = "tablename";
@Override
public String[] queryAvailableFields(String datastore, String tablename) {
ODLTableDefinition st = getTableDefinition(datastore,tablename);
if(st==null){
return new String[0];
}
String [] ret = new String[st.getColumnCount()];
for(int i =0 ; i <ret.length;i++){
ret[i] = st.getColumnName(i);
}
return ret;
}
@Override
public String[] queryAvailableTables(String datastore) {
// if this is the empty table ds, add the empty table name...
if(api.stringConventions().equalStandardised(datastore, emptyTableDs.replace(" ", ""))){
return new String[]{emptyTableName};
}
SourcedDatastore sd = getDatastore(datastore);
if(sd==null){
return new String[0];
}
String [] ret = new String[sd.getDefinition().getTableCount()];
for(int i =0 ; i <ret.length;i++){
ret[i] = sd.getDefinition().getTableAt(i).getName();
}
return ret;
}
@Override
public String[] queryAvailableDatastores() {
List<SourcedDatastore> datastores = getDatastores();
String [] ret = new String[datastores.size()];
ArrayList<String> arrayList = new ArrayList<>();
for(int i =0 ; i<ret.length ; i++){
arrayList.add( datastores.get(i).getDatastoreId());
}
arrayList.add(ScriptConstants.SCRIPT_EMBEDDED_TABLE_DATA_DS);
arrayList.add(emptyTableDs);
// add formulae..
// arrayList.add();
// arrayList.add(ScriptConstants.SHAPEFILE_DS_NAME_PREFIX + "filename.shp");
// arrayList.add(ImportFileType.EXCEL.name().toLowerCase() + ScriptConstants.IMPORT_LINK_POSTFIX + "filename.xls");
// arrayList.add(ImportFileType.EXCEL.name().toLowerCase() + ScriptConstants.IMPORT_LINK_POSTFIX + "filename.xlsx");
// arrayList.add(ImportFileType.CSV.name().toLowerCase() + ScriptConstants.IMPORT_LINK_POSTFIX + "filename.csv");
// arrayList.add(ImportFileType.TAB.name().toLowerCase() + ScriptConstants.IMPORT_LINK_POSTFIX + "filename.tab");
return arrayList.toArray(new String[arrayList.size()]);
}
@Override
public String[] queryAvailableFormula(ODLColumnType columnType) {
return runner != null ? runner.getAvailableFieldsQuery().queryAvailableFormula(columnType) : new String[0];
}
@Override
public ODLTableDefinition getTableDefinition(String datastore, String tablename) {
SourcedTable st = getTable(datastore, tablename);
if(st!=null){
return st.getTableDefinition();
}
return null;
}
private SourcedDatastore getDatastore(String datastore){
for(SourcedDatastore sd : getDatastores()){
if(Strings.equalsStd(sd.getDatastoreId(), datastore)){
return sd;
}
}
return null;
}
private SourcedTable getTable(String datastore, String table){
SourcedDatastore sd = getDatastore(datastore);
if(sd!=null){
for(SourcedTable st : ScriptFieldsParser.toTables(sd)){
if(Strings.equalsStd(st.getTableName(), table)){
return st;
}
}
}
return null;
}
@Override
public ODLDatastore<? extends ODLTableDefinition> getDatastoreDefinition(String datastore) {
SourcedDatastore sd = getDatastore(datastore);
if(sd!=null){
return sd.getDefinition();
}
return null;
}
};
return ret;
}
/**
* Do any updating or validating of the script data needed before running
*/
protected void validateScriptData() {
}
// @Override
// public TableName promptUserForTable(String title) {
// SelectTableDialog dlg = SelectTableComboBox.createModal(api,SwingUtilities.getWindowAncestor(this), script, runner != null ? runner.getDatastoreDefinition() : null, title);
// dlg.setLocationRelativeTo(this);
// if (title != null) {
// dlg.setTitle(title);
// }
//
// if (dlg.showModal() == SelectTableDialog.OK_OPTION) {
// return dlg.getSelectedItem();
// }
// return null;
// }
protected void showMessage(String message) {
JOptionPane.showMessageDialog(this, message);
}
public void updateAppearance() {
toolBar.updateEnabled();
}
protected void datastoreStructureChanged() {
updateAppearance();
}
protected ComponentConfigurationEditorAPI createComponentEditorAPI(final String componentId,final Option option,final InstructionConfig instruction) {
return new ComponentConfigurationEditorImpl() {
@Override
public void onIODataChanged() {
// repaint everything so they will check for errors, auto-corrects etc
ScriptEditor.this.repaint();
}
@Override
public ODLApi getApi() {
return api;
}
@Override
public ODLDatastore<? extends ODLTableDefinition> getAvailableInputDatastore() {
if(instruction!=null && !Strings.isEmpty(instruction.getDatastore())){
if(Strings.equalsStd(ScriptConstants.EXTERNAL_DS_NAME, instruction.getDatastore())){
return runner.getDatastoreDefinition();
}
AdapterConfig adapterConfig = ScriptUtils.getAdapterById(script, instruction.getDatastore(), true);
if(adapterConfig!=null){
return adapterConfig.createOutputDefinition();
}
}
return null;
}
@Override
public Preferences getComponentPreferences() {
return PreferencesManager.getSingleton().node(Strings.std(componentId));
}
@Override
public JFrame getAncestorFrame() {
return (JFrame) SwingUtilities.getWindowAncestor(ScriptEditor.this);
}
@Override
public boolean isInstruction() {
return instruction!=null;
}
@Override
public void executeInPlace(String title, int mode) {
ScriptEditor.this.executeInPlace(title,componentId, option, instruction,mode);
}
};
}
protected void executeInPlace(String title, final String componentId,Option option,InstructionConfig instruction,int mode){
ExecutionReportImpl report = new ExecutionReportImpl();
// Take copy of the script and set all unsynced options.
// This will avoid problems if part of the script is set to sync incorrectly...
Script copy =ScriptIO.instance().deepCopy(script);
ScriptUtils.setAllUnsynced(copy);
// get the instruction index
int indx = -1;
for(int i =0 ; i<option.getInstructions().size();i++){
if(option.getInstructions().get(i)==instruction){
indx=i;
break;
}
}
// get copy of the option
option = ScriptUtils.getOption(copy, option.getOptionId());
if(option==null || indx==-1){
throw new RuntimeException("Corrupt script.");
}
// remove instructions on or after the target instruction
while(indx < option.getInstructions().size()){
option.getInstructions().remove(option.getInstructions().size()-1);
}
// add the dummy instruction
InstructionConfig newInstruction = new InstructionConfig(instruction.getDatastore(), null, componentId, instruction.getComponentConfig());
newInstruction.setExecutionMode(mode);
option.getInstructions().add(newInstruction);
// get a sub-path script for this option only
Script subscript = OptionsSubpath.getSubpathScript(copy, new String[]{option.getOptionId()}, report);
// give script a unique id
subscript.setUuid(UUID.randomUUID());
// finally run the temporary script
runner.executeScript(subscript,null,title!=null? title:"" );
}
protected List<SourcedDatastore> getDatastores(){
return ScriptFieldsParser.getSingleLevelDatastores(api, script, script, runner!=null?runner.getDatastoreDefinition():null);
}
// protected List<SourcedColumn> getScriptInternalFields() {
// return ScriptFieldsParser.getSingleLevelColumns(api,script,script, null);
// }
public File getFile(){
return file;
}
}