Browse Source

148190#32

tags/Root_extensions
aclement 17 years ago
parent
commit
7358a5c2ba
18 changed files with 1340 additions and 1101 deletions
  1. 144
    143
      ajbrowser/src/org/aspectj/tools/ajbrowser/BrowserManager.java
  2. 0
    177
      ajbrowser/src/org/aspectj/tools/ajbrowser/BrowserProperties.java
  3. 0
    104
      ajbrowser/src/org/aspectj/tools/ajbrowser/CompilerMessagesPanel.java
  4. 0
    545
      ajbrowser/src/org/aspectj/tools/ajbrowser/TopFrame.java
  5. 88
    0
      ajbrowser/src/org/aspectj/tools/ajbrowser/core/BrowserBuildProgressMonitor.java
  6. 97
    0
      ajbrowser/src/org/aspectj/tools/ajbrowser/core/BrowserCompilerConfiguration.java
  7. 54
    0
      ajbrowser/src/org/aspectj/tools/ajbrowser/core/BrowserErrorHandler.java
  8. 60
    0
      ajbrowser/src/org/aspectj/tools/ajbrowser/core/BrowserOutputLocationManager.java
  9. 24
    0
      ajbrowser/src/org/aspectj/tools/ajbrowser/core/PreferenceStoreConstants.java
  10. 7
    5
      ajbrowser/src/org/aspectj/tools/ajbrowser/ui/BasicEditor.java
  11. 94
    0
      ajbrowser/src/org/aspectj/tools/ajbrowser/ui/BrowserMessageHandler.java
  12. 38
    0
      ajbrowser/src/org/aspectj/tools/ajbrowser/ui/BrowserRuntimeProperties.java
  13. 7
    2
      ajbrowser/src/org/aspectj/tools/ajbrowser/ui/BrowserUIAdapter.java
  14. 4
    3
      ajbrowser/src/org/aspectj/tools/ajbrowser/ui/EditorManager.java
  15. 37
    15
      ajbrowser/src/org/aspectj/tools/ajbrowser/ui/swing/BrowserOptionsPanel.java
  16. 87
    0
      ajbrowser/src/org/aspectj/tools/ajbrowser/ui/swing/MessageHandlerPanel.java
  17. 599
    0
      ajbrowser/src/org/aspectj/tools/ajbrowser/ui/swing/TopFrame.java
  18. 0
    107
      ajbrowser/testsrc/org/aspectj/tools/ajbrowser/InteractiveBrowserTest.java

+ 144
- 143
ajbrowser/src/org/aspectj/tools/ajbrowser/BrowserManager.java View File

@@ -8,45 +8,66 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Xerox/PARC initial implementation
* Xerox/PARC initial implementation
* Helen Hawkins Converted to new interface (bug 148190)
* ******************************************************************/


package org.aspectj.tools.ajbrowser;

import java.io.IOException;
import java.util.*;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;

import org.aspectj.ajde.*;
import org.aspectj.ajde.ui.*;
import org.aspectj.ajde.Ajde;
import org.aspectj.ajde.IconRegistry;
import org.aspectj.ajde.internal.BuildConfigManager;
import org.aspectj.ajde.ui.FileStructureView;
import org.aspectj.ajde.ui.InvalidResourceException;
import org.aspectj.ajde.ui.UserPreferencesAdapter;
import org.aspectj.ajde.ui.internal.UserPreferencesStore;
import org.aspectj.ajde.ui.swing.*;
import org.aspectj.asm.*;
import org.aspectj.ajde.ui.javaoptions.JavaBuildOptions;
import org.aspectj.ajde.ui.javaoptions.JavaCompilerWarningsOptionsPanel;
import org.aspectj.ajde.ui.javaoptions.JavaComplianceOptionsPanel;
import org.aspectj.ajde.ui.javaoptions.JavaDebugOptionsPanel;
import org.aspectj.ajde.ui.javaoptions.JavaOtherOptionsPanel;
import org.aspectj.ajde.ui.swing.MultiStructureViewPanel;
import org.aspectj.asm.AsmManager;
import org.aspectj.asm.IHierarchy;
import org.aspectj.asm.IHierarchyListener;
import org.aspectj.tools.ajbrowser.core.BrowserBuildProgressMonitor;
import org.aspectj.tools.ajbrowser.core.BrowserCompilerConfiguration;
import org.aspectj.tools.ajbrowser.core.BrowserErrorHandler;
import org.aspectj.tools.ajbrowser.ui.BasicEditor;
import org.aspectj.tools.ajbrowser.ui.BrowserMessageHandler;
import org.aspectj.tools.ajbrowser.ui.BrowserRuntimeProperties;
import org.aspectj.tools.ajbrowser.ui.BrowserUIAdapter;
import org.aspectj.tools.ajbrowser.ui.EditorManager;
import org.aspectj.tools.ajbrowser.ui.swing.BrowserOptionsPanel;
import org.aspectj.tools.ajbrowser.ui.swing.MessageHandlerPanel;
import org.aspectj.tools.ajbrowser.ui.swing.TopFrame;
import org.aspectj.util.FileUtil;
//import org.aspectj.asm.internal.*;

/**
* IDE manager for standalone AJDE application.
*
* @author Mik Kersten
*
* @author Mik Kersten
*/
public class BrowserManager {

public static final String TITLE = "AspectJ Browser";

private static final BrowserManager INSTANCE = new BrowserManager();
private BrowserProperties browserProjectProperties;
private EditorManager editorManager;
private UserPreferencesAdapter preferencesAdapter;
private static TopFrame topFrame = null;

private List configFiles = new ArrayList();
private JavaBuildOptions javaBuildOptions;
public static BrowserManager getDefault() {
return INSTANCE;
}
private List configFiles = new ArrayList();
public static final String TITLE = "AspectJ Browser";
private static TopFrame topFrame = null;
public final IHierarchyListener VIEW_LISTENER = new IHierarchyListener() {
public void elementsUpdated(IHierarchy model) {
@@ -55,73 +76,75 @@ public class BrowserManager {
fsv.setSourceFile(BrowserManager.getDefault().getEditorManager().getCurrFile());
}
}
};
};
public void init(String[] configFilesArgs, boolean visible) {
try {
UserPreferencesAdapter preferencesAdapter = new UserPreferencesStore(true);
browserProjectProperties = new BrowserProperties(preferencesAdapter);
TaskListManager taskListManager = new CompilerMessagesPanel();
javaBuildOptions = new JavaBuildOptions();
preferencesAdapter = new UserPreferencesStore(true);
topFrame = new TopFrame();

BasicEditor ajdeEditor = new BasicEditor();
BrowserUIAdapter browserUIAdapter = new BrowserUIAdapter();
topFrame = new TopFrame();
configFiles = getConfigFilesList(configFilesArgs);

AjdeUIManager.getDefault().init(
ajdeEditor,
taskListManager,
browserProjectProperties,
preferencesAdapter,
browserUIAdapter,
new IconRegistry(),
topFrame,
true);
editorManager = new EditorManager(ajdeEditor);
Ajde.getDefault().getBuildManager().addListener(BUILD_MESSAGES_LISTENER);
MultiStructureViewPanel multiViewPanel = new MultiStructureViewPanel(
AjdeUIManager.getDefault().getViewManager().getBrowserPanel(),
AjdeUIManager.getDefault().getFileStructurePanel()
);
BrowserMessageHandler messageHandler = new BrowserMessageHandler();
topFrame.init(
multiViewPanel,
(CompilerMessagesPanel)taskListManager,
editorManager.getEditorPanel()
);
if (visible) topFrame.setVisible(true);
if (configFiles.size() == 0) {
Ajde.getDefault().getErrorHandler().handleWarning(
"No build configuration selected. "
+ "Select a \".lst\" build configuration file in order to compile and navigate structure.");
} else {
//UiManager.getDefault().getViewManager().updateConfigsList();
}
AjdeUIManager.getDefault().getOptionsFrame().addOptionsPanel(new BrowserOptionsPanel());
AsmManager.getDefault().addListener(VIEW_LISTENER);
//String lastOpenFilePath = browserProjectProperties.getLastOpenSourceFilePath();
//editorManager.showSourceLine(lastOpenFilePath, 1, false);
//Ajde.getDefault().getStructureViewManager().fireNavigationAction(lastOpenFilePath, 6);
//Ajde.getDefault().enableLogging(System.out);
if (configFilesArgs.length > 0 && configFilesArgs[0] != null) {
Ajde.getDefault().getConfigurationManager().setActiveConfigFile(configFilesArgs[0]);
}
Ajde.getDefault().init(
new BrowserCompilerConfiguration(preferencesAdapter),
messageHandler,
new BrowserBuildProgressMonitor(messageHandler),
ajdeEditor,
new BrowserUIAdapter(),
new IconRegistry(),
topFrame,
new BrowserRuntimeProperties(preferencesAdapter),
true);

setUpTopFrame(visible);
addOptionsPanels();

setUpConfigFiles(configFilesArgs);

AsmManager.getDefault().addListener(VIEW_LISTENER);

} catch (Throwable t) {
t.printStackTrace();
Ajde.getDefault().getErrorHandler().handleError(
"AJDE failed to initialize.",
t);
BrowserErrorHandler.handleError("AJDE failed to initialize.", t);
}
}

/**
* Find and create the set of build configuration files
* @param configFilesArgs
*/
private void setUpConfigFiles(String[] configFilesArgs) {
configFiles = getConfigFilesList(configFilesArgs);
if (configFiles.size() == 0) {
BrowserErrorHandler
.handleWarning("No build configuration selected. "
+ "Select a \".lst\" build configuration file in order to compile and navigate structure.");
} else {
Ajde.getDefault().getBuildConfigManager().setActiveConfigFile(
(String)configFiles.get(0));
}
}

/**
* Create the top frame of the browser
*/
private void setUpTopFrame(boolean visible) {
MultiStructureViewPanel multiViewPanel = new MultiStructureViewPanel(
Ajde.getDefault().getViewManager()
.getBrowserPanel(), Ajde.getDefault()
.getFileStructurePanel());

topFrame.init(multiViewPanel, new MessageHandlerPanel(),
editorManager.getEditorPanel());

if (visible)
topFrame.setVisible(true);
}

public void resetEditorFrame() {
topFrame.resetSourceEditorPanel();
}
@@ -144,36 +167,29 @@ public class BrowserManager {
editorManager.saveContents();
}

public void showMessages() {
topFrame.showMessagesPanel();
}

public void hideMessages() {
topFrame.hideMessagesPanel();
}

public JFrame getRootFrame() {
return topFrame;
}
public JFrame getRootFrame() {
return topFrame;
}

public void openFile(String filePath) {
try {
if (filePath.endsWith(".lst")) {
AjdeUIManager.getDefault().getBuildConfigEditor().openFile(filePath);
topFrame.setEditorPanel(AjdeUIManager.getDefault().getBuildConfigEditor());
Ajde.getDefault().getBuildConfigEditor().openFile(filePath);
topFrame.setEditorPanel(Ajde.getDefault().getBuildConfigEditor());
} else if (FileUtil.hasSourceSuffix(filePath)){
editorManager.showSourceLine(filePath, 0, false);
} else {
Ajde.getDefault().getErrorHandler().handleError("File: " + filePath
+ " could not be opened because the extension was not recoginzed.");
BrowserErrorHandler
.handleError("File: "
+ filePath
+ " could not be opened because the extension was not recoginzed.");
}
} catch (IOException ioe) {
Ajde.getDefault().getErrorHandler().handleError("Could not open file: " + filePath, ioe);
BrowserErrorHandler.handleError("Could not open file: "
+ filePath, ioe);
} catch (InvalidResourceException ire) {
Ajde.getDefault().getErrorHandler().handleError("Invalid file: " + filePath, ire);
}
browserProjectProperties.setLastOpenSourceFilePath(filePath);
BrowserErrorHandler.handleError("Invalid file: " + filePath, ire);
}
}

private List getConfigFilesList(String[] configFiles) {
@@ -185,60 +201,45 @@ public class BrowserManager {
}
return configs;
}

// private static class Runner {
//
// public static void invoke(String className) {
// try {
// if (className == null || className.length() == 0) {
// Ajde.getDefault().getErrorHandler().handleWarning("No main class specified, please select a class to run.");
//
// } else {
// Class[] argTypes = { String[].class };
// java.lang.reflect.Method method = Class.forName(className).getDeclaredMethod("main", argTypes);
// Object[] args = { new String[0] };
// method.invoke(null, args);
// }
// } catch(ClassNotFoundException cnfe) {
// Ajde.getDefault().getErrorHandler().handleWarning("Main class not found: " + className +
// "\nMake sure that you have \".\" on your classpath.");
// } catch(NoSuchMethodException nsme) {
// Ajde.getDefault().getErrorHandler().handleWarning("Class: " + className + " does not declare public static void main(String[])");
// } catch(java.lang.reflect.InvocationTargetException ite) {
// Ajde.getDefault().getErrorHandler().handleWarning("Could not execute: " + className);
// } catch(IllegalAccessException iae) {
// Ajde.getDefault().getErrorHandler().handleWarning("Class: " + className + " does not declare public main method");
// }
// }
// }
private final BuildListener BUILD_MESSAGES_LISTENER = new BuildListener() {
public void compileStarted(String buildConfigFile) { }
public void compileFinished(String buildConfigFile, int buildTime, boolean succeeded, boolean warnings) {
if (succeeded && !warnings) {
hideMessages();
} else {
showMessages();
}
}
public void compileAborted(String buildConfigFile, String message) { }
};
public List getConfigFiles() {
return configFiles;
/**
* Add the different options panels to the main options frame
* (adds panels for java compliance, compiler warnings, debug
* warnings, other java options and options specific to
* ajbrowser)
*/
private void addOptionsPanels() {
Ajde.getDefault().getOptionsFrame().addOptionsPanel(
new JavaComplianceOptionsPanel(javaBuildOptions));
Ajde.getDefault().getOptionsFrame().addOptionsPanel(
new JavaCompilerWarningsOptionsPanel(javaBuildOptions));
Ajde.getDefault().getOptionsFrame().addOptionsPanel(
new JavaOtherOptionsPanel(javaBuildOptions));
Ajde.getDefault().getOptionsFrame().addOptionsPanel(
new JavaDebugOptionsPanel(javaBuildOptions));
Ajde.getDefault().getOptionsFrame().addOptionsPanel(
new BrowserOptionsPanel());
}

public BrowserProperties getBrowserProjectProperties() {
return browserProjectProperties;
}
/**
* @return
* @return the EditorManager
*/
public EditorManager getEditorManager() {
return editorManager;
}
/**
* @return the UserPreferencesAdapter
*/
public UserPreferencesAdapter getPreferencesAdapter() {
return preferencesAdapter;
}

/**
* @return the JavaBuildOptions instance being used
*/
public JavaBuildOptions getJavaBuildOptions() {
return javaBuildOptions;
}

}

+ 0
- 177
ajbrowser/src/org/aspectj/tools/ajbrowser/BrowserProperties.java View File

@@ -1,177 +0,0 @@
/* *******************************************************************
* Copyright (c) 1999-2001 Xerox Corporation,
* 2002 Palo Alto Research Center, Incorporated (PARC).
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Xerox/PARC initial implementation
* AMC 01.20.2003 extended for new AspectJ 1.1 project options
* ******************************************************************/



package org.aspectj.tools.ajbrowser;

import java.util.*;
import java.io.*;
import org.aspectj.ajde.*;
import org.aspectj.ajde.ui.*;

public class BrowserProperties implements ProjectPropertiesAdapter {
UserPreferencesAdapter preferencesAdapter = null;
public BrowserProperties(UserPreferencesAdapter preferencesAdapter) {
this.preferencesAdapter = preferencesAdapter;
}

public String getLastOpenSourceFilePath() {
return preferencesAdapter.getProjectPreference("editor.lastOpenFile");
}

public void setLastOpenSourceFilePath(String value) {
preferencesAdapter.setProjectPreference("editor.lastOpenFile",value);
}

public String getLastOpenSourceLineNumber() {
return preferencesAdapter.getProjectPreference("editor.lastOpenLineNumber");
}

public void setLastOpenSourceLineNumber(String value) {
preferencesAdapter.setProjectPreference("editor.lastOpenLineNumber",value);
}

public List getBuildConfigFiles() {
return BrowserManager.getDefault().getConfigFiles();
}
public String getDefaultBuildConfigFile() {
return null;
}

public String getLastActiveBuildConfigFile() {
return null;
}

public String getProjectName() {
return null;
}

public String getClassToExecute() {
return preferencesAdapter.getProjectPreference("runtime.mainClass");
}

public void setClassToExecute(String mainClass) {
preferencesAdapter.setProjectPreference("runtime.mainClass", mainClass);
}

public String getRootProjectDir() {
return new File(Ajde.getDefault().getConfigurationManager().getActiveConfigFile()).getParent();
}

public String getExecutionArgs() {
return null;
}

public List getProjectSourceFiles() {
return null;
}
public String getVmArgs() {
return null;
}

public String getProjectSourcePath() {
return null;
}

public String getBootClasspath() {
return System.getProperty("sun.boot.class.path");
}

public void setAjcOptions(String flags) {
preferencesAdapter.setProjectPreference("build.flags", flags);
}

public String getAjcOptions() {
return preferencesAdapter.getProjectPreference("build.flags");
}

public String getOutputPath() {
String outputPath = preferencesAdapter.getProjectPreference("build.outputpath");
if (outputPath == null) {
return ".";
} else {
return outputPath;
}
}

public void setOutputPath(String path) {
preferencesAdapter.setProjectPreference("build.outputpath", path);
}
public OutputLocationManager getOutputLocationManager() {
return null;
}

public String getUserClasspath() {
return preferencesAdapter.getProjectPreference("build.classpath");
}

public String getClasspath() {
String systemPath = System.getProperty("java.class.path", ".");
String userPath = preferencesAdapter.getProjectPreference("build.classpath");
if (userPath != null && userPath.trim().length() != 0) {
return userPath;
} else {
return systemPath;
}
}

public void setClasspath(String path) {
preferencesAdapter.setProjectPreference("build.classpath", path);
}

// 1.1 options
public Set getInJars( ) {
return null;
}
public Set getInpath() {
return null;
}
public String getOutJar( ) { // XXX unimplemented
return null;
}
public Set getSourceRoots( ) { // XXX unimplemented
return null;
}
public Set getAspectPath( ) { // XXX unimplemented
return null;
}

public Map getSourcePathResources() {
return null;
}
}

//public String getAjcWorkingDir() {
//String workingDir = preferencesAdapter.getProjectPreference("build.workingdir");
//if (workingDir == null || workingDir.equals(getOutputPath())) {
// return getOutputPath() + "./ajworkingdir";
//} else {
// return workingDir;
//}
//}

//public void setAjcWorkingDir(String path) {
//preferencesAdapter.setProjectPreference("build.workingdir", path);
//}


+ 0
- 104
ajbrowser/src/org/aspectj/tools/ajbrowser/CompilerMessagesPanel.java View File

@@ -1,104 +0,0 @@
/* *******************************************************************
* Copyright (c) 1999-2001 Xerox Corporation,
* 2002 Palo Alto Research Center, Incorporated (PARC).
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Xerox/PARC initial implementation
* ******************************************************************/


package org.aspectj.tools.ajbrowser;

import java.awt.BorderLayout;
import java.awt.event.*;

import javax.swing.*;

import org.aspectj.ajde.*;
import org.aspectj.ajde.ui.swing.*;
import org.aspectj.bridge.*;
import org.aspectj.bridge.IMessage.Kind;

/**
* Used to display a list of compiler messages that can be clicked in order
* to seek to their corresponding sourceline.
*
* @author Mik Kersten
*/
public class CompilerMessagesPanel extends JPanel implements TaskListManager {
private static final long serialVersionUID = -2251912345065588977L;
private JScrollPane jScrollPane1 = new JScrollPane();
//private JScrollPane jScrollPane2 = new JScrollPane();
private JList list = new JList();
private DefaultListModel listModel = new DefaultListModel();
private BorderLayout borderLayout1 = new BorderLayout();
private boolean hasWarning = false;

public CompilerMessagesPanel() {
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
list.setModel(listModel);

MouseListener mouseListener = new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() >= 1) {
int index = list.locationToIndex(e.getPoint());
if (listModel.getSize() >= index && index != -1) {
IMessage message = (IMessage)listModel.getElementAt(index);
Ajde.getDefault().getEditorAdapter().showSourceLine(message.getSourceLocation(), true);
}
}
}
};
list.addMouseListener(mouseListener);
list.setCellRenderer(new CompilerMessagesCellRenderer());
}

public void addSourcelineTask(IMessage message) {
listModel.addElement(message);
checkIfWarning(message.getKind());
}
public void addSourcelineTask(String message, ISourceLocation sourceLocation, IMessage.Kind kind) {
listModel.addElement(new Message(message, kind, null, sourceLocation));
checkIfWarning(kind);
}

public void addProjectTask(String message, IMessage.Kind kind) {
listModel.addElement(new Message(message, kind, null, null));
checkIfWarning(kind);
}
private void checkIfWarning(Kind kind) {
if (kind.equals(IMessage.WARNING)) hasWarning = true;
}
public void clearTasks() {
listModel.clear();
hasWarning = false;
}

private void jbInit() throws Exception {
this.setLayout(borderLayout1);
this.add(jScrollPane1, BorderLayout.CENTER);
jScrollPane1.getViewport().add(list, null);
}

public boolean hasWarning() {
return hasWarning;
}

}




+ 0
- 545
ajbrowser/src/org/aspectj/tools/ajbrowser/TopFrame.java View File

@@ -1,545 +0,0 @@
/* *******************************************************************
* Copyright (c) 1999-2001 Xerox Corporation,
* 2002 Palo Alto Research Center, Incorporated (PARC).
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Xerox/PARC initial implementation
* ******************************************************************/


package org.aspectj.tools.ajbrowser;

import java.awt.*;
import java.awt.event.*;
import java.io.File;

import javax.swing.*;
import javax.swing.border.*;
import javax.swing.filechooser.FileFilter;

import org.aspectj.ajde.Ajde;
import org.aspectj.ajde.ui.swing.*;
import org.aspectj.asm.IProgramElement;

/**
* UI for standalone operation.
*
* @author Mik Kersten
*/
public class TopFrame extends JFrame {

private static final long serialVersionUID = 1007473581156451702L;

private static final File CURRENT_DIR = new File(".");

JLabel statusText_label = new JLabel();

//private AJButtonMenuCombo lastBuildCombo = null;
private JPanel editor_panel = null;
private JPanel sourceEditor_panel = null;

private JMenuBar menuBar = new JMenuBar();
private JMenu jMenu1 = new JMenu();
private JMenu jMenu2 = new JMenu();
private JMenuItem projectBuild_menuItem = new JMenuItem();
private FlowLayout left_flowLayout = new FlowLayout();
private JMenuItem jMenuItem1 = new JMenuItem();
private JMenuItem exit_menuItem = new JMenuItem();
private JSplitPane top_splitPane = new JSplitPane();
// private BorderLayout borderLayout2 = new BorderLayout();
// private BorderLayout borderLayout1 = new BorderLayout();
private BorderLayout borderLayout3 = new BorderLayout();
private JMenuItem projectRun_menuItem = new JMenuItem();
private JMenuItem projectRunOther_menuItem = new JMenuItem();
private JPanel status_panel = new JPanel();
private BorderLayout borderLayout4 = new BorderLayout();
private Border emptyBorder = BorderFactory.createEmptyBorder();
private JPanel toolbar_panel = new JPanel();
private JSplitPane right_splitPane = new JSplitPane();
private JPanel messages_panel = null;
private JMenu tools_menu = new JMenu();
private JMenuItem joinpointProbe_menuItem = new JMenuItem();
private JMenuItem projectDebug_menuItem = new JMenuItem();
private JMenuItem svProperties_menuItem = new JMenuItem();
private File lastChosenDir = CURRENT_DIR;
JPanel toolBar_panel = new JPanel();
JToolBar build_toolBar = new JToolBar();
JButton closeConfig_button = new JButton();
JButton openConfig_button = new JButton();
JButton run_button = new JButton();
JToolBar project_toolBar = new JToolBar();
JButton save_button = new JButton();
JButton options_button = new JButton();
JButton editConfig_button = new JButton();
JToolBar file_toolBar = new JToolBar();
JPanel filler_panel = new JPanel();
BorderLayout borderLayout5 = new BorderLayout();
BorderLayout borderLayout6 = new BorderLayout();
Border border8;
JLabel jLabel1 = new JLabel();
JLabel jLabel2 = new JLabel();
JPanel multiView_panel;

private AJButtonMenuCombo buildCombo;

public void init(MultiStructureViewPanel multiViewPanel, JPanel compilerMessagesPanel, JPanel editorPanel) {
try {
this.multiView_panel = multiViewPanel;
//this.browser_panel = browserPanel;
//this.fileStructure_panel = fileStructurePanel;
this.messages_panel = compilerMessagesPanel;
this.editor_panel = editorPanel;
this.sourceEditor_panel = editorPanel;

jbInit();
svProperties_menuItem.setIcon(AjdeUIManager.getDefault().getIconRegistry().getBrowserOptionsIcon());
projectBuild_menuItem.setIcon(AjdeUIManager.getDefault().getIconRegistry().getBuildIcon());
projectRun_menuItem.setIcon(AjdeUIManager.getDefault().getIconRegistry().getExecuteIcon());
projectRunOther_menuItem.setIcon(AjdeUIManager.getDefault().getIconRegistry().getExecuteIcon());
projectDebug_menuItem.setIcon(AjdeUIManager.getDefault().getIconRegistry().getDebugIcon());

this.setJMenuBar(menuBar);
this.setIconImage(((ImageIcon)AjdeUIManager.getDefault().getIconRegistry().getStructureSwingIcon(IProgramElement.Kind.ADVICE)).getImage());
this.setLocation(75, 10);
this.setSize(900, 650);
this.setTitle(BrowserManager.TITLE);
//bindKeys();
fixButtonBorders();
messages_panel.setVisible(false);

JPopupMenu orderMenu = new BuildConfigPopupMenu(new AbstractAction() {

private static final long serialVersionUID = 1L;

public void actionPerformed(ActionEvent arg0) {
BrowserManager.getDefault().saveAll();
}
});

buildCombo = new AJButtonMenuCombo(
"Build",
"Build",
AjdeUIManager.getDefault().getIconRegistry().getBuildIcon(),
orderMenu,
false);
build_toolBar.add(buildCombo, 1);
refreshBuildMenu();
}
catch(Exception e) {
e.printStackTrace();
}
}
private void refreshBuildMenu() {
JPopupMenu orderMenu = new BuildConfigPopupMenu(new AbstractAction() {
private static final long serialVersionUID = -3204840278758386318L;

public void actionPerformed(ActionEvent arg0) {
BrowserManager.getDefault().saveAll();
}
});

buildCombo.setMenu(orderMenu);
}

public void setEditorPanel(JPanel panel) {
editor_panel = panel;
right_splitPane.remove(editor_panel);
right_splitPane.add(panel, JSplitPane.TOP);
panel.setVisible(true);
}

/**
* @todo get rid of this method and make jbinit() work properly
*/
private void fixButtonBorders() {
run_button.setBorder(null);
options_button.setBorder(null);
openConfig_button.setBorder(null);
closeConfig_button.setBorder(null);
save_button.setBorder(null);
editConfig_button.setBorder(null);
}

private void jbInit() throws Exception {
border8 = BorderFactory.createCompoundBorder(BorderFactory.createEtchedBorder(Color.white,new Color(156, 156, 158)),BorderFactory.createEmptyBorder(2,2,2,2));
emptyBorder = BorderFactory.createEmptyBorder(2,2,2,2);
jMenu1.setFont(new java.awt.Font("Dialog", 0, 11));
jMenu1.setText("File");
jMenu1.setMnemonic(KeyEvent.VK_F);
jMenu2.setFont(new java.awt.Font("Dialog", 0, 11));
jMenu2.setText("Project");
jMenu2.setMnemonic(KeyEvent.VK_P);
projectBuild_menuItem.setFont(new java.awt.Font("Dialog", 0, 11));
projectBuild_menuItem.setText("Build");
projectBuild_menuItem.setMnemonic(KeyEvent.VK_B);
projectBuild_menuItem.setAccelerator(KeyStroke.getKeyStroke(
KeyEvent.VK_B, ActionEvent.ALT_MASK));

projectBuild_menuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
projectBuild_menuItem_actionPerformed(e);
}
});
left_flowLayout.setAlignment(FlowLayout.LEFT);
jMenuItem1.setFont(new java.awt.Font("Dialog", 0, 11));
jMenuItem1.setText("Save");
jMenuItem1.setMnemonic(KeyEvent.VK_S);
jMenuItem1.setAccelerator(KeyStroke.getKeyStroke(
KeyEvent.VK_S, ActionEvent.ALT_MASK));
jMenuItem1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
jMenuItem1_actionPerformed(e);
}
});
exit_menuItem.setFont(new java.awt.Font("Dialog", 0, 11));
exit_menuItem.setText("Exit");
exit_menuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
exit_menuItem_actionPerformed(e);
}
});
top_splitPane.setPreferredSize(new Dimension(706, 800));
top_splitPane.setDividerSize(4);
this.getContentPane().setLayout(borderLayout3);
projectRun_menuItem.setEnabled(true);
projectRun_menuItem.setFont(new java.awt.Font("Dialog", 0, 11));
projectRun_menuItem.setText("Run in same VM");
projectRun_menuItem.setToolTipText("Run in same VM (hold shift down to run in separate process)");
projectRun_menuItem.setMnemonic(KeyEvent.VK_R);
projectRun_menuItem.setAccelerator(KeyStroke.getKeyStroke(
KeyEvent.VK_R, ActionEvent.ALT_MASK));
projectRun_menuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
projectRun_menuItem_actionPerformed(e);
}
});
projectRunOther_menuItem.setEnabled(true);
projectRunOther_menuItem.setFont(new java.awt.Font("Dialog", 0, 11));
projectRunOther_menuItem.setText("Run in separate process");
projectRunOther_menuItem.setMnemonic(KeyEvent.VK_P);
projectRunOther_menuItem.setAccelerator(KeyStroke.getKeyStroke(
KeyEvent.VK_P, ActionEvent.ALT_MASK));
projectRunOther_menuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
projectRunOther_menuItem_actionPerformed(e);
}
});
statusText_label.setFont(new java.awt.Font("Dialog", 0, 11));
statusText_label.setBorder(BorderFactory.createLoweredBevelBorder());
statusText_label.setMaximumSize(new Dimension(2000, 20));
statusText_label.setPreferredSize(new Dimension(300, 20));
status_panel.setLayout(borderLayout4);
this.addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosed(WindowEvent e) {
this_windowClosed(e);
}
public void windowClosing(WindowEvent e) {
this_windowClosing(e);
}
});
toolbar_panel.setLayout(borderLayout5);
right_splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
right_splitPane.setBorder(null);
right_splitPane.setDividerSize(4);
tools_menu.setFont(new java.awt.Font("Dialog", 0, 11));
tools_menu.setText("Tools");
tools_menu.setMnemonic(KeyEvent.VK_T);
projectDebug_menuItem.setEnabled(false);
projectDebug_menuItem.setFont(new java.awt.Font("Dialog", 0, 11));
projectDebug_menuItem.setText("Debug");
svProperties_menuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
svProperties_menuItem_actionPerformed(e);
}
});
svProperties_menuItem.setText("Options...");
svProperties_menuItem.setActionCommand("AJDE Console...");
svProperties_menuItem.setFont(new java.awt.Font("Dialog", 0, 11));
svProperties_menuItem.setMnemonic(KeyEvent.VK_O);
svProperties_menuItem.setAccelerator(KeyStroke.getKeyStroke(
KeyEvent.VK_O, ActionEvent.ALT_MASK));
build_toolBar.setBorder(emptyBorder);
build_toolBar.setFloatable(false);
closeConfig_button.setMaximumSize(new Dimension(100, 20));
closeConfig_button.setEnabled(true);
closeConfig_button.setFont(new java.awt.Font("Dialog", 0, 11));
closeConfig_button.setBorder(null);
closeConfig_button.setMinimumSize(new Dimension(24, 20));
closeConfig_button.setPreferredSize(new Dimension(20, 20));
closeConfig_button.setToolTipText("Close build configuration");
closeConfig_button.setIcon(AjdeUIManager.getDefault().getIconRegistry().getCloseConfigIcon());
closeConfig_button.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
closeConfig_button_actionPerformed(e);
}
});
openConfig_button.setMaximumSize(new Dimension(100, 20));
openConfig_button.setEnabled(true);
openConfig_button.setFont(new java.awt.Font("Dialog", 0, 11));
openConfig_button.setBorder(null);
openConfig_button.setMinimumSize(new Dimension(24, 20));
openConfig_button.setPreferredSize(new Dimension(20, 20));
openConfig_button.setToolTipText("Select build configuration...");
openConfig_button.setIcon(AjdeUIManager.getDefault().getIconRegistry().getOpenConfigIcon());
openConfig_button.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
openConfig_button_actionPerformed(e);
}
});
run_button.setMaximumSize(new Dimension(60, 20));
run_button.setEnabled(true);
run_button.setFont(new java.awt.Font("Dialog", 0, 11));
run_button.setBorder(null);
run_button.setMinimumSize(new Dimension(24, 20));
run_button.setPreferredSize(new Dimension(20, 20));
run_button.setToolTipText("Run in same VM (hold shift down to run in separate process)");
run_button.setIcon(AjdeUIManager.getDefault().getIconRegistry().getExecuteIcon());
run_button.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
run_button_actionPerformed(e);
}
});
project_toolBar.setBorder(emptyBorder);
save_button.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
save_button_actionPerformed(e);
}
});
save_button.setIcon(AjdeUIManager.getDefault().getIconRegistry().getSaveIcon());
save_button.setText("Save");
save_button.setToolTipText("Save");
save_button.setPreferredSize(new Dimension(55, 20));
save_button.setMinimumSize(new Dimension(24, 20));
save_button.setFont(new java.awt.Font("Dialog", 0, 11));
save_button.setBorder(null);
save_button.setMaximumSize(new Dimension(60, 20));
options_button.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
options_button_actionPerformed(e);
}
});
options_button.setIcon(AjdeUIManager.getDefault().getIconRegistry().getBrowserOptionsIcon());
options_button.setText("Options");
options_button.setToolTipText("Options...");
options_button.setPreferredSize(new Dimension(60, 20));
options_button.setMinimumSize(new Dimension(24, 20));
options_button.setFont(new java.awt.Font("Dialog", 0, 11));
options_button.setBorder(null);
options_button.setMaximumSize(new Dimension(80, 20));
editConfig_button.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
editConfig_button_actionPerformed(e);
}
});
editConfig_button.setIcon(AjdeUIManager.getDefault().getIconRegistry().getStructureSwingIcon(IProgramElement.Kind.FILE_LST));
editConfig_button.setText("Edit Config");
editConfig_button.setToolTipText("Edit Config...");
editConfig_button.setPreferredSize(new Dimension(80, 20));
editConfig_button.setMinimumSize(new Dimension(24, 20));
editConfig_button.setFont(new java.awt.Font("Dialog", 0, 11));
editConfig_button.setBorder(null);
editConfig_button.setMaximumSize(new Dimension(80, 20));
file_toolBar.setBorder(emptyBorder);
toolBar_panel.setLayout(borderLayout6);
jLabel1.setFont(new java.awt.Font("Dialog", 0, 11));
jLabel1.setText(" Build: ");
jLabel2.setText(" Run: ");
jLabel2.setFont(new java.awt.Font("Dialog", 0, 11));
//fileStructure_panel.setFont(new java.awt.Font("Dialog", 0, 11));
//browser_panel.setFont(new java.awt.Font("Dialog", 0, 11));
this.getContentPane().add(top_splitPane, BorderLayout.CENTER);
top_splitPane.add(right_splitPane, JSplitPane.RIGHT);
top_splitPane.add(multiView_panel, JSplitPane.LEFT);
right_splitPane.add(messages_panel, JSplitPane.BOTTOM);
right_splitPane.add(editor_panel, JSplitPane.TOP);
//structureView_pane.add(fileStructure_panel, JSplitPane.RIGHT);
//structureView_pane.add(browser_panel, JSplitPane.LEFT);
this.getContentPane().add(status_panel, BorderLayout.SOUTH);
status_panel.add(statusText_label, BorderLayout.CENTER);
this.getContentPane().add(toolbar_panel, BorderLayout.NORTH);
toolbar_panel.add(filler_panel, BorderLayout.CENTER);
toolbar_panel.add(toolBar_panel, BorderLayout.WEST);
//file_toolBar.add(editConfig_button, null);
file_toolBar.add(save_button, null);
file_toolBar.add(options_button, null);
toolBar_panel.add(build_toolBar, BorderLayout.WEST);
toolBar_panel.add(project_toolBar, BorderLayout.CENTER);
project_toolBar.add(jLabel2, null);
project_toolBar.add(run_button, null);
build_toolBar.add(jLabel1, null);
build_toolBar.add(openConfig_button, null);
build_toolBar.add(closeConfig_button, null);
toolBar_panel.add(file_toolBar, BorderLayout.EAST);
menuBar.add(jMenu1);
menuBar.add(jMenu2);
menuBar.add(tools_menu);
jMenu1.add(jMenuItem1);
jMenu1.addSeparator();
jMenu1.add(exit_menuItem);
jMenu2.add(projectBuild_menuItem);
jMenu2.add(projectRun_menuItem);
jMenu2.add(projectRunOther_menuItem);
//jMenu2.add(projectDebug_menuItem);
tools_menu.add(joinpointProbe_menuItem);
tools_menu.add(svProperties_menuItem);
top_splitPane.setDividerLocation(380);
right_splitPane.setDividerLocation(500);
project_toolBar.addSeparator();
project_toolBar.addSeparator();
}

private void exit_menuItem_actionPerformed(ActionEvent e) {
quit();
}

private void this_windowClosing(WindowEvent e) {
quit();
}

private void quit() {
this.dispose();
System.exit(0);
}


void treeMode_comboBox_actionPerformed(ActionEvent e) { }

void save_button_actionPerformed(ActionEvent e) {
BrowserManager.getDefault().getEditorManager().saveContents();
}


void this_windowClosed(WindowEvent e) {
quit();
}

public void showMessagesPanel() {
right_splitPane.setDividerLocation(right_splitPane.getHeight()-100);
messages_panel.setVisible(true);
}

public void hideMessagesPanel() {
right_splitPane.setDividerLocation(right_splitPane.getHeight());
messages_panel.setVisible(false);
}

void jMenuItem1_actionPerformed(ActionEvent e) {
BrowserManager.getDefault().getEditorManager().saveContents();
}

void projectBuild_menuItem_actionPerformed(ActionEvent e) {
BrowserManager.getDefault().saveAll();
if (EditorManager.isShiftDown(e.getModifiers())) {
buildFresh();
} else {
build();
}
}

void run_button_actionPerformed(ActionEvent e) {
if (EditorManager.isShiftDown(e.getModifiers())) {
runInNewVM();
} else {
runInSameVM();
}
}

void projectRunOther_menuItem_actionPerformed(ActionEvent e) {
runInNewVM();
}

void projectRun_menuItem_actionPerformed(ActionEvent e) {
if (EditorManager.isShiftDown(e.getModifiers())) {
runInNewVM();
} else {
runInSameVM();
}
}

void build_button_actionPerformed(ActionEvent e) {
BrowserManager.getDefault().saveAll();
if (EditorManager.isShiftDown(e.getModifiers())) {
buildFresh();
} else {
build();
}
}

void options_button_actionPerformed(ActionEvent e) {
AjdeUIManager.getDefault().showOptionsFrame();
}

void editConfig_button_actionPerformed(ActionEvent e) {
//Ajde.getDefault().getConfigurationManager().editConfigFile(UiManager.getDefault().getViewManager().getCurrConfigFile());
BrowserManager.getDefault().openFile(Ajde.getDefault().getConfigurationManager().getActiveConfigFile());
refreshBuildMenu();
}

public void resetSourceEditorPanel() {
right_splitPane.removeAll();
right_splitPane.add(sourceEditor_panel, JSplitPane.TOP);
}
private void svProperties_menuItem_actionPerformed(ActionEvent e) {
AjdeUIManager.getDefault().showOptionsFrame();
}

private void openConfig_button_actionPerformed(ActionEvent e) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setCurrentDirectory(lastChosenDir);
fileChooser.setFileFilter(new FileFilter() {
public boolean accept(File f) {
return (f.getPath().endsWith(".lst") || f.isDirectory());
}
public String getDescription() {
return "AspectJ Build Configuration (*.lst)";
}
});
int returnVal = fileChooser.showOpenDialog(this);
if(returnVal == JFileChooser.APPROVE_OPTION) {
File result = fileChooser.getSelectedFile();
String path = result.getAbsolutePath();//.replace('\\', '/');
BrowserManager.getDefault().getConfigFiles().add(0, path);
Ajde.getDefault().getConfigurationManager().setActiveConfigFile(path);
lastChosenDir = result.getParentFile();
if (null == lastChosenDir) {
lastChosenDir = CURRENT_DIR;
}
refreshBuildMenu();
}
}

private void closeConfig_button_actionPerformed(ActionEvent e) {
BrowserManager.getDefault().getConfigFiles().remove(Ajde.getDefault().getConfigurationManager().getActiveConfigFile());
if (!BrowserManager.getDefault().getConfigFiles().isEmpty()) {
Ajde.getDefault().getConfigurationManager().setActiveConfigFile((String)BrowserManager.getDefault().getConfigFiles().get(0));
}
refreshBuildMenu();
}
private void buildFresh() {
Ajde.getDefault().getBuildManager().buildFresh();
}
private void build() {
Ajde.getDefault().getBuildManager().build();
}
private void runInSameVM() {
Ajde.getDefault().runInSameVM();
}
private void runInNewVM() {
Ajde.getDefault().runInNewVM();
}
}

+ 88
- 0
ajbrowser/src/org/aspectj/tools/ajbrowser/core/BrowserBuildProgressMonitor.java View File

@@ -0,0 +1,88 @@
/********************************************************************
* Copyright (c) 2007 Contributors. All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://eclipse.org/legal/epl-v10.html
*
* Contributors: IBM Corporation - initial API and implementation
* Helen Hawkins - initial version (bug 148190)
*******************************************************************/
package org.aspectj.tools.ajbrowser.core;

import javax.swing.JDialog;

import org.aspectj.ajde.Ajde;
import org.aspectj.ajde.core.IBuildProgressMonitor;
import org.aspectj.ajde.ui.swing.BuildProgressPanel;
import org.aspectj.tools.ajbrowser.BrowserManager;
import org.aspectj.tools.ajbrowser.ui.BrowserMessageHandler;
import org.aspectj.tools.ajbrowser.ui.swing.TopFrame;

/**
* Build progress monitor that shows the progress in a dialog containing
* a JProgressBar. Also updates the progress bar at the bottom of AjBrowser
* with the build progress information.
*/
public class BrowserBuildProgressMonitor extends Thread implements IBuildProgressMonitor {

public static final String PROGRESS_HEADING = "AspectJ Build";
private BuildProgressPanel progressDialog = null;
private JDialog dialog = null;
private TopFrame topFrame;
private BrowserMessageHandler handler;
public BrowserBuildProgressMonitor(BrowserMessageHandler handler) {
this.handler = handler;
topFrame = (TopFrame) BrowserManager.getDefault().getRootFrame();
dialog = new JDialog(topFrame, PROGRESS_HEADING, false);
progressDialog = new BuildProgressPanel();
dialog.setContentPane(progressDialog);
dialog.setSize(550, 120);
try {
dialog.setLocationRelativeTo(topFrame);
} catch (NoSuchMethodError nsme) {
// running on 1.3
}
}
public void finish(boolean wasFullBuild) {
Ajde.getDefault().getIdeUIAdapter().displayStatusInformation("build finished...");
progressDialog.finish();
dialog.dispose();
if (handler.getMessages().isEmpty()) {
topFrame.hideMessagesPanel(handler);
} else {
topFrame.showMessagesPanel(handler);
}
}

public boolean isCancelRequested() {
boolean isCancel = progressDialog.isCancelRequested();
if (isCancel) {
Ajde.getDefault().getIdeUIAdapter().displayStatusInformation("Compile aborted");
}
return isCancel;
}

public void setProgress(double percentDone) {
progressDialog.setProgressBarVal((int) (percentDone*progressDialog.getProgressBarMax()));
}

public void setProgressText(String text) {
Ajde.getDefault().getIdeUIAdapter().displayStatusInformation(text);
progressDialog.setProgressText(text);
}

public void begin() {
Ajde.getDefault().getIdeUIAdapter().displayStatusInformation("starting build...");
handler.reset();
progressDialog.setProgressBarVal(0);
progressDialog.setProgressText("starting build...");
dialog.setLocationRelativeTo(Ajde.getDefault().getRootFrame());
dialog.setVisible(true);
}

}

+ 97
- 0
ajbrowser/src/org/aspectj/tools/ajbrowser/core/BrowserCompilerConfiguration.java View File

@@ -0,0 +1,97 @@
/********************************************************************
* Copyright (c) 2007 Contributors. All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://eclipse.org/legal/epl-v10.html
*
* Contributors: IBM Corporation - initial API and implementation
* Helen Hawkins - initial version (bug 148190)
*******************************************************************/
package org.aspectj.tools.ajbrowser.core;

import java.io.File;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.aspectj.ajde.core.ICompilerConfiguration;
import org.aspectj.ajde.core.IOutputLocationManager;
import org.aspectj.ajde.ui.UserPreferencesAdapter;
import org.aspectj.tools.ajbrowser.BrowserManager;

/**
* AjBrowser implementation of ICompilerConfiguration which returns something
* for getClasspath(), getJavaOptionsMap(), getNonStandardOptions() and
* getOutputLocationManager() and null for everything else. The reason it doesn't
* return anything for getProjectSourceFiles() is that it uses .lst files to record
* what is needed to build (via BuildConfigManager).
*/
public class BrowserCompilerConfiguration implements ICompilerConfiguration {

private UserPreferencesAdapter preferencesAdapter;
private IOutputLocationManager locationManager;

public BrowserCompilerConfiguration(UserPreferencesAdapter preferencesAdapter) {
this.preferencesAdapter = preferencesAdapter;
}

public String getClasspath() {
StringBuffer classpath = new StringBuffer();
String userPath = preferencesAdapter
.getProjectPreference(PreferenceStoreConstants.BUILD_CLASSPATH);
if (userPath != null && userPath.trim().length() != 0) {
classpath.append(userPath);
}
List outputDirs = getOutputLocationManager().getAllOutputLocations();
for (Iterator iterator = outputDirs.iterator(); iterator.hasNext();) {
File dir = (File) iterator.next();
classpath.append(File.pathSeparator + dir.getAbsolutePath() + File.pathSeparator);
}
classpath.append(System.getProperty("java.class.path", "."));
//System.out.println("classpath: " + classpath.toString());
return classpath.toString();
}

public Map getJavaOptionsMap() {
return BrowserManager.getDefault().getJavaBuildOptions().getJavaBuildOptionsMap();
}

public String getNonStandardOptions() {
return preferencesAdapter
.getProjectPreference(PreferenceStoreConstants.NONSTANDARD_OPTIONS);
}

public IOutputLocationManager getOutputLocationManager() {
if (locationManager == null) {
locationManager = new BrowserOutputLocationManager(preferencesAdapter);
}
return locationManager;
}

public List getProjectSourceFiles() {
// unimplemented in AjBrowser (uses BuildConfigManager instead)
return null;
}

public Map getSourcePathResources() {
// unimplemented in AjBrowser
return null;
}

public Set getAspectPath() {
// unimplemented in AjBrowser
return null;
}

public Set getInpath() {
// unimplemented in AjBrowser
return null;
}

public String getOutJar() {
// unimplemented in AjBrowser
return null;
}
}

+ 54
- 0
ajbrowser/src/org/aspectj/tools/ajbrowser/core/BrowserErrorHandler.java View File

@@ -0,0 +1,54 @@
/********************************************************************
* Copyright (c) 2007 Contributors. All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://eclipse.org/legal/epl-v10.html
*
* Contributors: IBM Corporation - initial API and implementation
* Helen Hawkins - initial version (bug 148190)
*******************************************************************/
package org.aspectj.tools.ajbrowser.core;

import java.io.PrintWriter;
import java.io.StringWriter;

import javax.swing.JOptionPane;

import org.aspectj.ajde.Ajde;
import org.aspectj.ajde.ui.swing.ErrorDialog;
import org.aspectj.tools.ajbrowser.BrowserManager;

/**
* Error handler used by AjBrowser. Handles errors and warnings by
* producing an error/warning dialog.
*/
public class BrowserErrorHandler {

public static void handleWarning(String message) {
JOptionPane.showMessageDialog(BrowserManager.getDefault()
.getRootFrame(), message, "AJBrowser Warning",
JOptionPane.WARNING_MESSAGE);
}

public static void handleError(String errorMessage) {
handleError(errorMessage, null);
}

public static void handleError(String message, Throwable t) {
String stack = getStackTraceAsString(t);
ErrorDialog errorDialog = new ErrorDialog(Ajde.getDefault()
.getRootFrame(), "AJBrowser Error", t, message, stack);
errorDialog.setVisible(true);
}

private static String getStackTraceAsString(Throwable t) {
StringWriter stringWriter = new StringWriter();
if (t != null) {
t.printStackTrace(new PrintWriter(stringWriter));
return stringWriter.getBuffer().toString();
}
return "<no stack trace available>";
}

}

+ 60
- 0
ajbrowser/src/org/aspectj/tools/ajbrowser/core/BrowserOutputLocationManager.java View File

@@ -0,0 +1,60 @@
/********************************************************************
* Copyright (c) 2007 Contributors. All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://eclipse.org/legal/epl-v10.html
*
* Contributors: IBM Corporation - initial API and implementation
* Helen Hawkins - initial version (bug 148190)
*******************************************************************/
package org.aspectj.tools.ajbrowser.core;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.aspectj.ajde.core.IOutputLocationManager;
import org.aspectj.ajde.ui.UserPreferencesAdapter;

/**
* IOutputLocationManager which returns the same output location for
* all files and resources.
*/
public class BrowserOutputLocationManager implements IOutputLocationManager {

private UserPreferencesAdapter preferencesAdapter;

public BrowserOutputLocationManager(
UserPreferencesAdapter preferencesAdapter) {
this.preferencesAdapter = preferencesAdapter;
}

public File getOutputLocationForClass(File compilationUnit) {
return new File(getCommonOutputDir());
}

public File getOutputLocationForResource(File resource) {
return new File(getCommonOutputDir());
}

private String getCommonOutputDir() {
String outputPath = preferencesAdapter.getProjectPreference(
PreferenceStoreConstants.BUILD_OUTPUTPATH);
if (outputPath == null) {
return ".";
}
return outputPath;
}

public List getAllOutputLocations() {
List outputDirs = new ArrayList();
outputDirs.add(new File(getCommonOutputDir()));
return outputDirs;
}

public File getDefaultOutputLocation() {
return new File(getCommonOutputDir());
}

}

+ 24
- 0
ajbrowser/src/org/aspectj/tools/ajbrowser/core/PreferenceStoreConstants.java View File

@@ -0,0 +1,24 @@
/********************************************************************
* Copyright (c) 2007 Contributors. All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://eclipse.org/legal/epl-v10.html
*
* Contributors: IBM Corporation - initial API and implementation
* Helen Hawkins - initial version (bug 148190)
*******************************************************************/
package org.aspectj.tools.ajbrowser.core;

/**
* Constants used by the preference store
*/
public class PreferenceStoreConstants {

public static final String BUILD_CLASSPATH = "build.classpath";
public static final String RUNTIME_MAINCLASS = "runtime.mainClass";
public static final String BUILD_OUTPUTPATH = "build.outputpath";
public static final String JAVA_CLASSPATH = "java.class.path";
public static final String NONSTANDARD_OPTIONS = "ajc.nonStandardOptions";
}

ajbrowser/src/org/aspectj/tools/ajbrowser/BasicEditor.java → ajbrowser/src/org/aspectj/tools/ajbrowser/ui/BasicEditor.java View File

@@ -8,11 +8,12 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Xerox/PARC initial implementation
* Xerox/PARC initial implementation
* Helen Hawkins Converted to new interface (bug 148190)
* ******************************************************************/


package org.aspectj.tools.ajbrowser;
package org.aspectj.tools.ajbrowser.ui;

import java.awt.BorderLayout;
import java.awt.Font;
@@ -22,7 +23,6 @@ import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
//import java.net.URL;

import javax.swing.JEditorPane;
import javax.swing.JPanel;
@@ -33,6 +33,8 @@ import javax.swing.text.DefaultHighlighter;
import org.aspectj.ajde.Ajde;
import org.aspectj.ajde.EditorAdapter;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.tools.ajbrowser.BrowserManager;
import org.aspectj.tools.ajbrowser.core.BrowserErrorHandler;

/**
* Bare-bones editor implementation used when the framework is being used
@@ -63,7 +65,7 @@ public class BasicEditor implements EditorAdapter {
jbInit();
}
catch(Exception e) {
Ajde.getDefault().getErrorHandler().handleError("Could not initialize GUI.", e);
BrowserErrorHandler.handleError("Could not initialize GUI.", e);
}
}

@@ -108,7 +110,7 @@ public class BasicEditor implements EditorAdapter {
editorPane.getHighlighter().addHighlight(currHighlightStart, currHighlightEnd, DefaultHighlighter.DefaultPainter);
editorPane.setCaretPosition(currHighlightStart);
} catch (BadLocationException ble) {
Ajde.getDefault().getErrorHandler().handleError("Could not highlight location.", ble);
BrowserErrorHandler.handleError("Could not highlight location.", ble);
}
BrowserManager.getDefault().getEditorManager().notifyCurrentFileChanged(filePath);
}

+ 94
- 0
ajbrowser/src/org/aspectj/tools/ajbrowser/ui/BrowserMessageHandler.java View File

@@ -0,0 +1,94 @@
/********************************************************************
* Copyright (c) 2007 Contributors. All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://eclipse.org/legal/epl-v10.html
*
* Contributors: IBM Corporation - initial API and implementation
* Helen Hawkins - initial version (bug 148190)
*******************************************************************/
package org.aspectj.tools.ajbrowser.ui;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import org.aspectj.ajde.Ajde;
import org.aspectj.ajde.IUIBuildMessageHandler;
import org.aspectj.ajde.ui.swing.ErrorDialog;
import org.aspectj.bridge.AbortException;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.IMessage.Kind;

/**
* MessageHandler used by AjBrowser that displays ERROR messages with
* exceptions and ABORT messages in an error dialog. Other messages are
* displayed by the MessageHandlerPanel. By default INFO and WEAVEINFO
* messages are ignored.
*/
public class BrowserMessageHandler implements IUIBuildMessageHandler {

private List ignoring;
private List messages;
public BrowserMessageHandler() {
ignoring = new ArrayList();
messages = new ArrayList();
ignore(IMessage.INFO);
ignore(IMessage.WEAVEINFO);
}
public boolean handleMessage(IMessage message) throws AbortException {
Kind messageKind = message.getKind();
if (isIgnoring(messageKind)) {
return true;
}
if (messageKind.equals(IMessage.ABORT)
|| (message.getThrown() != null) ) {
String stack = getStackTraceAsString(message.getThrown());
ErrorDialog errorDialog = new ErrorDialog(
Ajde.getDefault().getRootFrame(),
"AJDE Error", message.getThrown(), message.getMessage(), stack);
errorDialog.setVisible(true);
return true;
}
messages.add(message);
return true;
}

public void dontIgnore(Kind kind) {
if (null != kind) {
ignoring.remove(kind);
}
}

public boolean isIgnoring(Kind kind) {
return ((null != kind) && (ignoring.contains(kind)));
}
public void ignore(Kind kind) {
if ((null != kind) && (!ignoring.contains(kind))) {
ignoring.add(kind);
}
}
public List getMessages() {
return messages;
}

private String getStackTraceAsString(Throwable t) {
StringWriter stringWriter = new StringWriter();
if (t != null) {
t.printStackTrace(new PrintWriter(stringWriter));
return stringWriter.getBuffer().toString();
}
return "<no stack trace available>";
}

public void reset() {
messages.clear();
}
}

+ 38
- 0
ajbrowser/src/org/aspectj/tools/ajbrowser/ui/BrowserRuntimeProperties.java View File

@@ -0,0 +1,38 @@
/********************************************************************
* Copyright (c) 2007 Contributors. All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://eclipse.org/legal/epl-v10.html
*
* Contributors: IBM Corporation - initial API and implementation
* Helen Hawkins - initial version (bug 148190)
*******************************************************************/
package org.aspectj.tools.ajbrowser.ui;

import org.aspectj.ajde.IRuntimeProperties;
import org.aspectj.ajde.ui.UserPreferencesAdapter;
import org.aspectj.tools.ajbrowser.core.PreferenceStoreConstants;

/**
* AjBrowser implementation of IRuntimeProperties which uses the PreferenceStoreConstant
* to decide which class the user has specified contains the main method
*/
public class BrowserRuntimeProperties implements IRuntimeProperties {

private UserPreferencesAdapter preferencesAdapter;
public BrowserRuntimeProperties(UserPreferencesAdapter preferencesAdapter) {
this.preferencesAdapter = preferencesAdapter;
}
public String getClassToExecute() {
return preferencesAdapter.getProjectPreference(PreferenceStoreConstants.RUNTIME_MAINCLASS);
}

public String getExecutionArgs() {
// not implemented by ajbrowser
return null;
}

}

ajbrowser/src/org/aspectj/tools/ajbrowser/BrowserUIAdapter.java → ajbrowser/src/org/aspectj/tools/ajbrowser/ui/BrowserUIAdapter.java View File

@@ -12,10 +12,15 @@
* ******************************************************************/

package org.aspectj.tools.ajbrowser;
package org.aspectj.tools.ajbrowser.ui;

import org.aspectj.ajde.ui.*;
import org.aspectj.ajde.IdeUIAdapter;
import org.aspectj.tools.ajbrowser.BrowserManager;

/**
* AjBrowser implementation if IdeUIAdapter which displays the provided
* information in the status bar at the bottom of the AjBrowser GUI.
*/
public class BrowserUIAdapter implements IdeUIAdapter {
public void displayStatusInformation(String message) {

ajbrowser/src/org/aspectj/tools/ajbrowser/EditorManager.java → ajbrowser/src/org/aspectj/tools/ajbrowser/ui/EditorManager.java View File

@@ -12,7 +12,7 @@
* ******************************************************************/


package org.aspectj.tools.ajbrowser;
package org.aspectj.tools.ajbrowser.ui;

import java.awt.BorderLayout;
import java.awt.event.KeyEvent;
@@ -23,6 +23,7 @@ import javax.swing.*;

import org.aspectj.ajde.*;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.tools.ajbrowser.core.BrowserErrorHandler;

/**
* Responsible for controlling the editor.
@@ -91,7 +92,7 @@ public class EditorManager {
try {
SwingUtilities.invokeAndWait(update);
} catch (Exception e) {
Ajde.getDefault().getErrorHandler().handleError("Could not add view for source line.", e);
BrowserErrorHandler.handleError("Could not add view for source line.", e);
}
}
}
@@ -151,7 +152,7 @@ public class EditorManager {
((EditorAdapter)it.next()).saveContents();
}
} catch (IOException ioe) {
Ajde.getDefault().getErrorHandler().handleError("Editor could not save the current file.", ioe);
BrowserErrorHandler.handleError("Editor could not save the current file.", ioe);
}
}


ajbrowser/src/org/aspectj/tools/ajbrowser/BrowserOptionsPanel.java → ajbrowser/src/org/aspectj/tools/ajbrowser/ui/swing/BrowserOptionsPanel.java View File

@@ -8,19 +8,24 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Xerox/PARC initial implementation
* Xerox/PARC initial implementation
* Helen Hawkins Converted to new interface (bug 148190)
* ******************************************************************/


package org.aspectj.tools.ajbrowser;
package org.aspectj.tools.ajbrowser.ui.swing;

import java.io.*;
import javax.swing.*;
import java.awt.*;
import javax.swing.border.*;
import org.aspectj.ajde.ui.swing.*;
import org.aspectj.tools.ajbrowser.BrowserManager;
import org.aspectj.tools.ajbrowser.core.PreferenceStoreConstants;

/**
* Panel the displays both ajc and runtime options
*
* @author Mik Kersten
*/
public class BrowserOptionsPanel extends OptionsPanel {
@@ -36,8 +41,10 @@ public class BrowserOptionsPanel extends OptionsPanel {
private Box compileOptions_box2 = Box.createVerticalBox();
private JTextField classpath_field = new JTextField();
private JTextField outputPath_field = new JTextField();
private JTextField nonStandardOptions_field = new JTextField();
private JLabel jLabel16 = new JLabel();
private JLabel jLabel15 = new JLabel();
private JLabel nonStandardOptions_label = new JLabel();
private Box compileOptions_box3 = Box.createVerticalBox();
private BorderLayout borderLayout1 = new BorderLayout();
private Border border1;
@@ -58,32 +65,38 @@ public class BrowserOptionsPanel extends OptionsPanel {

public void loadOptions() throws IOException {
outputPath_field.setText(
BrowserManager.getDefault().getBrowserProjectProperties().getOutputPath()
BrowserManager.getDefault().getPreferencesAdapter().
getProjectPreference(PreferenceStoreConstants.BUILD_OUTPUTPATH)
);
nonStandardOptions_field.setText(
BrowserManager.getDefault().getPreferencesAdapter().
getProjectPreference(PreferenceStoreConstants.NONSTANDARD_OPTIONS)
);
classpath_field.setText(
BrowserManager.getDefault().getBrowserProjectProperties().getClasspath()
BrowserManager.getDefault().getPreferencesAdapter().
getProjectPreference(PreferenceStoreConstants.BUILD_CLASSPATH)
);
classToRun_field.setText(
BrowserManager.getDefault().getBrowserProjectProperties().getClassToExecute()
BrowserManager.getDefault().getPreferencesAdapter().
getProjectPreference(PreferenceStoreConstants.RUNTIME_MAINCLASS)
);
}
public void saveOptions() throws IOException {
BrowserManager.getDefault().getBrowserProjectProperties().setOutputPath(
outputPath_field.getText()
);
BrowserManager.getDefault().getBrowserProjectProperties().setClasspath(
classpath_field.getText()
);
BrowserManager.getDefault().getBrowserProjectProperties().setClassToExecute(
classToRun_field.getText()
);
BrowserManager.getDefault().getPreferencesAdapter().setProjectPreference(
PreferenceStoreConstants.BUILD_OUTPUTPATH, outputPath_field.getText());
BrowserManager.getDefault().getPreferencesAdapter().setProjectPreference(
PreferenceStoreConstants.NONSTANDARD_OPTIONS, nonStandardOptions_field.getText());
BrowserManager.getDefault().getPreferencesAdapter().setProjectPreference(
PreferenceStoreConstants.BUILD_CLASSPATH, classpath_field.getText());
BrowserManager.getDefault().getPreferencesAdapter().setProjectPreference(
PreferenceStoreConstants.RUNTIME_MAINCLASS, classToRun_field.getText());
}

private void jbInit() throws Exception {
border1 =
BorderFactory.createEtchedBorder(Color.white, new Color(156, 156, 158));
titledBorder1 = new TitledBorder(border1, "ajc Build Paths");
titledBorder1 = new TitledBorder(border1, "Ajc Options");
border2 =
BorderFactory.createCompoundBorder(
titledBorder1,
@@ -111,6 +124,9 @@ public class BrowserOptionsPanel extends OptionsPanel {
outputPath_field.setPreferredSize(new Dimension(225, 21));
outputPath_field.setMinimumSize(new Dimension(100, 21));
outputPath_field.setFont(new java.awt.Font("SansSerif", 0, 11));
nonStandardOptions_field.setPreferredSize(new Dimension(225, 21));
nonStandardOptions_field.setMinimumSize(new Dimension(100, 21));
nonStandardOptions_field.setFont(new java.awt.Font("SansSerif", 0, 11));
jLabel16.setText("Classpath (defaults to current directory): ");
jLabel16.setPreferredSize(new Dimension(200, 25));
jLabel16.setMaximumSize(new Dimension(400, 25));
@@ -119,6 +135,10 @@ public class BrowserOptionsPanel extends OptionsPanel {
jLabel15.setFont(new java.awt.Font("Dialog", 0, 11));
jLabel15.setPreferredSize(new Dimension(230, 25));
jLabel15.setText("Output path (defaults to current directory): ");
nonStandardOptions_label.setMaximumSize(new Dimension(400, 25));
nonStandardOptions_label.setFont(new java.awt.Font("Dialog", 0, 11));
nonStandardOptions_label.setPreferredSize(new Dimension(230, 25));
nonStandardOptions_label.setText("Non-standard compiler options: ");
titledBorder1.setTitleFont(new java.awt.Font("Dialog", 0, 11));
titledBorder2.setTitleFont(new java.awt.Font("Dialog", 0, 11));
runOptions_panel.add(jLabel4, null);
@@ -126,8 +146,10 @@ public class BrowserOptionsPanel extends OptionsPanel {
build_panel.add(buildPaths_panel, BorderLayout.CENTER);
build_panel.add(runOptions_panel, BorderLayout.SOUTH);
compileOptions_box2.add(outputPath_field, null);
compileOptions_box2.add(nonStandardOptions_field, null);
compileOptions_box2.add(classpath_field, null);
compileOptions_box3.add(jLabel15, null);
compileOptions_box3.add(nonStandardOptions_label, null);
compileOptions_box3.add(jLabel16, null);
buildPaths_panel.add(compileOptions_box3, null);
buildPaths_panel.add(compileOptions_box2, null);

+ 87
- 0
ajbrowser/src/org/aspectj/tools/ajbrowser/ui/swing/MessageHandlerPanel.java View File

@@ -0,0 +1,87 @@
/********************************************************************
* Copyright (c) 2007 Contributors. All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://eclipse.org/legal/epl-v10.html
*
* Contributors: IBM Corporation - initial API and implementation
* Helen Hawkins - initial version (bug 148190)
*******************************************************************/
package org.aspectj.tools.ajbrowser.ui.swing;

import java.awt.BorderLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Iterator;
import java.util.List;

import javax.swing.DefaultListModel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import org.aspectj.ajde.Ajde;
import org.aspectj.ajde.ui.swing.CompilerMessagesCellRenderer;
import org.aspectj.bridge.IMessage;
import org.aspectj.tools.ajbrowser.ui.BrowserMessageHandler;

/**
* Panel used to display messages from the message handler
*/
public class MessageHandlerPanel extends JPanel {
private static final long serialVersionUID = -2251912345065588977L;
private JScrollPane jScrollPane1 = new JScrollPane();
private JList list;
private DefaultListModel listModel;
private BorderLayout borderLayout1 = new BorderLayout();

public void showMessageHandlerPanel(BrowserMessageHandler handler, boolean showPanel) {
if (!showPanel) {
setVisible(false);
return;
}
createList(handler.getMessages());
try {
jbInit();
} catch (Exception e) {
e.printStackTrace();
}
list.setModel(listModel);

MouseListener mouseListener = new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() >= 1) {
int index = list.locationToIndex(e.getPoint());
if (listModel.getSize() >= index && index != -1) {
IMessage message = (IMessage) listModel
.getElementAt(index);
Ajde.getDefault().getEditorAdapter().showSourceLine(
message.getSourceLocation(), true);
}
}
}
};
list.addMouseListener(mouseListener);
list.setCellRenderer(new CompilerMessagesCellRenderer());
setVisible(showPanel);
}
private void createList(List messages) {
list = new JList();
listModel = new DefaultListModel();
for (Iterator iterator = messages.iterator(); iterator.hasNext();) {
listModel.addElement(iterator.next());
}
}

private void jbInit() throws Exception {
this.setLayout(borderLayout1);
this.add(jScrollPane1, BorderLayout.CENTER);
jScrollPane1.getViewport().add(list, null);
}

}

+ 599
- 0
ajbrowser/src/org/aspectj/tools/ajbrowser/ui/swing/TopFrame.java View File

@@ -0,0 +1,599 @@
/* *******************************************************************
* Copyright (c) 1999-2001 Xerox Corporation,
* 2002 Palo Alto Research Center, Incorporated (PARC).
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Xerox/PARC initial implementation
* ******************************************************************/

package org.aspectj.tools.ajbrowser.ui.swing;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowEvent;
import java.io.File;

import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JSplitPane;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import javax.swing.border.Border;
import javax.swing.filechooser.FileFilter;

import org.aspectj.ajde.Ajde;
import org.aspectj.ajde.ui.swing.AJButtonMenuCombo;
import org.aspectj.ajde.ui.swing.BuildConfigPopupMenu;
import org.aspectj.ajde.ui.swing.MultiStructureViewPanel;
import org.aspectj.asm.IProgramElement;
import org.aspectj.tools.ajbrowser.BrowserManager;
import org.aspectj.tools.ajbrowser.ui.BrowserMessageHandler;
import org.aspectj.tools.ajbrowser.ui.EditorManager;

/**
* UI for standalone operation.
*
* @author Mik Kersten
*/
public class TopFrame extends JFrame {

private static final long serialVersionUID = 1007473581156451702L;

private static final File CURRENT_DIR = new File(".");

public JLabel statusText_label = new JLabel();

private JPanel editor_panel = null;
private JPanel sourceEditor_panel = null;

private JMenuBar menuBar = new JMenuBar();
private JMenu jMenu1 = new JMenu();
private JMenu jMenu2 = new JMenu();
private JMenuItem projectBuild_menuItem = new JMenuItem();
private FlowLayout left_flowLayout = new FlowLayout();
private JMenuItem jMenuItem1 = new JMenuItem();
private JMenuItem exit_menuItem = new JMenuItem();
private JSplitPane top_splitPane = new JSplitPane();
private BorderLayout borderLayout3 = new BorderLayout();
private JMenuItem projectRun_menuItem = new JMenuItem();
private JMenuItem projectRunOther_menuItem = new JMenuItem();
private JPanel status_panel = new JPanel();
private BorderLayout borderLayout4 = new BorderLayout();
private Border emptyBorder = BorderFactory.createEmptyBorder();
private JPanel toolbar_panel = new JPanel();
private JSplitPane right_splitPane = new JSplitPane();
private MessageHandlerPanel messages_panel = null;
private JMenu tools_menu = new JMenu();
private JMenuItem joinpointProbe_menuItem = new JMenuItem();
private JMenuItem projectDebug_menuItem = new JMenuItem();
private JMenuItem svProperties_menuItem = new JMenuItem();
private File lastChosenDir = CURRENT_DIR;

JPanel toolBar_panel = new JPanel();
JToolBar build_toolBar = new JToolBar();
JButton closeConfig_button = new JButton();
JButton openConfig_button = new JButton();
JButton run_button = new JButton();
JToolBar project_toolBar = new JToolBar();
JButton save_button = new JButton();
JButton options_button = new JButton();
JButton editConfig_button = new JButton();
JToolBar file_toolBar = new JToolBar();
JPanel filler_panel = new JPanel();
BorderLayout borderLayout5 = new BorderLayout();
BorderLayout borderLayout6 = new BorderLayout();
Border border8;
JLabel jLabel1 = new JLabel();
JLabel jLabel2 = new JLabel();
JPanel multiView_panel;

private AJButtonMenuCombo buildCombo;

public void init(MultiStructureViewPanel multiViewPanel,
MessageHandlerPanel compilerMessagesPanel, JPanel editorPanel) {
try {
this.multiView_panel = multiViewPanel;
this.messages_panel = compilerMessagesPanel;
this.editor_panel = editorPanel;
this.sourceEditor_panel = editorPanel;

jbInit();
svProperties_menuItem.setIcon(Ajde.getDefault()
.getIconRegistry().getBrowserOptionsIcon());
projectBuild_menuItem.setIcon(Ajde.getDefault()
.getIconRegistry().getBuildIcon());
projectRun_menuItem.setIcon(Ajde.getDefault()
.getIconRegistry().getExecuteIcon());
projectRunOther_menuItem.setIcon(Ajde.getDefault()
.getIconRegistry().getExecuteIcon());
projectDebug_menuItem.setIcon(Ajde.getDefault()
.getIconRegistry().getDebugIcon());

this.setJMenuBar(menuBar);
this.setIconImage(((ImageIcon) Ajde.getDefault()
.getIconRegistry().getStructureSwingIcon(
IProgramElement.Kind.ADVICE)).getImage());
this.setLocation(75, 10);
this.setSize(900, 650);
this.setTitle(BrowserManager.TITLE);
// bindKeys();
fixButtonBorders();
messages_panel.setVisible(false);

JPopupMenu orderMenu = new BuildConfigPopupMenu(
new AbstractAction() {

private static final long serialVersionUID = 1L;

public void actionPerformed(ActionEvent arg0) {
BrowserManager.getDefault().saveAll();
}
});

buildCombo = new AJButtonMenuCombo("Build", "Build", Ajde
.getDefault().getIconRegistry().getBuildIcon(), orderMenu,
false);

build_toolBar.add(buildCombo, 1);
refreshBuildMenu();
} catch (Exception e) {
e.printStackTrace();
}
}

private void refreshBuildMenu() {
JPopupMenu orderMenu = new BuildConfigPopupMenu(new AbstractAction() {
private static final long serialVersionUID = -3204840278758386318L;

public void actionPerformed(ActionEvent arg0) {
BrowserManager.getDefault().saveAll();
}
});

buildCombo.setMenu(orderMenu);
}

public void setEditorPanel(JPanel panel) {
editor_panel = panel;
right_splitPane.remove(editor_panel);
right_splitPane.add(panel, JSplitPane.TOP);
panel.setVisible(true);
}

/**
* @todo get rid of this method and make jbinit() work properly
*/
private void fixButtonBorders() {
run_button.setBorder(null);
options_button.setBorder(null);
openConfig_button.setBorder(null);
closeConfig_button.setBorder(null);
save_button.setBorder(null);
editConfig_button.setBorder(null);
}

private void jbInit() throws Exception {
border8 = BorderFactory.createCompoundBorder(BorderFactory
.createEtchedBorder(Color.white, new Color(156, 156, 158)),
BorderFactory.createEmptyBorder(2, 2, 2, 2));
emptyBorder = BorderFactory.createEmptyBorder(2, 2, 2, 2);
jMenu1.setFont(new java.awt.Font("Dialog", 0, 11));
jMenu1.setText("File");
jMenu1.setMnemonic(KeyEvent.VK_F);
jMenu2.setFont(new java.awt.Font("Dialog", 0, 11));
jMenu2.setText("Project");
jMenu2.setMnemonic(KeyEvent.VK_P);
projectBuild_menuItem.setFont(new java.awt.Font("Dialog", 0, 11));
projectBuild_menuItem.setText("Build");
projectBuild_menuItem.setMnemonic(KeyEvent.VK_B);
projectBuild_menuItem.setAccelerator(KeyStroke.getKeyStroke(
KeyEvent.VK_B, ActionEvent.ALT_MASK));

projectBuild_menuItem
.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
projectBuild_menuItem_actionPerformed(e);
}
});
left_flowLayout.setAlignment(FlowLayout.LEFT);
jMenuItem1.setFont(new java.awt.Font("Dialog", 0, 11));
jMenuItem1.setText("Save");
jMenuItem1.setMnemonic(KeyEvent.VK_S);
jMenuItem1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,
ActionEvent.ALT_MASK));
jMenuItem1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
jMenuItem1_actionPerformed(e);
}
});
exit_menuItem.setFont(new java.awt.Font("Dialog", 0, 11));
exit_menuItem.setText("Exit");
exit_menuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
exit_menuItem_actionPerformed(e);
}
});
top_splitPane.setPreferredSize(new Dimension(706, 800));
top_splitPane.setDividerSize(4);
this.getContentPane().setLayout(borderLayout3);
projectRun_menuItem.setEnabled(true);
projectRun_menuItem.setFont(new java.awt.Font("Dialog", 0, 11));
projectRun_menuItem.setText("Run in same VM");
projectRun_menuItem
.setToolTipText("Run in same VM (hold shift down to run in separate process)");
projectRun_menuItem.setMnemonic(KeyEvent.VK_R);
projectRun_menuItem.setAccelerator(KeyStroke.getKeyStroke(
KeyEvent.VK_R, ActionEvent.ALT_MASK));
projectRun_menuItem
.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
projectRun_menuItem_actionPerformed(e);
}
});
projectRunOther_menuItem.setEnabled(true);
projectRunOther_menuItem.setFont(new java.awt.Font("Dialog", 0, 11));
projectRunOther_menuItem.setText("Run in separate process");
projectRunOther_menuItem.setMnemonic(KeyEvent.VK_P);
projectRunOther_menuItem.setAccelerator(KeyStroke.getKeyStroke(
KeyEvent.VK_P, ActionEvent.ALT_MASK));
projectRunOther_menuItem
.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
projectRunOther_menuItem_actionPerformed(e);
}
});
statusText_label.setFont(new java.awt.Font("Dialog", 0, 11));
statusText_label.setBorder(BorderFactory.createLoweredBevelBorder());
statusText_label.setMaximumSize(new Dimension(2000, 20));
statusText_label.setPreferredSize(new Dimension(300, 20));
status_panel.setLayout(borderLayout4);
this.addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosed(WindowEvent e) {
this_windowClosed(e);
}

public void windowClosing(WindowEvent e) {
this_windowClosing(e);
}
});
toolbar_panel.setLayout(borderLayout5);
right_splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
right_splitPane.setBorder(null);
right_splitPane.setDividerSize(4);
tools_menu.setFont(new java.awt.Font("Dialog", 0, 11));
tools_menu.setText("Tools");
tools_menu.setMnemonic(KeyEvent.VK_T);
projectDebug_menuItem.setEnabled(false);
projectDebug_menuItem.setFont(new java.awt.Font("Dialog", 0, 11));
projectDebug_menuItem.setText("Debug");
svProperties_menuItem
.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
svProperties_menuItem_actionPerformed(e);
}
});
svProperties_menuItem.setText("Options...");
svProperties_menuItem.setActionCommand("AJDE Console...");
svProperties_menuItem.setFont(new java.awt.Font("Dialog", 0, 11));
svProperties_menuItem.setMnemonic(KeyEvent.VK_O);
svProperties_menuItem.setAccelerator(KeyStroke.getKeyStroke(
KeyEvent.VK_O, ActionEvent.ALT_MASK));
build_toolBar.setBorder(emptyBorder);
build_toolBar.setFloatable(false);
closeConfig_button.setMaximumSize(new Dimension(100, 20));
closeConfig_button.setEnabled(true);
closeConfig_button.setFont(new java.awt.Font("Dialog", 0, 11));
closeConfig_button.setBorder(null);
closeConfig_button.setMinimumSize(new Dimension(24, 20));
closeConfig_button.setPreferredSize(new Dimension(20, 20));
closeConfig_button.setToolTipText("Close build configuration");
closeConfig_button.setIcon(Ajde.getDefault().getIconRegistry()
.getCloseConfigIcon());
closeConfig_button
.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
closeConfig_button_actionPerformed(e);
}
});
openConfig_button.setMaximumSize(new Dimension(100, 20));
openConfig_button.setEnabled(true);
openConfig_button.setFont(new java.awt.Font("Dialog", 0, 11));
openConfig_button.setBorder(null);
openConfig_button.setMinimumSize(new Dimension(24, 20));
openConfig_button.setPreferredSize(new Dimension(20, 20));
openConfig_button.setToolTipText("Select build configuration...");
openConfig_button.setIcon(Ajde.getDefault().getIconRegistry()
.getOpenConfigIcon());
openConfig_button
.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
openConfig_button_actionPerformed(e);
}
});
run_button.setMaximumSize(new Dimension(60, 20));
run_button.setEnabled(true);
run_button.setFont(new java.awt.Font("Dialog", 0, 11));
run_button.setBorder(null);
run_button.setMinimumSize(new Dimension(24, 20));
run_button.setPreferredSize(new Dimension(20, 20));
run_button
.setToolTipText("Run in same VM (hold shift down to run in separate process)");
run_button.setIcon(Ajde.getDefault().getIconRegistry()
.getExecuteIcon());
run_button.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
run_button_actionPerformed(e);
}
});
project_toolBar.setBorder(emptyBorder);
save_button.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
save_button_actionPerformed(e);
}
});
save_button.setIcon(Ajde.getDefault().getIconRegistry()
.getSaveIcon());
save_button.setText("Save");
save_button.setToolTipText("Save");
save_button.setPreferredSize(new Dimension(55, 20));
save_button.setMinimumSize(new Dimension(24, 20));
save_button.setFont(new java.awt.Font("Dialog", 0, 11));
save_button.setBorder(null);
save_button.setMaximumSize(new Dimension(60, 20));
options_button.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
options_button_actionPerformed(e);
}
});
options_button.setIcon(Ajde.getDefault().getIconRegistry()
.getBrowserOptionsIcon());
options_button.setText("Options");
options_button.setToolTipText("Options...");
options_button.setPreferredSize(new Dimension(60, 20));
options_button.setMinimumSize(new Dimension(24, 20));
options_button.setFont(new java.awt.Font("Dialog", 0, 11));
options_button.setBorder(null);
options_button.setMaximumSize(new Dimension(80, 20));
editConfig_button
.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
editConfig_button_actionPerformed(e);
}
});
editConfig_button.setIcon(Ajde.getDefault().getIconRegistry()
.getStructureSwingIcon(IProgramElement.Kind.FILE_LST));
editConfig_button.setText("Edit Config");
editConfig_button.setToolTipText("Edit Config...");
editConfig_button.setPreferredSize(new Dimension(80, 20));
editConfig_button.setMinimumSize(new Dimension(24, 20));
editConfig_button.setFont(new java.awt.Font("Dialog", 0, 11));
editConfig_button.setBorder(null);
editConfig_button.setMaximumSize(new Dimension(80, 20));
file_toolBar.setBorder(emptyBorder);
toolBar_panel.setLayout(borderLayout6);
jLabel1.setFont(new java.awt.Font("Dialog", 0, 11));
jLabel1.setText(" Build: ");
jLabel2.setText(" Run: ");
jLabel2.setFont(new java.awt.Font("Dialog", 0, 11));
// fileStructure_panel.setFont(new java.awt.Font("Dialog", 0, 11));
// browser_panel.setFont(new java.awt.Font("Dialog", 0, 11));
this.getContentPane().add(top_splitPane, BorderLayout.CENTER);
top_splitPane.add(right_splitPane, JSplitPane.RIGHT);
top_splitPane.add(multiView_panel, JSplitPane.LEFT);
right_splitPane.add(messages_panel, JSplitPane.BOTTOM);
right_splitPane.add(editor_panel, JSplitPane.TOP);
// structureView_pane.add(fileStructure_panel, JSplitPane.RIGHT);
// structureView_pane.add(browser_panel, JSplitPane.LEFT);
this.getContentPane().add(status_panel, BorderLayout.SOUTH);
status_panel.add(statusText_label, BorderLayout.CENTER);
this.getContentPane().add(toolbar_panel, BorderLayout.NORTH);
toolbar_panel.add(filler_panel, BorderLayout.CENTER);
toolbar_panel.add(toolBar_panel, BorderLayout.WEST);
// file_toolBar.add(editConfig_button, null);
file_toolBar.add(save_button, null);
file_toolBar.add(options_button, null);
toolBar_panel.add(build_toolBar, BorderLayout.WEST);
toolBar_panel.add(project_toolBar, BorderLayout.CENTER);
project_toolBar.add(jLabel2, null);
project_toolBar.add(run_button, null);
build_toolBar.add(jLabel1, null);
build_toolBar.add(openConfig_button, null);
build_toolBar.add(closeConfig_button, null);
toolBar_panel.add(file_toolBar, BorderLayout.EAST);
menuBar.add(jMenu1);
menuBar.add(jMenu2);
menuBar.add(tools_menu);
jMenu1.add(jMenuItem1);
jMenu1.addSeparator();
jMenu1.add(exit_menuItem);
jMenu2.add(projectBuild_menuItem);
jMenu2.add(projectRun_menuItem);
jMenu2.add(projectRunOther_menuItem);
// jMenu2.add(projectDebug_menuItem);
tools_menu.add(joinpointProbe_menuItem);
tools_menu.add(svProperties_menuItem);
top_splitPane.setDividerLocation(380);
right_splitPane.setDividerLocation(500);
project_toolBar.addSeparator();
project_toolBar.addSeparator();
}

private void exit_menuItem_actionPerformed(ActionEvent e) {
quit();
}

private void this_windowClosing(WindowEvent e) {
quit();
}

private void quit() {
this.dispose();
System.exit(0);
}

void treeMode_comboBox_actionPerformed(ActionEvent e) {
}

void save_button_actionPerformed(ActionEvent e) {
BrowserManager.getDefault().getEditorManager().saveContents();
}

void this_windowClosed(WindowEvent e) {
quit();
}

public void showMessagesPanel(BrowserMessageHandler handler) {
right_splitPane.setDividerLocation(right_splitPane.getHeight() - 100);
messages_panel.showMessageHandlerPanel(handler, true);
}

public void hideMessagesPanel(BrowserMessageHandler handler) {
right_splitPane.setDividerLocation(right_splitPane.getHeight());
messages_panel.showMessageHandlerPanel(handler, false);
}

void jMenuItem1_actionPerformed(ActionEvent e) {
BrowserManager.getDefault().getEditorManager().saveContents();
}

void projectBuild_menuItem_actionPerformed(ActionEvent e) {
BrowserManager.getDefault().saveAll();
if (EditorManager.isShiftDown(e.getModifiers())) {
buildFresh();
} else {
build();
}
}

void run_button_actionPerformed(ActionEvent e) {
if (EditorManager.isShiftDown(e.getModifiers())) {
runInNewVM();
} else {
runInSameVM();
}
}

void projectRunOther_menuItem_actionPerformed(ActionEvent e) {
runInNewVM();
}

void projectRun_menuItem_actionPerformed(ActionEvent e) {
if (EditorManager.isShiftDown(e.getModifiers())) {
runInNewVM();
} else {
runInSameVM();
}
}

void build_button_actionPerformed(ActionEvent e) {
BrowserManager.getDefault().saveAll();
if (EditorManager.isShiftDown(e.getModifiers())) {
buildFresh();
} else {
build();
}
}

void options_button_actionPerformed(ActionEvent e) {
Ajde.getDefault().showOptionsFrame();
}

void editConfig_button_actionPerformed(ActionEvent e) {
BrowserManager.getDefault().openFile(
Ajde.getDefault().getBuildConfigManager()
.getActiveConfigFile());
refreshBuildMenu();
}

public void resetSourceEditorPanel() {
right_splitPane.removeAll();
right_splitPane.add(sourceEditor_panel, JSplitPane.TOP);
}

private void svProperties_menuItem_actionPerformed(ActionEvent e) {
Ajde.getDefault().showOptionsFrame();
}

private void openConfig_button_actionPerformed(ActionEvent e) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setCurrentDirectory(lastChosenDir);
fileChooser.setFileFilter(new FileFilter() {
public boolean accept(File f) {
return (f.getPath().endsWith(".lst") || f.isDirectory());
}

public String getDescription() {
return "AspectJ Build Configuration (*.lst)";
}
});
int returnVal = fileChooser.showOpenDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File result = fileChooser.getSelectedFile();
String path = result.getAbsolutePath();// .replace('\\', '/');
if (!Ajde.getDefault().getBuildConfigManager()
.getAllBuildConfigFiles().contains(path)) {
Ajde.getDefault().getBuildConfigManager()
.getAllBuildConfigFiles().add(0, path);
}
Ajde.getDefault().getBuildConfigManager().setActiveConfigFile(
path);
lastChosenDir = result.getParentFile();
if (null == lastChosenDir) {
lastChosenDir = CURRENT_DIR;
}
refreshBuildMenu();
}
}

private void closeConfig_button_actionPerformed(ActionEvent e) {
Ajde.getDefault().getBuildConfigManager()
.getAllBuildConfigFiles().remove(
Ajde.getDefault().getBuildConfigManager()
.getActiveConfigFile());
if (!Ajde.getDefault().getBuildConfigManager()
.getAllBuildConfigFiles().isEmpty()) {
Ajde.getDefault().getBuildConfigManager().setActiveConfigFile(
(String) Ajde.getDefault().getBuildConfigManager()
.getAllBuildConfigFiles().get(0));
}
refreshBuildMenu();
}

private void buildFresh() {
Ajde.getDefault().runBuildInDifferentThread(Ajde.getDefault()
.getBuildConfigManager().getActiveConfigFile(), true);
}

private void build() {
Ajde.getDefault().runBuildInDifferentThread(Ajde.getDefault()
.getBuildConfigManager().getActiveConfigFile(), false);
}

private void runInSameVM() {
Ajde.getDefault().runInSameVM();
}

private void runInNewVM() {
Ajde.getDefault().runInNewVM();
}

}

+ 0
- 107
ajbrowser/testsrc/org/aspectj/tools/ajbrowser/InteractiveBrowserTest.java View File

@@ -1,107 +0,0 @@
/* *******************************************************************
* Copyright (c) 1999-2001 Xerox Corporation,
* 2002 Palo Alto Research Center, Incorporated (PARC).
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Xerox/PARC initial implementation
* ******************************************************************/


package org.aspectj.tools.ajbrowser;

import java.io.File;
import javax.swing.*;
import junit.framework.*;
//import org.aspectj.asm.*;
import org.aspectj.bridge.*;
import org.aspectj.bridge.IMessage;
import org.aspectj.ajde.*;

/**
* Define system property "ajbrowser.interactive" to run.
* @author Mik Kersten
*/
public class InteractiveBrowserTest extends TestCase {
static boolean interactive() {
return (null != System.getProperty("ajbrowser.interactive"));
}
public InteractiveBrowserTest(String name) {
super(name);
}

public static TestSuite suite() {
TestSuite result = new TestSuite();
result.addTestSuite(InteractiveBrowserTest.class);
return result;
}

public void testInitNoArgs() {
//String[] args = { "C:/Dev/aspectj/modules/ajde/testdata/examples/figures-coverage/all.lst" };
String[] args = { };
BrowserManager.getDefault().init(args, true);
}

public void testAddProjectTask() {
if (!interactive()) {
return;
}
BrowserManager.getDefault().init(new String[]{}, true);
Ajde.getDefault().getTaskListManager().addProjectTask(
"project-level task",
IMessage.ERROR);

BrowserManager.getDefault().showMessages();

assertTrue("confirmation result", verifySuccess("Project task is visible."));
}
public void testAddSourceLineTasks() {
if (!interactive()) {
return;
}
BrowserManager.getDefault().init(new String[]{}, true);
ISourceLocation dummyLocation = new SourceLocation(new File("<file>"), 0, 0);

Ajde.getDefault().getTaskListManager().addSourcelineTask(
"error task",
dummyLocation,
IMessage.ERROR);

Ajde.getDefault().getTaskListManager().addSourcelineTask(
"warning task",
dummyLocation,
IMessage.WARNING);
Ajde.getDefault().getTaskListManager().addSourcelineTask(
"info task",
dummyLocation,
IMessage.INFO);
BrowserManager.getDefault().showMessages();

assertTrue("confirmation result", verifySuccess("3 kinds of sourceline tasks are visible."));
}
private boolean verifySuccess(String message) {
int result = JOptionPane.showConfirmDialog(
BrowserManager.getDefault().getRootFrame(),
"Verify Results",
message,
JOptionPane.YES_NO_OPTION);
return result == JOptionPane.YES_OPTION;
}
protected void setUp() throws Exception {
super.setUp();
}
protected void tearDown() throws Exception {
super.tearDown();
}
}

Loading…
Cancel
Save