/******************************************************************************* * 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.execution; import java.io.File; import java.util.HashSet; import java.util.UUID; import java.util.concurrent.Future; import javax.swing.JInternalFrame; import javax.swing.JOptionPane; import com.opendoorlogistics.api.ODLApi; import com.opendoorlogistics.api.tables.ODLDatastore; import com.opendoorlogistics.api.tables.ODLDatastoreUndoable; import com.opendoorlogistics.api.tables.ODLListener; import com.opendoorlogistics.api.tables.ODLTableAlterable; import com.opendoorlogistics.api.tables.ODLTableDefinition; import com.opendoorlogistics.components.tables.creator.CreateTablesComponent; import com.opendoorlogistics.core.components.ODLWizardTemplateConfig; import com.opendoorlogistics.core.scripts.ScriptConstants; import com.opendoorlogistics.core.scripts.elements.Option; import com.opendoorlogistics.core.scripts.elements.OutputConfig; import com.opendoorlogistics.core.scripts.elements.Script; import com.opendoorlogistics.core.scripts.execution.ExecutionReportImpl; import com.opendoorlogistics.core.scripts.io.ScriptIO; import com.opendoorlogistics.core.scripts.utils.ScriptUtils; import com.opendoorlogistics.core.utils.ui.ExecutionReportDialog; import com.opendoorlogistics.studio.appframe.AppFrame; import com.opendoorlogistics.studio.appframe.AppPermissions; import com.opendoorlogistics.studio.internalframes.HasInternalFrames.FramePlacement; import com.opendoorlogistics.studio.scripts.editor.ScriptWizardActions; import com.opendoorlogistics.studio.scripts.editor.adapters.QueryAvailableData; import com.opendoorlogistics.studio.scripts.editor.adapters.QueryAvailableDataImpl; import com.opendoorlogistics.studio.scripts.editor.wizardgenerated.ScriptEditorWizardGenerated; /** * The script UI manager exists permanently whilst the application frame is open. * @author Phil * */ final public class ScriptUIManagerImpl implements ScriptUIManager, ODLListener { private final AppFrame appframe; private final HashSet<ODLListener> dsChangedListeners = new HashSet<>(); public ScriptUIManagerImpl(AppFrame frame) { super(); this.appframe = frame; } /* * (non-Javadoc) * * @see * com.opendoorlogistics.studio.IScriptUIManager#getDatastoreDefinition() */ @Override public ODLDatastore<? extends ODLTableDefinition> getDatastoreDefinition() { if (getDs() != null) { return getDs(); } return null; } /* * (non-Javadoc) * * @see * com.opendoorlogistics.studio.IScriptUIManager#launchScriptEditor(com. * opendoorlogistics.core.scripts.Script, java.io.File) */ @Override public void launchScriptEditor(Script script, String optionId,File file) { // check to see if already open if(file!=null && file.exists()){ for(JInternalFrame frame:appframe.getInternalFrames()){ if(ScriptEditorWizardGenerated.class.isInstance(frame)){ ScriptEditorWizardGenerated other = (ScriptEditorWizardGenerated)frame; if(other.getFile()!=null && file.equals(other.getFile())){ other.setSelectedOption(optionId); frame.toFront(); return; } } } } ScriptEditorWizardGenerated editor = new ScriptEditorWizardGenerated(appframe.getApi(),script, file,optionId, this); // if(editor!=null){ editor.setVisible(true); appframe.addInternalFrame(editor,FramePlacement.AUTOMATIC); // } } /* * (non-Javadoc) * * @see * com.opendoorlogistics.studio.IScriptUIManager#launchScriptEditor(java * .io.File) */ @Override public void launchScriptEditor(File file, String optionId) { Script script = loadScript(file); if (script != null) { launchScriptEditor(script, optionId,file); } } private Script loadScript(File file) { try { ScriptIO scriptIO = ScriptIO.instance(); Script script = scriptIO.fromFile(file); if (script == null) { throw new RuntimeException(); } return script; } catch (Throwable e2) { ExecutionReportImpl report = new ExecutionReportImpl(); report.setFailed(e2); report.log("Could not open script file: " + file.getAbsolutePath()); ExecutionReportDialog.show(appframe, "Error opening script", report); return null; } } /* * (non-Javadoc) * * @see com.opendoorlogistics.studio.IScriptUIManager#executeScript(com. * opendoorlogistics.core.scripts.Script, java.lang.String) */ @Override public Future<Void> executeScript(Script script, String[]optionIds,String name) { // take a deep copy of the script to ensure its immutable script = ScriptIO.instance().deepCopy(script); // test to see if we should launch multiple versions of a control Option option = null; if(optionIds ==null || optionIds.length==0){ option = script; }else if(optionIds.length==1){ option = ScriptUtils.getOption(script, optionIds[0]); } boolean launchMultiple = option!=null && option.isLaunchMultiple(); // if launching multiple, give the script a unique id if(launchMultiple){ script.setUuid(UUID.randomUUID()); } if (getDs() == null ) { showMessage("Cannot execute as no datastore is loaded.", false); return null; } if(name==null){ name = ScriptUtils.getDefaultScriptName(script); } return getScriptRunner().execute(script,optionIds, name); } /* * (non-Javadoc) * * @see com.opendoorlogistics.studio.IScriptUIManager#testCompileScript(com. * opendoorlogistics.core.scripts.Script, java.lang.String) */ @Override public void testCompileScript(Script script, String []optionids,String name) { if (getDs() == null ) { showMessage("Cannot compile as no data tables are loaded.", false); return; } getScriptRunner().compileOnEDT(script,optionids, name); } /* * (non-Javadoc) * * @see * com.opendoorlogistics.studio.IScriptUIManager#executeScript(java.io.File) */ @Override public Future<Void> executeScript(File file, String[]optionIds) { Script loaded = loadScript(file); if (loaded != null) { return executeScript(loaded,optionIds, file.getName()); } return null; } /* * (non-Javadoc) * * @see * com.opendoorlogistics.studio.IScriptUIManager#testCompileScript(java. * io.File) */ @Override public void testCompileScript(File file, String []optionids) { Script script = loadScript(file); if (script != null) { testCompileScript(script, optionids,file.getName()); } } // /* // * (non-Javadoc) // * // * @see com.opendoorlogistics.studio.IScriptUIManager#refreshReport(com. // * opendoorlogistics.core.scripts.Script, boolean) // */ // @Override // public RunResult refreshReport(Script script,ReporterFrameIdentifier frameIdentifier, boolean runOnEDTWithoutProgress) { // if (!SwingUtilities.isEventDispatchThread()) { // throw new RuntimeException("This should only be called from the EDT"); // } // // if (appframe.getLoaded() == null) { // showMessage("Cannot refresh report as no data tables are loaded.", false); // return RunResult.FAILED; // } // // // get the subset of instructions to run.. start off with only the instruction need to refresh this single report // StandardisedStringSet instructionIdsToRefresh = new StandardisedStringSet(); // instructionIdsToRefresh.add(frameIdentifier.getInstructionId()); // // // If we're doing an automatic refresh (which are the only ones on the EDT), work out what // // other windows are open from the same script. Filter the script to execute all these instructions. // if(runOnEDTWithoutProgress){ // for(JInternalFrame childFrame:appframe.getInternalFrames()){ // if(ReporterFrame.class.isInstance(childFrame)){ // ReporterFrame<?> rp = (ReporterFrame<?>)childFrame; // if(rp.getRefreshMode() == RefreshMode.AUTOMATIC && Strings.equalsStd(rp.getId().getScriptId(),script.getUuid().toString())){ // instructionIdsToRefresh.add(rp.getId().getInstructionId()); // } // } // } // } // // // now get the options to execute these instructions // String[]optionIds = ScriptUtils.getOptionIdByInstructionIds(script, instructionIdsToRefresh); // // if (runOnEDTWithoutProgress) { // return getScriptRunner().execute(script,optionIds, "Refresh open report",true); // } else { // return getScriptRunner().execute(script, optionIds,"Refresh open report",false); // } // // } /* * (non-Javadoc) * * @see com.opendoorlogistics.studio.IScriptUIManager#hasLoadedData() */ @Override public boolean hasLoadedData() { return getDs() != null; } /* * (non-Javadoc) * * @see * com.opendoorlogistics.studio.IScriptUIManager#getAvailableFieldsQuery() */ @Override public QueryAvailableData getAvailableFieldsQuery() { return new QueryAvailableDataImpl() { @Override protected ODLDatastore<? extends ODLTableDefinition> getDs() { return ScriptUIManagerImpl.this.getDs(); } @Override protected String getDsName() { return ScriptUIManagerImpl.this.getDs() != null ? ScriptConstants.EXTERNAL_DS_NAME : null; } }; } protected ScriptsRunner getScriptRunner() { return appframe.getLoadedDatastore().getRunner(); } protected ODLDatastoreUndoable<? extends ODLTableAlterable> getDs() { return appframe.getLoadedDatastore() != null ? appframe.getLoadedDatastore().getDs() : null; } protected void showMessage(String text, boolean scrollableDlg) { if (scrollableDlg) { } else { JOptionPane.showMessageDialog(appframe, text); } } @Override public void tableChanged(int tableId, int firstRow, int lastRow) { // TODO Auto-generated method stub } @Override public void datastoreStructureChanged() { for(ODLListener listener : dsChangedListeners){ listener.datastoreStructureChanged(); } } @Override public ODLListenerType getType() { return ODLListenerType.DATASTORE_STRUCTURE_CHANGED; } @Override public synchronized void registerDatastoreStructureChangedListener(ODLListener listener) { if(listener.getType()!=ODLListenerType.DATASTORE_STRUCTURE_CHANGED){ throw new RuntimeException(); } dsChangedListeners.add(listener); } @Override public void removerDatastoreStructureChangedListener(ODLListener listener) { dsChangedListeners.remove(listener); } @Override public void launchCreateTablesWizard(ODLDatastore<? extends ODLTableDefinition> ds) { ODLWizardTemplateConfig template = CreateTablesComponent.createTemplateConfig(ds); Script script = ScriptWizardActions.createScriptFromMasterComponent(appframe.getApi(),null, new CreateTablesComponent(), template, null, new int[0]); for(OutputConfig output : script.getOutputs()){ output.setUserCanEdit(false); } launchScriptEditor(script, null,null); } @Override public ODLApi getApi() { return appframe.getApi(); } @Override public AppPermissions getAppPermissions() { return appframe.getAppPermissions(); } }