Java tutorial
/* * Copyright (c) 2010-2012 Research In Motion Limited. All rights reserved. * * This program and the accompanying materials are made available * under the terms of the Eclipse Public License, Version 1.0, * which accompanies this distribution and is available at * * http://www.eclipse.org/legal/epl-v10.html * */ package net.rim.ejde.internal.ui.wizards.imports; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.Vector; import net.rim.ejde.internal.core.ContextManager; import net.rim.ejde.internal.core.IConstants; import net.rim.ejde.internal.imports.LegacyImportHelper; import net.rim.ejde.internal.util.ImportUtils; import net.rim.ejde.internal.util.Messages; import net.rim.ejde.internal.util.StatusFactory; import net.rim.ide.OSUtils; import net.rim.ide.Project; import net.rim.ide.RIA; import net.rim.ide.Workspace; import org.apache.log4j.Logger; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.jdt.launching.IVMInstall; import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTableViewer; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.events.FocusAdapter; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; 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.Display; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; /** * This is a common UI group which allow user to choose projects from a jdw file or the Samples workspace of the selected * BlackBerry JRE. This UI group communicates with the class which uses it through the {@link IProjectImportSelectionUICallback}. * * */ public class ProjectImportSelectionUI { static private final Logger _log = Logger.getLogger(ProjectImportSelectionUI.class); static public final String SAMPLE_JDW_RELATIVE_PATH = "samples/samples.jdw"; private final static int BUTTON_DEFAULT_WIDTH = 70; private IPath _currentWorkspace; private Button _browseButton; private Text _importPathField; private Button _copyButton; private Button _selectDependencyButton; public CheckboxTableViewer _tableViewer; private Button _selectAllButton; private Button _deselectAllButton; Composite _parent; Set<String> _existingProjects; IProjectImportSelectionUICallback _callback; private boolean _allowBrowseJDW; private IVMInstall _currentVM; private boolean _isValidWorkspaceFile = false; private List<IImportTypeChangeListener> listeners; public ProjectImportSelectionUI(Composite parent, IProjectImportSelectionUICallback callback, boolean allowBrowseJDW) { _parent = parent; _callback = callback; _allowBrowseJDW = allowBrowseJDW; IWorkspace workspace = ResourcesPlugin.getWorkspace(); IProject[] eclipseProjects = workspace.getRoot().getProjects(); _existingProjects = new HashSet<String>(eclipseProjects.length); if (0 < eclipseProjects.length) { for (int i = 0; i < eclipseProjects.length; i++) { _existingProjects.add(eclipseProjects[i].getName()); } } listeners = new ArrayList<IImportTypeChangeListener>(); } public void setCurrentVM(IVMInstall vm) { _currentVM = vm; } /** * Checks if all dependency projects of the projects selected on the UI are also selected. * * @return */ public String hasDependencyProblem() { Table table = _tableViewer.getTable(); TableItem[] items = table.getItems(); Object[] checkedProjects = _tableViewer.getCheckedElements(); for (TableItem item : items) { Project project = (Project) item.getData(); if (_tableViewer.getChecked(project)) { continue; } Project masterProject = isDependedByOthers(project, checkedProjects, new HashSet<Project>()); if (masterProject == null) { continue; } return NLS.bind(Messages.GenericSelectionPage_DEPENDENCY_ERROR_MSG, new String[] { project.getDisplayName(), masterProject.getDisplayName() }); } return IConstants.EMPTY_STRING; } /** * Gets import type. * * @return */ public int getImportType() { return _copyButton.getSelection() ? LegacyImportHelper.COPY_IMPORT : LegacyImportHelper.LINK_IMPORT; } /** * Gets the number of selected projects. * * @return */ public int getSelectedProjectsNumber() { return _tableViewer.getCheckedElements().length; } /** * Gets the number of exist projects. * * @return */ public int getExistingProjectsNumber() { return _tableViewer.getGrayedElements().length; } /** * Gets the number of all projects. * * @return */ public int getAllProjectNumber() { return _tableViewer.getTable().getItemCount(); } /** * Returns a value indicating if the selected workspace file is valid * * @return */ public boolean isValidWorkspaceFile() { return _isValidWorkspaceFile; } /** * Gets the current workspace path. * * @return */ public IPath getCurrentWorkspace() { return _currentWorkspace; } private boolean projectExists(String projectName) { if (null == _existingProjects || _existingProjects.isEmpty()) return false; return _existingProjects.contains(projectName); } public void loadWorkspace(IPath workspacePath) { if (_currentVM == null) { return; } if (workspacePath == null || workspacePath.isEmpty()) { return; } if (workspacePath.equals(_currentWorkspace)) { return; } _currentWorkspace = workspacePath; File workspaceFile = workspacePath.toFile(); if (!workspaceFile.exists() || !workspaceFile.isFile()) { _isValidWorkspaceFile = false; _tableViewer.setInput(null); _callback.setComplete(false); return; } _isValidWorkspaceFile = true; LoadLegacyWorkspaceTask task = new LoadLegacyWorkspaceTask(workspaceFile); ProgressMonitorDialog monitorDialog = new ProgressMonitorDialog(ContextManager.getActiveWorkbenchShell()); try { monitorDialog.run(false, false, task); } catch (Throwable e) { _log.debug(e.getMessage(), e); _callback.setComplete(false); } Workspace workspace = task.getWorkspace(); List<Project> nonExistingProjects = new ArrayList<Project>(); List<Project> allProjects = new ArrayList<Project>(); int numProjects = workspace.getNumProjects(); for (int i = 0; i < numProjects; i++) { Project project = workspace.getProject(i); String projectName = project.getDisplayName(); // do not count AEPs if (project.getType() != Project.CLDC_APPLICATION_ENTRY && project.getType() != Project.MIDLET_ENTRY) { if (!projectExists(projectName)) { // checks if the project // already exists in the previous workspace nonExistingProjects.add(project); } allProjects.add(project); } } Collections.sort(allProjects, ProjectNameComparator); _tableViewer.setInput(allProjects); _tableViewer.setCheckedElements(nonExistingProjects.toArray(new Project[nonExistingProjects.size()])); checkExistingProjects(); if (nonExistingProjects.size() == 0) { _callback.setComplete(false); } else { _callback.setComplete(true); } } private void checkExistingProjects() { TableItem[] items = _tableViewer.getTable().getItems(); IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); for (TableItem item : items) { Project project = (Project) item.getData(); if (workspaceRoot.getProject(project.getDisplayName()).exists()) { // existing projects are mark as grayed and checked item.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY)); item.setGrayed(true); item.setChecked(true); } } } /** * Gets selected projects. * * @return */ public Set<Project> getSelectedProjects() { Set<Project> projectSet = new HashSet<Project>(); TableItem[] items = _tableViewer.getTable().getItems(); for (TableItem item : items) { if (item.getChecked() && !item.getGrayed()) { projectSet.add((Project) (item.getData())); } } return projectSet; } /** * Gets a project based on project name * * @param projectName * @return */ public Project getProject(String projectName) { TableItem[] items = _tableViewer.getTable().getItems(); Project project; for (TableItem item : items) { project = (Project) item.getData(); if (project.getDisplayName().equalsIgnoreCase(projectName)) { return project; } } return null; } /** * Enable/disable the UI. * * @param enabled */ public void enableUI(boolean enabled) { if (_browseButton != null) { _browseButton.setEnabled(enabled); } if (_importPathField != null) { _importPathField.setEnabled(enabled); } if (_copyButton != null && _allowBrowseJDW) { _copyButton.setEnabled(enabled); } if (_tableViewer != null) { _tableViewer.getTable().setEnabled(enabled); } if (_selectAllButton != null) { _selectAllButton.setEnabled(enabled); } if (_deselectAllButton != null) { _deselectAllButton.setEnabled(enabled); } } /** * Checks if the given <code>project</code> is dependent by any checked project in the <code>checkedProjects</code> but is not * in the <code>dependentProjects</code>. * * @param project * @param checkedProjects * @param dependentProjects * @return Project the first project which depends on the given <code>project</code>. */ private Project isDependedByOthers(Project project, Object[] checkedProjects, Set<Project> dependentProjects) { for (Object obj : checkedProjects) { Project checkedProject = (Project) obj; if (!dependentProjects.contains(checkedProject)) { for (int i = 0; i < checkedProject.getNumDependsDirectlyOn(); i++) { if (project.equals(checkedProject.getDependsDirectlyOn(i))) { return checkedProject; } } } } return null; } public void creatContent() { // workspace location entry field Composite pathComp = new Composite(_parent, SWT.NONE); pathComp.setLayout(new GridLayout(3, false)); pathComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); if (_allowBrowseJDW) { String importLocationLabel = Messages.GenericSelectionPage_WORKSPACE_LABEL; Label projectContentsLabel = new Label(pathComp, SWT.NONE); projectContentsLabel.setText(importLocationLabel); //$NON-NLS-1$*/ projectContentsLabel.setLayoutData(new GridData(SWT.BEGINNING)); // jdw path text _importPathField = new Text(pathComp, SWT.BORDER); _importPathField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); _importPathField.setText(""); //$NON-NLS-1$ _importPathField.addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { if ((e.keyCode == SWT.CR) || (e.keyCode == SWT.KEYPAD_CR)) { _log.debug("\"Entry\" was pressed"); String workspaceFileToImport = _importPathField.getText(); loadWorkspace(new Path(workspaceFileToImport)); } } }); _importPathField.addFocusListener(new FocusAdapter() { @Override public void focusLost(FocusEvent e) { String workspaceFilePath = _importPathField.getText(); loadWorkspace(new Path(workspaceFilePath)); } }); // browse button _browseButton = new Button(pathComp, SWT.PUSH); GridData data = new GridData(GridData.END); data.widthHint = BUTTON_DEFAULT_WIDTH; _browseButton.setLayoutData(data); _browseButton.setText(Messages.IConstants_BROWSE_BUTTON_TITLE); //$NON-NLS-1$ _browseButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { FileDialog dialog = new FileDialog(_importPathField.getShell()); String[] filters = new String[] { "*.jdw" }; String[] filterNames = new String[] { Messages.BLACKBERRY_WORKSPACE_FILTER_NAME }; dialog.setFilterExtensions(filters); dialog.setFilterNames(filterNames); String workspaceFileToImport = dialog.open(); if (null != workspaceFileToImport) { _importPathField.setText(workspaceFileToImport); loadWorkspace(new Path(workspaceFileToImport)); } } }); } Composite comp = new Composite(_parent, SWT.NONE); GridLayout gridLayout = new GridLayout(3, false); comp.setLayout(gridLayout); GridData gd = new GridData(GridData.FILL_BOTH); gd.heightHint = 250; comp.setLayoutData(gd); // projects label Label projectsLabel = new Label(comp, SWT.NONE); projectsLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, true, false, 3, 1)); projectsLabel.setText(Messages.GenericSelectionPage_PROJECT_TABLE_TITLE); // projects table _tableViewer = CheckboxTableViewer.newCheckList(comp, SWT.SINGLE | SWT.FULL_SELECTION | SWT.CHECK | SWT.BORDER); _tableViewer.setContentProvider(new ArrayContentProvider()); _tableViewer.setLabelProvider(new ProjectTableLabelProvider()); _tableViewer.addCheckStateListener(new CheckStateListenerImpl()); Table table = _tableViewer.getTable(); table.addKeyListener(new KeyListenerImpl()); table.setHeaderVisible(true); table.setLinesVisible(true); table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 2)); TableColumn projectIconColumn, projectNameColumn; projectIconColumn = new TableColumn(table, SWT.NONE); projectIconColumn.setText("Project Icon"); //$NON-NLS-1$ projectIconColumn.setWidth(80); projectNameColumn = new TableColumn(table, SWT.NONE); projectNameColumn.setText("Project Name"); //$NON-NLS-1$ projectNameColumn.setWidth(450); // select / de-select project buttons _selectAllButton = new Button(comp, SWT.PUSH); _selectAllButton.setText("Select All"); //$NON-NLS-1$ GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL); gridData.widthHint = BUTTON_DEFAULT_WIDTH; _selectAllButton.setLayoutData(gridData); _deselectAllButton = new Button(comp, SWT.PUSH); //_deselectAllButton.setText( _resources.getString( "Wizard.GenericSelectionPage.DeselectAll" ) ); //$NON-NLS-1$ _deselectAllButton.setText("Deselect All"); //$NON-NLS-1$ GridData gridData2 = new GridData(SWT.FILL, SWT.TOP, false, false); gridData2.widthHint = BUTTON_DEFAULT_WIDTH; _deselectAllButton.setLayoutData(gridData2); _selectAllButton.addSelectionListener(new SelectionAdapter() { /* * (non-Javadoc) * * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org .eclipse .swt.events.SelectionEvent) */ @Override public void widgetSelected(SelectionEvent e) { Table table = _tableViewer.getTable(); for (TableItem item : table.getItems()) { if (!item.getGrayed()) { item.setChecked(true); } } table.redraw(); _callback.setMessage(IConstants.EMPTY_STRING, IMessageProvider.NONE); _callback.setComplete(table.getItems().length > 0); // donot } }); _deselectAllButton.addSelectionListener(new SelectionAdapter() { /* * (non-Javadoc) * * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org .eclipse .swt.events.SelectionEvent) */ @Override public void widgetSelected(SelectionEvent e) { Table table = _tableViewer.getTable(); for (TableItem item : table.getItems()) { if (!item.getGrayed()) { item.setChecked(false); } } _callback.setMessage(Messages.GenericSelectionPage_NO_PROJECT_SELECTED_ERROR_MSG, IMessageProvider.ERROR); _callback.setComplete(false); } }); // the copy project checkbox _copyButton = new Button(comp, SWT.CHECK); _copyButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, true, false, 3, 1)); _copyButton.setText(Messages.GenericSelectionPage_COPY_MODEL_LABEL); // by default we suggest users to use copy model _copyButton.setSelection(true); // if it is sample import wizard, we only allow copy import _copyButton.setEnabled(_allowBrowseJDW); _copyButton.addSelectionListener(new SelectionListener() { @Override public void widgetDefaultSelected(SelectionEvent e) { // TODO Auto-generated method stub } @Override public void widgetSelected(SelectionEvent e) { fireImportTypeChangeEvent(e); } }); // the select dependency project checkbox _selectDependencyButton = new Button(comp, SWT.CHECK); _selectDependencyButton.setText("Automatically select dependent projects"); // by default we suggest users to use copy model _selectDependencyButton.setSelection(true); } public void addImportTypeChangeListener(IImportTypeChangeListener listener) { listeners.add(listener); } private void fireImportTypeChangeEvent(SelectionEvent event) { for (IImportTypeChangeListener listener : listeners) { listener.ImportTypeChanged(event); } } private class KeyListenerImpl extends KeyAdapter { long startTime = 0; char[] inputs; int index = 0; /** * We listen to the keys */ public void keyPressed(KeyEvent e) { if (!((e.character >= 'a' && e.character <= 'z') || (e.character >= 'A' && e.character <= 'Z'))) { return; } if ((startTime == 0) || (System.currentTimeMillis() - startTime) > 1000) { startTime = System.currentTimeMillis(); inputs = new char[10]; index = 0; } inputs[index++] = e.character; String inputString = new String(inputs); inputString = inputString.trim().toLowerCase(); Table table = _tableViewer.getTable(); TableItem[] items = table.getItems(); for (int i = 0; i < items.length; i++) { Project project = (Project) items[i].getData(); String projectName = project.getDisplayName().toLowerCase(); if (projectName.startsWith(inputString)) { _tableViewer.setSelection(new StructuredSelection(new Project[] { project }), true); break; } } } } private class CheckStateListenerImpl implements ICheckStateListener { public void checkStateChanged(CheckStateChangedEvent event) { Project project = (Project) event.getElement(); if (event.getChecked()) { _log.debug("Checked : [" + project.getDisplayName() + "]"); //$NON-NLS-1$ //$NON-NLS-2$ } else { _log.debug("Unchecked : [" + project.getDisplayName() + "]"); //$NON-NLS-1$ //$NON-NLS-2$ } CheckboxTableViewer view = (CheckboxTableViewer) event.getSource(); if (view.getGrayed(project)) { // if the checked item was grayed, we always mark it as checked view.setChecked(project, true); return; } if (_selectDependencyButton.getSelection()) { checkProject(view, project, event.getChecked()); } _callback.setComplete(true); } private void checkProject(CheckboxTableViewer view, Project project, boolean checked) { Set<Project> dependentProjects = null; try { dependentProjects = ImportUtils.getAllReferencedProjects(project); } catch (CoreException e) { _log.error(e.getMessage(), e); } if (dependentProjects == null || dependentProjects.size() == 0) { return; } Table table = view.getTable(); TableItem[] items = table.getItems(); Object[] checkedProjects = view.getCheckedElements(); for (TableItem item : items) { Project data = (Project) item.getData(); if (dependentProjects.contains(data)) { if (checked) { if (!item.getGrayed() && !item.getChecked()) { // if the dependent project is not grayed, gray // it item.setChecked(true); } } else { if (!item.getGrayed() && item.getChecked() && (isDependedByOthers(data, checkedProjects, dependentProjects) == null)) { // if the dependent project is not an existing project, it is checked and it is not depended by // another project, un-gray it item.setGrayed(false); item.setChecked(false); } } } } } } protected class ProjectTableLabelProvider extends LabelProvider implements ITableLabelProvider { public Image getColumnImage(Object element, int columnIndex) { if (null != element && element instanceof Project && columnIndex >= 0) { Project project = (Project) element; switch (columnIndex) { case 0: { Vector<File> icons = project.getIcons(); Image icon = null; try { if (null != icons && !icons.isEmpty()) { File iconFile = new File( OSUtils.replaceFileSeperator(icons.firstElement().getAbsolutePath())); if (!iconFile.exists()) { return null; } ImageData imageData = new ImageData( new BufferedInputStream(new FileInputStream(iconFile))); imageData = imageData.scaledTo(_tableViewer.getTable().getItemHeight(), _tableViewer.getTable().getItemHeight()); icon = new Image(Display.getCurrent(), imageData); } } catch (FileNotFoundException e) { _log.debug("", e); //$NON-NLS-1$ } return icon; } default: return null; //$NON-NLS-1$ } } return null; } public String getColumnText(Object element, int columnIndex) { if (null != element && element instanceof Project && columnIndex >= 0) { Project project = (Project) element; switch (columnIndex) { case 1: return project.getDisplayName(); default: return ""; //$NON-NLS-1$ } } return ""; //$NON-NLS-1$ } } static Comparator<Project> ProjectNameComparator = new Comparator<Project>() { public int compare(Project project1, Project project2) { return project1.getDisplayName().toUpperCase().compareTo(project2.getDisplayName().toUpperCase()); } }; protected class LoadLegacyWorkspaceTask implements IRunnableWithProgress { File workspaceFileToImport; Workspace workspace; // Workspace workspace; // List< Project > notExistingProjects; public LoadLegacyWorkspaceTask(File workspace) { workspaceFileToImport = workspace; } /* * (non-Javadoc) * * @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse .core.runtime.IProgressMonitor) */ @Override public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { if (workspaceFileToImport.exists() && workspaceFileToImport.isFile()) { monitor.beginTask("Loading workspace...", 10); try { RIA ria = ContextManager.PLUGIN.getRIA(_currentVM.getInstallLocation().getPath()); workspace = createWorkspace(workspaceFileToImport, ria); } catch (Throwable e) { _log.debug(e.getMessage(), e); return; } monitor.worked(8); if (workspace == null) { throw new InvocationTargetException( new CoreException(StatusFactory.createErrorStatus("Could not load the workspace."))); } } } private Workspace createWorkspace(File jdw, RIA ria) { Workspace workspace = null; try { workspace = new Workspace(jdw, ria); workspace.save(); } catch (Throwable e) { _log.debug("", e); } return workspace; } public Workspace getWorkspace() { return workspace; } } static protected interface IImportTypeChangeListener { public void ImportTypeChanged(SelectionEvent event); } }