From: <pat...@us...> - 2011-02-08 17:28:03
|
Revision: 1197 http://cishell.svn.sourceforge.net/cishell/?rev=1197&view=rev Author: pataphil Date: 2011-02-08 17:27:54 +0000 (Tue, 08 Feb 2011) Log Message: ----------- * Added drag-and-drop file loading functionality. * Reviewed by Micah. * Refactored file loading to be done via service instead of explicitly through an algorithm. Modified Paths: -------------- trunk/clients/gui/org.cishell.reference.gui.datamanager/META-INF/MANIFEST.MF trunk/clients/gui/org.cishell.reference.gui.datamanager/src/org/cishell/reference/gui/datamanager/AbstractDataManagerView.java trunk/clients/gui/org.cishell.reference.gui.datamanager/src/org/cishell/reference/gui/datamanager/Activator.java trunk/clients/gui/org.cishell.reference.gui.persistence/META-INF/MANIFEST.MF trunk/clients/gui/org.cishell.reference.gui.persistence/OSGI-INF/load.properties trunk/clients/gui/org.cishell.reference.gui.persistence/OSGI-INF/load.xml trunk/clients/gui/org.cishell.reference.gui.persistence/src/org/cishell/reference/gui/persistence/load/FileLoadAlgorithm.java trunk/core/org.cishell.framework/META-INF/MANIFEST.MF trunk/core/org.cishell.framework/src/org/cishell/framework/data/DataProperty.java trunk/core/org.cishell.reference/META-INF/MANIFEST.MF trunk/core/org.cishell.reference/build.properties Added Paths: ----------- trunk/clients/gui/org.cishell.reference.gui.persistence/OSGI-INF/fileloader.properties trunk/clients/gui/org.cishell.reference.gui.persistence/OSGI-INF/fileloader.xml trunk/clients/gui/org.cishell.reference.gui.persistence/src/org/cishell/reference/gui/persistence/load/FileLoaderAlgorithm.java trunk/clients/gui/org.cishell.reference.gui.persistence/src/org/cishell/reference/gui/persistence/load/FileLoaderAlgorithmFactory.java trunk/core/org.cishell.framework/src/org/cishell/app/service/fileloader/ trunk/core/org.cishell.framework/src/org/cishell/app/service/fileloader/FileLoadException.java trunk/core/org.cishell.framework/src/org/cishell/app/service/fileloader/FileLoadListener.java trunk/core/org.cishell.framework/src/org/cishell/app/service/fileloader/FileLoaderService.java trunk/core/org.cishell.framework/src/org/cishell/framework/CIShellContextDelegate.java trunk/core/org.cishell.framework/src/org/cishell/framework/LogServiceDelegate.java trunk/core/org.cishell.framework/src/org/cishell/framework/ServiceReferenceDelegate.java trunk/core/org.cishell.framework/src/org/cishell/framework/algorithm/AlgorithmFactory2.java trunk/core/org.cishell.reference/OSGI-INF/ trunk/core/org.cishell.reference/OSGI-INF/fileloader.properties trunk/core/org.cishell.reference/OSGI-INF/fileloader.xml trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/ trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/FileFormatSelector.java trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/FileLoaderServiceImpl.java trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/FileSelectorRunnable.java trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/FileValidator.java trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/PrettyLabeler.java trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/ValidatorSelectorRunnable.java Modified: trunk/clients/gui/org.cishell.reference.gui.datamanager/META-INF/MANIFEST.MF =================================================================== --- trunk/clients/gui/org.cishell.reference.gui.datamanager/META-INF/MANIFEST.MF 2011-02-04 16:25:21 UTC (rev 1196) +++ trunk/clients/gui/org.cishell.reference.gui.datamanager/META-INF/MANIFEST.MF 2011-02-08 17:27:54 UTC (rev 1197) @@ -13,6 +13,7 @@ org.cishell.reference.gui.datamanager, org.cishell.reference.gui.workspace, org.cishell.service.guibuilder;version="1.0.0", + org.cishell.utilities, org.osgi.service.log;version="1.3.0" Export-Package: org.cishell.reference.gui.datamanager Bundle-ActivationPolicy: lazy Modified: trunk/clients/gui/org.cishell.reference.gui.datamanager/src/org/cishell/reference/gui/datamanager/AbstractDataManagerView.java =================================================================== --- trunk/clients/gui/org.cishell.reference.gui.datamanager/src/org/cishell/reference/gui/datamanager/AbstractDataManagerView.java 2011-02-04 16:25:21 UTC (rev 1196) +++ trunk/clients/gui/org.cishell.reference.gui.datamanager/src/org/cishell/reference/gui/datamanager/AbstractDataManagerView.java 2011-02-08 17:27:54 UTC (rev 1197) @@ -13,6 +13,9 @@ * ***************************************************************************/ package org.cishell.reference.gui.datamanager; +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; import java.util.Dictionary; import java.util.HashMap; import java.util.HashSet; @@ -23,13 +26,16 @@ import org.cishell.app.service.datamanager.DataManagerListener; import org.cishell.app.service.datamanager.DataManagerService; +import org.cishell.framework.LocalCIShellContext; import org.cishell.framework.algorithm.Algorithm; -import org.cishell.framework.algorithm.AlgorithmCanceledException; import org.cishell.framework.algorithm.AlgorithmExecutionException; import org.cishell.framework.algorithm.AlgorithmFactory; +import org.cishell.framework.data.BasicData; import org.cishell.framework.data.Data; import org.cishell.framework.data.DataProperty; import org.cishell.reference.gui.workspace.CIShellApplication; +import org.cishell.utilities.AlgorithmUtilities; +import org.cishell.utilities.StringUtilities; import org.eclipse.jface.action.ActionContributionItem; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.viewers.ISelection; @@ -41,6 +47,12 @@ import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.TreeEditor; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DropTarget; +import org.eclipse.swt.dnd.DropTargetAdapter; +import org.eclipse.swt.dnd.DropTargetEvent; +import org.eclipse.swt.dnd.FileTransfer; +import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.events.FocusAdapter; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.KeyAdapter; @@ -185,7 +197,89 @@ } getSite().setSelectionProvider(new DataModelSelectionProvider()); + + DropTarget dropTarget = + new DropTarget(parent.getParent(), DND.DROP_DEFAULT | DND.DROP_MOVE); + dropTarget.setTransfer(new Transfer[] { FileTransfer.getInstance() }); + dropTarget.addDropListener(new DropTargetAdapter() { + @Override + public void drop(DropTargetEvent event) { + String fileNames[] = null; + FileTransfer fileTransfer = FileTransfer.getInstance(); + + if (fileTransfer.isSupportedType(event.currentDataType)) { + fileNames = (String[]) event.data; + Collection<File> flattenedFileStructure = + flattenDraggedFileStructures(fileNames); + Collection<Data> dataForProcessing = new ArrayList<Data>(); + + for (File file : flattenedFileStructure) { + dataForProcessing.add(new BasicData(file, "")); + } + + AlgorithmFactory fileLoaderFactory = + AlgorithmUtilities.getAlgorithmFactoryByPID( + "org.cishell.reference.gui.persistence.load.FileLoaderAlgorithm", + Activator.context); + DataManagerService dataManager = + (DataManagerService) Activator.context.getService( + Activator.context.getServiceReference( + DataManagerService.class.getName())); + + try { + Data[] inputData = fileLoaderFactory.createAlgorithm( + dataForProcessing.toArray(new Data[0]), + new Hashtable<String, Object>(), + new LocalCIShellContext(Activator.context)).execute(); + + for (Data inputDatum : inputData) { + dataManager.addData(inputDatum); + } + } catch (Throwable e) { + String format = + "An error occurred when loading your files.%n" + + "Please include the following when reporting this:%n%s"; + String logMessage = + String.format(format, StringUtilities.getStackTraceAsString(e)); + AbstractDataManagerView.this.logger.log(LogService.LOG_ERROR, logMessage); + } + } + } + }); } + + private Collection<File> flattenDraggedFileStructures(String[] fileNames) { + Collection<File> flattenedFileStructure = new ArrayList<File>(); + + for (String fileName : fileNames) { + flattenedFileStructure.addAll(flattenDraggedFileStructure(fileName)); + } + + return flattenedFileStructure; + } + + private Collection<File> flattenDraggedFileStructure(String fileName) { + File file = new File(fileName); + + if (file.isFile()) { + Collection<File> flattenedFileStructure = new ArrayList<File>(); + flattenedFileStructure.add(file); + + return flattenedFileStructure; + } else if (file.isDirectory()) { + Collection<File> flattenedFileStructure = new ArrayList<File>(); + + for (String childFileName : file.list()) { + String completeChildFileName = String.format( + "%s%s%s", fileName, File.separator, childFileName); + flattenedFileStructure.addAll(flattenDraggedFileStructure(completeChildFileName)); + } + + return flattenedFileStructure; + } else { + return new ArrayList<File>(); + } + } public void bundleChanged(BundleEvent event) { if (event.getType() == BundleEvent.STARTED) { Modified: trunk/clients/gui/org.cishell.reference.gui.datamanager/src/org/cishell/reference/gui/datamanager/Activator.java =================================================================== --- trunk/clients/gui/org.cishell.reference.gui.datamanager/src/org/cishell/reference/gui/datamanager/Activator.java 2011-02-04 16:25:21 UTC (rev 1196) +++ trunk/clients/gui/org.cishell.reference.gui.datamanager/src/org/cishell/reference/gui/datamanager/Activator.java 2011-02-08 17:27:54 UTC (rev 1197) @@ -18,7 +18,7 @@ // The plug-in ID public static final String PLUGIN_ID = "org.cishell.reference.gui.datamanager"; - private static BundleContext context; + public static BundleContext context; // The shared instance private static Activator plugin; Modified: trunk/clients/gui/org.cishell.reference.gui.persistence/META-INF/MANIFEST.MF =================================================================== --- trunk/clients/gui/org.cishell.reference.gui.persistence/META-INF/MANIFEST.MF 2011-02-04 16:25:21 UTC (rev 1196) +++ trunk/clients/gui/org.cishell.reference.gui.persistence/META-INF/MANIFEST.MF 2011-02-08 17:27:54 UTC (rev 1197) @@ -5,6 +5,7 @@ Bundle-Version: 1.0.0 Bundle-ClassPath: . Import-Package: org.cishell.app.service.datamanager, + org.cishell.app.service.fileloader, org.cishell.framework;version="1.0.0", org.cishell.framework.algorithm;version="1.0.0", org.cishell.framework.data;version="1.0.0", @@ -23,7 +24,7 @@ org.osgi.service.metatype;version="1.1.0", org.osgi.service.prefs;version="1.1.0" X-AutoStart: true -Service-Component: OSGI-INF/load.xml, OSGI-INF/save.xml, OSGI-INF/view.xml, OSGI-INF/viewwith.xml +Service-Component: OSGI-INF/load.xml, OSGI-INF/save.xml, OSGI-INF/view.xml, OSGI-INF/viewwith.xml, OSGI-INF/fileloader.xml Require-Bundle: org.eclipse.swt, org.eclipse.ui Bundle-RequiredExecutionEnvironment: J2SE-1.5 Added: trunk/clients/gui/org.cishell.reference.gui.persistence/OSGI-INF/fileloader.properties =================================================================== --- trunk/clients/gui/org.cishell.reference.gui.persistence/OSGI-INF/fileloader.properties (rev 0) +++ trunk/clients/gui/org.cishell.reference.gui.persistence/OSGI-INF/fileloader.properties 2011-02-08 17:27:54 UTC (rev 1197) @@ -0,0 +1,8 @@ +#menu_path=File/start +label=File Loader +description=This does the actual loading of files from the file system and loads them to Data Model window. +in_data=null +out_data=java.lang.Object +service.pid=org.cishell.reference.gui.persistence.load.FileLoaderAlgorithm +remoteable=true +documentation_url=http://wiki.slis.indiana.edu:8080/display/ALGDOC/Data+Formats \ No newline at end of file Added: trunk/clients/gui/org.cishell.reference.gui.persistence/OSGI-INF/fileloader.xml =================================================================== --- trunk/clients/gui/org.cishell.reference.gui.persistence/OSGI-INF/fileloader.xml (rev 0) +++ trunk/clients/gui/org.cishell.reference.gui.persistence/OSGI-INF/fileloader.xml 2011-02-08 17:27:54 UTC (rev 1197) @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<component name="org.cishell.reference.gui.persistence.load.FileLoaderAlgorithm.component" immediate="false"> + <implementation class="org.cishell.reference.gui.persistence.load.FileLoaderAlgorithmFactory"/> + <properties entry="OSGI-INF/fileloader.properties"/> + <reference name="LOG" interface="org.osgi.service.log.LogService"/> + <reference name="MTS" interface="org.osgi.service.metatype.MetaTypeService"/> + + <service> + <provide interface="org.cishell.framework.algorithm.AlgorithmFactory"/> + </service> +</component> \ No newline at end of file Modified: trunk/clients/gui/org.cishell.reference.gui.persistence/OSGI-INF/load.properties =================================================================== --- trunk/clients/gui/org.cishell.reference.gui.persistence/OSGI-INF/load.properties 2011-02-04 16:25:21 UTC (rev 1196) +++ trunk/clients/gui/org.cishell.reference.gui.persistence/OSGI-INF/load.properties 2011-02-08 17:27:54 UTC (rev 1197) @@ -1,7 +1,7 @@ menu_path=File/start label=Load... shortcut=ctrl+alt+o -description=This allows users to select file from the file system and load it to Data Model window +description=This allows users to select files from the file system and load them to Data Model window. in_data=null out_data=java.lang.Object service.pid=org.cishell.reference.gui.persistence.load.FileLoadAlgorithm Modified: trunk/clients/gui/org.cishell.reference.gui.persistence/OSGI-INF/load.xml =================================================================== --- trunk/clients/gui/org.cishell.reference.gui.persistence/OSGI-INF/load.xml 2011-02-04 16:25:21 UTC (rev 1196) +++ trunk/clients/gui/org.cishell.reference.gui.persistence/OSGI-INF/load.xml 2011-02-08 17:27:54 UTC (rev 1197) @@ -1,14 +1,14 @@ -<?xml version="1.0" encoding="UTF-8"?> -<component name="org.cishell.reference.gui.persistence.load.FileLoadAlgorithm.component" immediate="false"> - <implementation class="org.cishell.reference.gui.persistence.load.FileLoadFactory"/> - <properties entry="OSGI-INF/load.properties"/> - <reference name="LOG" interface="org.osgi.service.log.LogService"/> - <reference name="MTS" interface="org.osgi.service.metatype.MetaTypeService"/> - - <service> - <provide interface= - "org.cishell.framework.algorithm.AlgorithmFactory"/> - <provide interface= - "org.osgi.service.cm.ManagedService"/> - </service> +<?xml version="1.0" encoding="UTF-8"?> +<component name="org.cishell.reference.gui.persistence.load.FileLoadAlgorithm.component" immediate="false"> + <implementation class="org.cishell.reference.gui.persistence.load.FileLoadFactory"/> + <properties entry="OSGI-INF/load.properties"/> + <reference name="LOG" interface="org.osgi.service.log.LogService"/> + <reference name="MTS" interface="org.osgi.service.metatype.MetaTypeService"/> + + <service> + <provide interface= + "org.cishell.framework.algorithm.AlgorithmFactory"/> + <provide interface= + "org.osgi.service.cm.ManagedService"/> + </service> </component> \ No newline at end of file Modified: trunk/clients/gui/org.cishell.reference.gui.persistence/src/org/cishell/reference/gui/persistence/load/FileLoadAlgorithm.java =================================================================== --- trunk/clients/gui/org.cishell.reference.gui.persistence/src/org/cishell/reference/gui/persistence/load/FileLoadAlgorithm.java 2011-02-04 16:25:21 UTC (rev 1196) +++ trunk/clients/gui/org.cishell.reference.gui.persistence/src/org/cishell/reference/gui/persistence/load/FileLoadAlgorithm.java 2011-02-08 17:27:54 UTC (rev 1197) @@ -1,15 +1,13 @@ package org.cishell.reference.gui.persistence.load; import java.io.File; -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.Collection; import java.util.Dictionary; +import org.cishell.app.service.fileloader.FileLoadException; +import org.cishell.app.service.fileloader.FileLoaderService; import org.cishell.framework.CIShellContext; import org.cishell.framework.algorithm.Algorithm; import org.cishell.framework.algorithm.AlgorithmExecutionException; -import org.cishell.framework.algorithm.AlgorithmFactory; import org.cishell.framework.algorithm.ProgressMonitor; import org.cishell.framework.algorithm.ProgressTrackable; import org.cishell.framework.data.Data; @@ -26,6 +24,7 @@ public static String defaultLoadDirectory; private final LogService logger; + private FileLoaderService fileLoader; private BundleContext bundleContext; private CIShellContext ciShellContext; private ProgressMonitor progressMonitor = ProgressMonitor.NULL_MONITOR; @@ -34,7 +33,9 @@ CIShellContext ciShellContext, BundleContext bundleContext, Dictionary<String, Object> preferences) { - this.logger = (LogService)ciShellContext.getService(LogService.class.getName()); + this.logger = (LogService) ciShellContext.getService(LogService.class.getName()); + this.fileLoader = + (FileLoaderService) ciShellContext.getService(FileLoaderService.class.getName()); this.ciShellContext = ciShellContext; this.bundleContext = bundleContext; @@ -45,26 +46,37 @@ } public Data[] execute() throws AlgorithmExecutionException { - IWorkbenchWindow window = getFirstWorkbenchWindow(); - Display display = PlatformUI.getWorkbench().getDisplay(); - File[] files = getFilesToLoadFromUser(window, display); - - if ((files != null) && (files.length != 0)) { - Collection<Data> finalLabeledFileData = new ArrayList<Data>(); - - for (File file : files) { - Data[] validatedFileData = validateFile(window, display, file); - Data[] labeledFileData = labelFileData(file, validatedFileData); - - for (Data data : labeledFileData) { - finalLabeledFileData.add(data); - } - } - - return finalLabeledFileData.toArray(new Data[0]); - } else { - return null; + try { + return this.fileLoader.loadFilesFromUserSelection( + this.bundleContext, this.ciShellContext, this.logger, this.progressMonitor); + } catch (FileLoadException e) { + throw new AlgorithmExecutionException(e.getMessage(), e); } +// IWorkbenchWindow window = getFirstWorkbenchWindow(); +// Display display = PlatformUI.getWorkbench().getDisplay(); +// File[] files = getFilesToLoadFromUser(window, display); +// +// if (files != null) { +//// try { +// return new FileLoaderAlgorithm( +// this.bundleContext, +// files, +// this.ciShellContext, +// this.logger, +// this.progressMonitor).execute(); +//// } catch (Throwable e) { +//// String format = +//// "The chosen file is not compatible with this format. " + +//// "Check that your file is correctly formatted or try another validator. " + +//// "The reason is: %s"; +//// String logMessage = String.format(format, e.getMessage()); +//// this.logger.log(LogService.LOG_ERROR, logMessage, e); +//// +//// return null; +//// } +// } else { +// return null; +// } } public ProgressMonitor getProgressMonitor() { @@ -101,62 +113,4 @@ return fileSelector.getFiles(); } - - private Data[] validateFile(IWorkbenchWindow window, Display display, File file) { - AlgorithmFactory validator = null; - - try { - validator = getValidatorFromUser(window, display, file); - - if ((file == null) || (validator == null)) { - String logMessage = "File loading canceled"; - this.logger.log(LogService.LOG_WARNING, logMessage); - } else { - try { - return FileValidator.validateFile( - file, validator, this.progressMonitor, this.ciShellContext, this.logger); - } catch (AlgorithmExecutionException e) { - if ((e.getCause() != null) - && (e.getCause() instanceof UnsupportedEncodingException)) { - String format = - "This file cannot be loaded; it uses the unsupported character " + - "encoding %s."; - String logMessage = String.format(format, e.getCause().getMessage()); - this.logger.log(LogService.LOG_ERROR, logMessage); - } else { - throw e; - } - } - } - } catch (Throwable e) { - String logMessage = - "The chosen file is not compatible with this format. " + - "Check that your file is correctly formatted or try another validator. " + - "The reason is: " + e.getMessage(); - this.logger.log(LogService.LOG_ERROR, logMessage); - } - - return new Data[0]; - } - - private Data[] labelFileData(File file, Data[] validatedFileData) { - Data[] labeledFileData = PrettyLabeler.relabelWithFileNameHierarchy( - validatedFileData, file); - - return labeledFileData; - } - - private AlgorithmFactory getValidatorFromUser( - IWorkbenchWindow window, Display display, File file) { - ValidatorSelectorRunnable validatorSelector = - new ValidatorSelectorRunnable(window, this.bundleContext, file); - - if (Thread.currentThread() != display.getThread()) { - display.syncExec(validatorSelector); - } else { - validatorSelector.run(); - } - - return validatorSelector.getValidator(); - } } \ No newline at end of file Added: trunk/clients/gui/org.cishell.reference.gui.persistence/src/org/cishell/reference/gui/persistence/load/FileLoaderAlgorithm.java =================================================================== --- trunk/clients/gui/org.cishell.reference.gui.persistence/src/org/cishell/reference/gui/persistence/load/FileLoaderAlgorithm.java (rev 0) +++ trunk/clients/gui/org.cishell.reference.gui.persistence/src/org/cishell/reference/gui/persistence/load/FileLoaderAlgorithm.java 2011-02-08 17:27:54 UTC (rev 1197) @@ -0,0 +1,131 @@ +package org.cishell.reference.gui.persistence.load; + +import java.io.File; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.Collection; + +import org.cishell.framework.CIShellContext; +import org.cishell.framework.algorithm.Algorithm; +import org.cishell.framework.algorithm.AlgorithmExecutionException; +import org.cishell.framework.algorithm.AlgorithmFactory; +import org.cishell.framework.algorithm.ProgressMonitor; +import org.cishell.framework.data.Data; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.osgi.framework.BundleContext; +import org.osgi.service.log.LogService; + +public class FileLoaderAlgorithm implements Algorithm { + private BundleContext bundleContext; + private File[] filesToLoad; + private CIShellContext ciShellContext; + private LogService logger; + private ProgressMonitor progressMonitor; + + public FileLoaderAlgorithm( + BundleContext bundleContext, + File[] filesToLoad, + CIShellContext ciShellContext, + LogService logger, + ProgressMonitor progressMonitor) { + this.bundleContext = bundleContext; + this.filesToLoad = filesToLoad; + this.ciShellContext = ciShellContext; + this.logger = logger; + this.progressMonitor = progressMonitor; + } + + public Data[] execute() throws AlgorithmExecutionException { + IWorkbenchWindow window = getFirstWorkbenchWindow(); + Display display = PlatformUI.getWorkbench().getDisplay(); + + if ((this.filesToLoad != null) && (this.filesToLoad.length != 0)) { + Collection<Data> finalLabeledFileData = new ArrayList<Data>(); + + for (File file : this.filesToLoad) { + try { + Data[] validatedFileData = validateFile(window, display, file); + Data[] labeledFileData = labelFileData(file, validatedFileData); + + for (Data data : labeledFileData) { + finalLabeledFileData.add(data); + } + } catch (Throwable e) { + String format = + "The chosen file is not compatible with this format. " + + "Check that your file is correctly formatted or try another validator. " + + "The reason is: %s"; + String logMessage = String.format(format, e.getMessage()); + this.logger.log(LogService.LOG_ERROR, logMessage, e); + } + } + + return finalLabeledFileData.toArray(new Data[0]); + } else { + return null; + } + } + + private IWorkbenchWindow getFirstWorkbenchWindow() throws AlgorithmExecutionException { + final IWorkbenchWindow[] windows = PlatformUI.getWorkbench().getWorkbenchWindows(); + + if (windows.length == 0) { + throw new AlgorithmExecutionException( + "Cannot obtain workbench window needed to open dialog."); + } else { + return windows[0]; + } + } + + private Data[] validateFile(IWorkbenchWindow window, Display display, File file) + throws AlgorithmExecutionException { + AlgorithmFactory validator = null; + validator = getValidatorFromUser(window, display, file); + + if ((file == null) || (validator == null)) { + String logMessage = "File loading canceled"; + this.logger.log(LogService.LOG_WARNING, logMessage); + } else { + try { + return FileValidator.validateFile( + file, validator, this.progressMonitor, this.ciShellContext, this.logger); + } catch (AlgorithmExecutionException e) { + if ((e.getCause() != null) + && (e.getCause() instanceof UnsupportedEncodingException)) { + String format = + "This file cannot be loaded; it uses the unsupported character " + + "encoding %s."; + String logMessage = String.format(format, e.getCause().getMessage()); + this.logger.log(LogService.LOG_ERROR, logMessage); + } else { + throw e; + } + } + } + + return new Data[0]; + } + + private Data[] labelFileData(File file, Data[] validatedFileData) { + Data[] labeledFileData = + PrettyLabeler.relabelWithFileNameHierarchy(validatedFileData, file); + + return labeledFileData; + } + + private AlgorithmFactory getValidatorFromUser( + IWorkbenchWindow window, Display display, File file) { + ValidatorSelectorRunnable validatorSelector = + new ValidatorSelectorRunnable(window, this.bundleContext, file); + + if (Thread.currentThread() != display.getThread()) { + display.syncExec(validatorSelector); + } else { + validatorSelector.run(); + } + + return validatorSelector.getValidator(); + } +} \ No newline at end of file Added: trunk/clients/gui/org.cishell.reference.gui.persistence/src/org/cishell/reference/gui/persistence/load/FileLoaderAlgorithmFactory.java =================================================================== --- trunk/clients/gui/org.cishell.reference.gui.persistence/src/org/cishell/reference/gui/persistence/load/FileLoaderAlgorithmFactory.java (rev 0) +++ trunk/clients/gui/org.cishell.reference.gui.persistence/src/org/cishell/reference/gui/persistence/load/FileLoaderAlgorithmFactory.java 2011-02-08 17:27:54 UTC (rev 1197) @@ -0,0 +1,40 @@ +package org.cishell.reference.gui.persistence.load; + +import java.io.File; +import java.util.Dictionary; + +import org.cishell.framework.CIShellContext; +import org.cishell.framework.algorithm.Algorithm; +import org.cishell.framework.algorithm.AlgorithmFactory; +import org.cishell.framework.algorithm.ProgressMonitor; +import org.cishell.framework.data.Data; +import org.osgi.framework.BundleContext; +import org.osgi.service.component.ComponentContext; +import org.osgi.service.log.LogService; + +public class FileLoaderAlgorithmFactory implements AlgorithmFactory { + private BundleContext bundleContext; + private LogService logger; + + protected void activate(ComponentContext componentContext) { + this.bundleContext = componentContext.getBundleContext(); + this.logger = (LogService) this.bundleContext.getService( + this.bundleContext.getServiceReference(LogService.class.getName())); + } + + public Algorithm createAlgorithm( + Data[] data, Dictionary<String, Object> parameters, CIShellContext ciShellContext) { + File[] filesToLoad = new File[data.length]; + + for (int ii = 0; ii < data.length; ii++) { + filesToLoad[ii] = (File) data[ii].getData(); + } + + return new FileLoaderAlgorithm( + this.bundleContext, + filesToLoad, + ciShellContext, + this.logger, + ProgressMonitor.NULL_MONITOR); + } +} \ No newline at end of file Modified: trunk/core/org.cishell.framework/META-INF/MANIFEST.MF =================================================================== --- trunk/core/org.cishell.framework/META-INF/MANIFEST.MF 2011-02-04 16:25:21 UTC (rev 1196) +++ trunk/core/org.cishell.framework/META-INF/MANIFEST.MF 2011-02-08 17:27:54 UTC (rev 1197) @@ -5,11 +5,13 @@ Bundle-Version: 1.0.0 Bundle-Vendor: Cyberinfrastructure for Network Science Center Bundle-RequiredExecutionEnvironment: J2SE-1.5 -Import-Package: org.osgi.framework, +Import-Package: org.eclipse.osgi.framework.internal.core, + org.osgi.framework, org.osgi.service.log, org.osgi.service.metatype, org.osgi.service.prefs Export-Package: org.cishell.app.service.datamanager;version="1.0.0", + org.cishell.app.service.fileloader, org.cishell.app.service.scheduler;version="1.0.0", org.cishell.framework;version="1.0.0", org.cishell.framework.algorithm;version="1.0.0", Added: trunk/core/org.cishell.framework/src/org/cishell/app/service/fileloader/FileLoadException.java =================================================================== --- trunk/core/org.cishell.framework/src/org/cishell/app/service/fileloader/FileLoadException.java (rev 0) +++ trunk/core/org.cishell.framework/src/org/cishell/app/service/fileloader/FileLoadException.java 2011-02-08 17:27:54 UTC (rev 1197) @@ -0,0 +1,21 @@ +package org.cishell.app.service.fileloader; + +public class FileLoadException extends Exception { + private static final long serialVersionUID = 1L; + + public FileLoadException(String message, Throwable exception) { + super(message, exception); + } + + public FileLoadException(Throwable exception) { + super(exception); + } + + public FileLoadException(String message) { + super(message); + } + + public FileLoadException() { + this("Algorithm canceled by user."); + } +} Added: trunk/core/org.cishell.framework/src/org/cishell/app/service/fileloader/FileLoadListener.java =================================================================== --- trunk/core/org.cishell.framework/src/org/cishell/app/service/fileloader/FileLoadListener.java (rev 0) +++ trunk/core/org.cishell.framework/src/org/cishell/app/service/fileloader/FileLoadListener.java 2011-02-08 17:27:54 UTC (rev 1197) @@ -0,0 +1,7 @@ +package org.cishell.app.service.fileloader; + +import java.io.File; + +public interface FileLoadListener { + void fileLoaded(File file); +} \ No newline at end of file Added: trunk/core/org.cishell.framework/src/org/cishell/app/service/fileloader/FileLoaderService.java =================================================================== --- trunk/core/org.cishell.framework/src/org/cishell/app/service/fileloader/FileLoaderService.java (rev 0) +++ trunk/core/org.cishell.framework/src/org/cishell/app/service/fileloader/FileLoaderService.java 2011-02-08 17:27:54 UTC (rev 1197) @@ -0,0 +1,32 @@ +package org.cishell.app.service.fileloader; + +import java.io.File; + +import org.cishell.framework.CIShellContext; +import org.cishell.framework.algorithm.ProgressMonitor; +import org.cishell.framework.data.Data; +import org.osgi.framework.BundleContext; +import org.osgi.service.log.LogService; + +public interface FileLoaderService { + public void registerListener(FileLoadListener listener); + public void unregisterListener(FileLoadListener listener); + + public Data[] loadFilesFromUserSelection( + BundleContext bundleContext, + CIShellContext ciShellContext, + LogService logger, + ProgressMonitor progressMonitor) throws FileLoadException; + public Data[] loadFiles( + BundleContext bundleContext, + CIShellContext ciShellContext, + LogService logger, + ProgressMonitor progressMonitor, + File[] files) throws FileLoadException; + public Data[] loadFile( + BundleContext bundleContext, + CIShellContext ciShellContext, + LogService logger, + ProgressMonitor progressMonitor, + File file) throws FileLoadException; +} \ No newline at end of file Added: trunk/core/org.cishell.framework/src/org/cishell/framework/CIShellContextDelegate.java =================================================================== --- trunk/core/org.cishell.framework/src/org/cishell/framework/CIShellContextDelegate.java (rev 0) +++ trunk/core/org.cishell.framework/src/org/cishell/framework/CIShellContextDelegate.java 2011-02-08 17:27:54 UTC (rev 1197) @@ -0,0 +1,25 @@ +package org.cishell.framework; + +import org.osgi.framework.ServiceReference; +import org.osgi.service.log.LogService; + +public class CIShellContextDelegate implements CIShellContext { + private ServiceReference uniqueServiceReference; + private CIShellContext actualCIShellContext; + + public CIShellContextDelegate( + ServiceReference uniqueServiceReference, CIShellContext actualCIShellContext) { + this.uniqueServiceReference = uniqueServiceReference; + this.actualCIShellContext = actualCIShellContext; + } + + public Object getService(String service) { + if (LogService.class.getName().equals(service)) { + return new LogServiceDelegate( + this.uniqueServiceReference, + (LogService) this.actualCIShellContext.getService(service)); + } else { + return this.actualCIShellContext.getService(service); + } + } +} \ No newline at end of file Added: trunk/core/org.cishell.framework/src/org/cishell/framework/LogServiceDelegate.java =================================================================== --- trunk/core/org.cishell.framework/src/org/cishell/framework/LogServiceDelegate.java (rev 0) +++ trunk/core/org.cishell.framework/src/org/cishell/framework/LogServiceDelegate.java 2011-02-08 17:27:54 UTC (rev 1197) @@ -0,0 +1,32 @@ +package org.cishell.framework; + +import org.osgi.framework.ServiceReference; +import org.osgi.service.log.LogService; + +public class LogServiceDelegate implements LogService { + private ServiceReference uniqueServiceReference; + private LogService actualLogService; + + public LogServiceDelegate( + ServiceReference uniqueServiceReference, LogService actualLogService) { + this.uniqueServiceReference = uniqueServiceReference; + this.actualLogService = actualLogService; + } + + public void log(int level, String message) { + this.actualLogService.log(this.uniqueServiceReference, level, message); + } + + public void log(int level, String message, Throwable exception) { + this.actualLogService.log(this.uniqueServiceReference, level, message, exception); + } + + public void log(ServiceReference serviceReference, int level, String message) { + this.actualLogService.log(serviceReference, level, message); + } + + public void log( + ServiceReference serviceReference, int level, String message, Throwable exception) { + this.actualLogService.log(serviceReference, level, message, exception); + } +} \ No newline at end of file Added: trunk/core/org.cishell.framework/src/org/cishell/framework/ServiceReferenceDelegate.java =================================================================== --- trunk/core/org.cishell.framework/src/org/cishell/framework/ServiceReferenceDelegate.java (rev 0) +++ trunk/core/org.cishell.framework/src/org/cishell/framework/ServiceReferenceDelegate.java 2011-02-08 17:27:54 UTC (rev 1197) @@ -0,0 +1,86 @@ +package org.cishell.framework; + +import java.lang.reflect.Field; + +import org.eclipse.osgi.framework.internal.core.ServiceReferenceImpl; +import org.eclipse.osgi.framework.internal.core.ServiceRegistrationImpl; +import org.osgi.framework.Bundle; +import org.osgi.framework.ServiceReference; + +public class ServiceReferenceDelegate extends ServiceReferenceImpl { + public static final String REGISTRATION_FIELD_NAME = + "org.eclipse.osgi.framework.internal.core.ServiceReferenceImpl.registration"; + + private static int nextUniqueID = 0; + + private ServiceReference actualServiceReference; + private int uniqueID; + + public ServiceReferenceDelegate(ServiceReference actualServiceReference) { + super(getServiceRegistration(actualServiceReference)); + this.actualServiceReference = actualServiceReference; + this.uniqueID = nextUniqueID; + nextUniqueID++; + + } + + public Object getProperty(String key) { + return this.actualServiceReference.getProperty(key); + } + + public String[] getPropertyKeys() { + return this.actualServiceReference.getPropertyKeys(); + } + + public Bundle getBundle() { + return this.actualServiceReference.getBundle(); + } + + public Bundle[] getUsingBundles() { + return this.actualServiceReference.getUsingBundles(); + } + + public boolean isAssignableTo(Bundle bundle, String className) { + return this.actualServiceReference.isAssignableTo(bundle, className); + } + + @Override + public int compareTo(Object reference) { + if (reference instanceof ServiceReferenceDelegate) { + ServiceReferenceDelegate otherDelegate = (ServiceReferenceDelegate) reference; + + return new Integer(this.uniqueID).compareTo(new Integer(otherDelegate.uniqueID)); + } else { + return this.actualServiceReference.compareTo(reference); + } + } + + @Override + public int hashCode() { + return this.actualServiceReference.hashCode() + new Integer(this.uniqueID).hashCode(); + } + + // TODO: Totally, disginstingly hacky. + private static ServiceRegistrationImpl getServiceRegistration( + ServiceReference actualServiceReference) { + try { + Field[] fields = actualServiceReference.getClass().getDeclaredFields(); + +// for (Field field : fields) { +// System.err.println(field); +// } + Field registrationField = fields[0]; +// actualServiceReference.getClass().getField(REGISTRATION_FIELD_NAME); + boolean isAccessible = registrationField.isAccessible(); + registrationField.setAccessible(true); + Object serviceRegistration = registrationField.get(actualServiceReference); + registrationField.setAccessible(isAccessible); + + return (ServiceRegistrationImpl) serviceRegistration; + } catch (IllegalAccessException e) { + throw new RuntimeException(e.getMessage(), e); + } /* catch (NoSuchFieldException e) { + throw new RuntimeException(e.getMessage(), e); + } */ + } +} \ No newline at end of file Added: trunk/core/org.cishell.framework/src/org/cishell/framework/algorithm/AlgorithmFactory2.java =================================================================== --- trunk/core/org.cishell.framework/src/org/cishell/framework/algorithm/AlgorithmFactory2.java (rev 0) +++ trunk/core/org.cishell.framework/src/org/cishell/framework/algorithm/AlgorithmFactory2.java 2011-02-08 17:27:54 UTC (rev 1197) @@ -0,0 +1,7 @@ +package org.cishell.framework.algorithm; + +import org.osgi.framework.ServiceReference; + +public interface AlgorithmFactory2 { + public void setServiceReference(ServiceReference serviceReference); +} \ No newline at end of file Modified: trunk/core/org.cishell.framework/src/org/cishell/framework/data/DataProperty.java =================================================================== --- trunk/core/org.cishell.framework/src/org/cishell/framework/data/DataProperty.java 2011-02-04 16:25:21 UTC (rev 1196) +++ trunk/core/org.cishell.framework/src/org/cishell/framework/data/DataProperty.java 2011-02-08 17:27:54 UTC (rev 1197) @@ -60,6 +60,9 @@ * it. The type associated with this property is of type {@link Boolean}. */ public static final String MODIFIED = "Modified"; + + // TODO: Document me. + public static final String SERVICE_REFERENCE = "ServiceReference"; /** Says this data model is abstractly a matrix */ public static String MATRIX_TYPE = "Matrix"; Modified: trunk/core/org.cishell.reference/META-INF/MANIFEST.MF =================================================================== --- trunk/core/org.cishell.reference/META-INF/MANIFEST.MF 2011-02-04 16:25:21 UTC (rev 1196) +++ trunk/core/org.cishell.reference/META-INF/MANIFEST.MF 2011-02-08 17:27:54 UTC (rev 1197) @@ -3,21 +3,28 @@ Bundle-SymbolicName: org.cishell.reference Bundle-Version: 1.0.0 Import-Package: org.cishell.app.service.datamanager;version="1.0.0", + org.cishell.app.service.fileloader, org.cishell.app.service.scheduler;version="1.0.0", org.cishell.framework;version="1.0.0", org.cishell.framework.algorithm;version="1.0.0", org.cishell.framework.data;version="1.0.0", + org.cishell.reference.gui.common, org.cishell.service.conversion;version="1.0.0", org.cishell.service.guibuilder;version="1.0.0", org.osgi.framework, + org.osgi.service.cm;version="1.2.0", org.osgi.service.log, org.osgi.service.metatype;version="1.1.0", org.osgi.service.prefs Export-Package: org.cishell.reference.app.service.algorithminvocation, org.cishell.reference.app.service.datamanager, + org.cishell.reference.app.service.fileloader, org.cishell.reference.app.service.scheduler, org.cishell.reference.service.conversion, org.cishell.reference.service.metatype -Eclipse-LazyStart: true -Require-Bundle: edu.uci.ics.jung +Require-Bundle: edu.uci.ics.jung, + org.eclipse.swt, + org.eclipse.ui +Service-Component: OSGI-INF/fileloader.xml Bundle-RequiredExecutionEnvironment: J2SE-1.5 +X-AutoStart: true Added: trunk/core/org.cishell.reference/OSGI-INF/fileloader.properties =================================================================== --- trunk/core/org.cishell.reference/OSGI-INF/fileloader.properties (rev 0) +++ trunk/core/org.cishell.reference/OSGI-INF/fileloader.properties 2011-02-08 17:27:54 UTC (rev 1197) @@ -0,0 +1,11 @@ +#menu_path=File/start +#label=Load... +#shortcut=ctrl+alt+o +#description=This allows users to select files from the file system and load them to Data Model window. +#in_data=null +#out_data=java.lang.Object +service.pid=org.cishell.reference.app.service.fileloader.FileLoadServiceImpl +remoteable=true +prefs_published=local +receive_prefs=true +#documentation_url=http://wiki.slis.indiana.edu:8080/display/ALGDOC/Data+Formats \ No newline at end of file Added: trunk/core/org.cishell.reference/OSGI-INF/fileloader.xml =================================================================== --- trunk/core/org.cishell.reference/OSGI-INF/fileloader.xml (rev 0) +++ trunk/core/org.cishell.reference/OSGI-INF/fileloader.xml 2011-02-08 17:27:54 UTC (rev 1197) @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<component name="org.cishell.reference.app.service.fileloader.FileLoaderServiceImpl.component" immediate="true"> + <implementation class="org.cishell.reference.app.service.fileloader.FileLoaderServiceImpl"/> + <service> + <provide interface="org.osgi.service.cm.ManagedService"/> + <provide interface="org.cishell.app.service.fileloader.FileLoaderService"/> + </service> +</component> \ No newline at end of file Modified: trunk/core/org.cishell.reference/build.properties =================================================================== --- trunk/core/org.cishell.reference/build.properties 2011-02-04 16:25:21 UTC (rev 1196) +++ trunk/core/org.cishell.reference/build.properties 2011-02-08 17:27:54 UTC (rev 1197) @@ -1,4 +1,5 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ - . + .,\ + OSGI-INF/ Added: trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/FileFormatSelector.java =================================================================== --- trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/FileFormatSelector.java (rev 0) +++ trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/FileFormatSelector.java 2011-02-08 17:27:54 UTC (rev 1197) @@ -0,0 +1,190 @@ +package org.cishell.reference.app.service.fileloader; + +import java.io.File; + +import org.cishell.framework.algorithm.AlgorithmFactory; +import org.cishell.reference.gui.common.AbstractDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.List; +import org.eclipse.swt.widgets.Shell; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; + +public class FileFormatSelector extends AbstractDialog { + private BundleContext bundleContext; + private AlgorithmFactory validator; + private ServiceReference[] validatorReferences; + private List validatorList; + +// private static final String[] DETAILS_ITEM_KEY = +// {"format_name", "supported_file_extension", "format_description" }; + + /* + * Other possible keys could be restorable_model_name, restorable_model_description + * */ + +// private static final String[] DETAILS_ITEM_KEY_DISPLAY_VALUE = +// {"Format name", "Supported file extension", "Format description"}; + + /* + * Other possible keys display values could be "Restorable model name", + * "Restorable model description" + */ + + public FileFormatSelector( + String title, + Shell parent, + BundleContext bundleContext, + ServiceReference[] validatorReferences, + File file) { + super(parent, title, AbstractDialog.QUESTION); + this.bundleContext = bundleContext; + this.validatorReferences = validatorReferences; + + // Shall this part be moved out of the code? + String descriptionFormat = + "The file \'%s\' can be loaded using one or more of the following formats.%n" + + "Please select the format you would like to try."; + setDescription(String.format(descriptionFormat, file.getAbsolutePath())); + setDetails( + "This dialog allows the user to choose among all available " + + "formats for loading the selected data model. Choose any of the formats " + + "to continue loading the dataset."); + } + + public AlgorithmFactory getValidator() { + return this.validator; + } + + private Composite initializeGUI(Composite parent) { + Composite content = new Composite(parent, SWT.NONE); + + GridLayout layout = new GridLayout(); + layout.numColumns = 1; + content.setLayout(layout); + + Group validatorGroup = new Group(content, SWT.NONE); + // Shall this label be moved out of the code? + validatorGroup.setText("Load as..."); + validatorGroup.setLayout(new FillLayout()); + GridData validatorListGridData = new GridData(GridData.FILL_BOTH); + validatorListGridData.widthHint = 200; + validatorGroup.setLayoutData(validatorListGridData); + + this.validatorList = new List(validatorGroup, SWT.H_SCROLL |SWT.V_SCROLL | SWT.SINGLE); + // initPersisterArray(); + initializePersisterList(); + this.validatorList.addMouseListener(new MouseAdapter() { + public void mouseDoubleClick(MouseEvent mouseEvent) { + List list = (List)mouseEvent.getSource(); + int selection = list.getSelectionIndex(); + + if (selection != -1) { + selectionMade(selection); + } + } + }); + + this.validatorList.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent selectionEvent) { + List list = (List)selectionEvent.getSource(); + int selection = list.getSelectionIndex(); + + if (selection != -1) { + // updateDetailPane(validatorReferences[selection]); + } + } + }); + + validatorList.setSelection(0); + + return content; + } + + private void initializePersisterList() { + for (int ii = 0; ii < this.validatorReferences.length; ++ii) { + String name = (String)this.validatorReferences[ii].getProperty("label"); + + /* + * If someone was sloppy enough to not provide a name, then use the name of the + * class instead. + */ + if (name == null || name.length() == 0) { + name = this.validatorReferences[ii].getClass().getName(); + } + + this.validatorList.add(name); + } + } + + private void selectionMade(int selectedIndex) { + this.validator = + (AlgorithmFactory)this.bundleContext.getService(this.validatorReferences[selectedIndex]); + close(true); +// AlgorithmFactory validator = +// (AlgorithmFactory)this.bundleContext.getService(this.persisterArray[selectedIndex]); +// Data[] data = null; +// boolean loadSuccess = false; +// +// try { +// data = +// new Data[] { new BasicData(this.selectedFile.getPath(), String.class.getName()) }; +// data = validator.createAlgorithm(data, null, this.ciShellContext).execute(); +// loadSuccess = true; +// } catch (Throwable exception) { +// this.logger.log( +// LogService.LOG_ERROR, "Error occurred while executing selection", exception); +// exception.printStackTrace(); +// loadSuccess = false; +// } +// +// if ((data != null) && loadSuccess) { +// this.logger.log(LogService.LOG_INFO, "Loaded: " + this.selectedFile.getPath()); +// +// for (int ii = 0; ii < data.length; ii++) { +// this.returnList.add(data[ii]); +// } +// +// close(true); +// } else { +// this.logger.log(LogService.LOG_ERROR, "Unable to load with selected loader"); +// } + } + + public void createDialogButtons(Composite parent) { + Button select = new Button(parent, SWT.PUSH); + select.setText("Select"); + select.addSelectionListener(new SelectionAdapter(){ + public void widgetSelected(SelectionEvent selectionEvent) { + int index = FileFormatSelector.this.validatorList.getSelectionIndex(); + + if (index != -1) { + selectionMade(index); + } + } + }); + select.setFocus(); + + Button cancel = new Button(parent, SWT.NONE); + cancel.setText("Cancel"); + cancel.addSelectionListener(new SelectionAdapter(){ + public void widgetSelected(SelectionEvent selectionEvent) { + close(false); + } + }); + } + + public Composite createContent(Composite parent) { + return initializeGUI(parent); + } +} Added: trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/FileLoaderServiceImpl.java =================================================================== --- trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/FileLoaderServiceImpl.java (rev 0) +++ trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/FileLoaderServiceImpl.java 2011-02-08 17:27:54 UTC (rev 1197) @@ -0,0 +1,223 @@ +package org.cishell.reference.app.service.fileloader; + +import java.io.File; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Dictionary; +import java.util.HashSet; + +import org.cishell.app.service.fileloader.FileLoadException; +import org.cishell.app.service.fileloader.FileLoadListener; +import org.cishell.app.service.fileloader.FileLoaderService; +import org.cishell.framework.CIShellContext; +import org.cishell.framework.algorithm.AlgorithmExecutionException; +import org.cishell.framework.algorithm.AlgorithmFactory; +import org.cishell.framework.algorithm.ProgressMonitor; +import org.cishell.framework.data.Data; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.osgi.framework.BundleContext; +import org.osgi.service.cm.ConfigurationException; +import org.osgi.service.cm.ManagedService; +import org.osgi.service.log.LogService; + +public class FileLoaderServiceImpl implements FileLoaderService, ManagedService { + public static final String LOAD_DIRECTORY_PREFERENCE_KEY = "loadDir"; + public static String defaultLoadDirectory = ""; + + private Dictionary preferences; + private Collection<FileLoadListener> listeners = new HashSet<FileLoadListener>(); + + public void registerListener(FileLoadListener listener) { + this.listeners.add(listener); + } + + public void unregisterListener(FileLoadListener listener) { + if (this.listeners.contains(listener)) { + this.listeners.remove(listener); + } + } + + public Data[] loadFilesFromUserSelection( + BundleContext bundleContext, + CIShellContext ciShellContext, + LogService logger, + ProgressMonitor progressMonitor) throws FileLoadException { + if ("".equals(defaultLoadDirectory)) { + defaultLoadDirectory = determineDefaultLoadDirectory(); + } + + IWorkbenchWindow window = getFirstWorkbenchWindow(); + Display display = PlatformUI.getWorkbench().getDisplay(); + File[] files = getFilesToLoadFromUser(window, display); + + if (files != null) { + return loadFiles(bundleContext, ciShellContext, logger, progressMonitor, files); + } else { + return null; + } + } + + public Data[] loadFiles( + BundleContext bundleContext, + CIShellContext ciShellContext, + LogService logger, + ProgressMonitor progressMonitor, + File[] files) throws FileLoadException { + return loadFilesInternal(bundleContext, ciShellContext, logger, progressMonitor, files); + } + + public Data[] loadFile( + BundleContext bundleContext, + CIShellContext ciShellContext, + LogService logger, + ProgressMonitor progressMonitor, + File file) throws FileLoadException { + return loadFiles( + bundleContext, ciShellContext, logger, progressMonitor, new File[] { file }); + } + + public void updated(Dictionary preferences) throws ConfigurationException { + if (preferences != null) { + this.preferences = preferences; + } + } + + private String determineDefaultLoadDirectory() { + if (this.preferences != null) { + Object directoryPreference = preferences.get(LOAD_DIRECTORY_PREFERENCE_KEY); + + if (directoryPreference != null) { + return directoryPreference.toString(); + } else { + return ""; + } + } else { + return ""; + } + } + + private Data[] loadFilesInternal( + BundleContext bundleContext, + CIShellContext ciShellContext, + LogService logger, + ProgressMonitor progressMonitor, + File[] files) throws FileLoadException { + IWorkbenchWindow window = getFirstWorkbenchWindow(); + Display display = PlatformUI.getWorkbench().getDisplay(); + + if ((files != null) && (files.length != 0)) { + Collection<Data> finalLabeledFileData = new ArrayList<Data>(); + + for (File file : files) { + try { + Data[] validatedFileData = validateFile( + bundleContext, + ciShellContext, + logger, + progressMonitor, + window, + display, + file); + Data[] labeledFileData = labelFileData(file, validatedFileData); + + for (Data data : labeledFileData) { + finalLabeledFileData.add(data); + } + } catch (Throwable e) { + String format = + "The chosen file is not compatible with this format. " + + "Check that your file is correctly formatted or try another validator. " + + "The reason is: %s"; + String logMessage = String.format(format, e.getMessage()); + logger.log(LogService.LOG_ERROR, logMessage, e); + } + } + + return finalLabeledFileData.toArray(new Data[0]); + } else { + return null; + } + } + + private IWorkbenchWindow getFirstWorkbenchWindow() throws FileLoadException { + final IWorkbenchWindow[] windows = PlatformUI.getWorkbench().getWorkbenchWindows(); + + if (windows.length == 0) { + throw new FileLoadException( + "Cannot obtain workbench window needed to open dialog."); + } else { + return windows[0]; + } + } + + private File[] getFilesToLoadFromUser(IWorkbenchWindow window, Display display) { + FileSelectorRunnable fileSelector = new FileSelectorRunnable(window); + + if (Thread.currentThread() != display.getThread()) { + display.syncExec(fileSelector); + } else { + fileSelector.run(); + } + + return fileSelector.getFiles(); + } + + private Data[] validateFile( + BundleContext bundleContext, + CIShellContext ciShellContext, + LogService logger, + ProgressMonitor progressMonitor, + IWorkbenchWindow window, + Display display, + File file) throws AlgorithmExecutionException { + AlgorithmFactory validator = null; + validator = getValidatorFromUser(bundleContext, window, display, file); + + if ((file == null) || (validator == null)) { + String logMessage = "File loading canceled"; + logger.log(LogService.LOG_WARNING, logMessage); + } else { + try { + return FileValidator.validateFile( + file, validator, progressMonitor, ciShellContext, logger); + } catch (AlgorithmExecutionException e) { + if ((e.getCause() != null) + && (e.getCause() instanceof UnsupportedEncodingException)) { + String format = + "This file cannot be loaded; it uses the unsupported character " + + "encoding %s."; + String logMessage = String.format(format, e.getCause().getMessage()); + logger.log(LogService.LOG_ERROR, logMessage); + } else { + throw e; + } + } + } + + return new Data[0]; + } + + private Data[] labelFileData(File file, Data[] validatedFileData) { + Data[] labeledFileData = + PrettyLabeler.relabelWithFileNameHierarchy(validatedFileData, file); + + return labeledFileData; + } + + private AlgorithmFactory getValidatorFromUser( + BundleContext bundleContext, IWorkbenchWindow window, Display display, File file) { + ValidatorSelectorRunnable validatorSelector = + new ValidatorSelectorRunnable(window, bundleContext, file); + + if (Thread.currentThread() != display.getThread()) { + display.syncExec(validatorSelector); + } else { + validatorSelector.run(); + } + + return validatorSelector.getValidator(); + } +} \ No newline at end of file Added: trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/FileSelectorRunnable.java =================================================================== --- trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/FileSelectorRunnable.java (rev 0) +++ trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/FileSelectorRunnable.java 2011-02-08 17:27:54 UTC (rev 1197) @@ -0,0 +1,63 @@ +package org.cishell.reference.app.service.fileloader; + +import java.io.File; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.ui.IWorkbenchWindow; + +public final class FileSelectorRunnable implements Runnable { + private IWorkbenchWindow window; + + private File[] files; + + public FileSelectorRunnable(IWorkbenchWindow window) { + this.window = window; + } + + public File[] getFiles() { + return this.files; + } + + public void run() { + this.files = getFilesFromUser(); + + if (this.files.length == 0) { + return; + } else { + FileLoaderServiceImpl.defaultLoadDirectory = + this.files[0].getParentFile().getAbsolutePath(); + } + } + + private File[] getFilesFromUser() { + FileDialog fileDialog = createFileDialog(); + fileDialog.open(); + String path = fileDialog.getFilterPath(); + String[] fileNames = fileDialog.getFileNames(); + // TODO: Ask Angela about the order here, i.e. should they be sorted alphabetically? + + if ((fileNames == null) || (fileNames.length == 0)) { + return new File[0]; + } else { + File[] files = new File[fileNames.length]; + + for (int ii = 0; ii < fileNames.length; ii++) { + String fullFileName = path + File.separator + fileNames[ii]; + files[ii] = new File(fullFileName); + } + + return files; + } + } + + private FileDialog createFileDialog() { + File currentDirectory = new File(FileLoaderServiceImpl.defaultLoadDirectory); + String absolutePath = currentDirectory.getAbsolutePath(); + FileDialog fileDialog = new FileDialog(this.window.getShell(), SWT.OPEN | SWT.MULTI); + fileDialog.setFilterPath(absolutePath); + fileDialog.setText("Select Files"); + + return fileDialog; + } +} \ No newline at end of file Added: trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/FileValidator.java =================================================================== --- trunk/core/org.cis... [truncated message content] |