Java tutorial
//============================================================================ // // Copyright (C) 2002-2014 David Schneider, Lars Kdderitzsch // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // //============================================================================ package net.sf.eclipsecs.ui.properties; import java.util.List; import net.sf.eclipsecs.core.config.ICheckConfiguration; import net.sf.eclipsecs.core.jobs.BuildProjectJob; import net.sf.eclipsecs.core.jobs.ConfigureDeconfigureNatureJob; import net.sf.eclipsecs.core.jobs.TransformCheckstyleRulesJob; import net.sf.eclipsecs.core.nature.CheckstyleNature; import net.sf.eclipsecs.core.projectconfig.FileSet; import net.sf.eclipsecs.core.projectconfig.IProjectConfiguration; import net.sf.eclipsecs.core.projectconfig.ProjectConfigurationFactory; import net.sf.eclipsecs.core.projectconfig.ProjectConfigurationWorkingCopy; import net.sf.eclipsecs.core.projectconfig.filters.IFilter; import net.sf.eclipsecs.core.util.CheckstyleLog; import net.sf.eclipsecs.core.util.CheckstylePluginException; import net.sf.eclipsecs.ui.CheckstyleUIPlugin; import net.sf.eclipsecs.ui.CheckstyleUIPluginPrefs; import net.sf.eclipsecs.ui.Messages; import net.sf.eclipsecs.ui.config.CheckConfigurationWorkingSetEditor; import net.sf.eclipsecs.ui.properties.filter.IFilterEditor; import net.sf.eclipsecs.ui.properties.filter.PluginFilterEditors; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialogWithToggle; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTableViewer; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.window.Window; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; 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.Control; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.TabFolder; import org.eclipse.swt.widgets.TabItem; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.dialogs.PropertyPage; /** * Property page for projects to enable checkstyle audit. * * @author Lars Kdderitzsch */ public class CheckstylePropertyPage extends PropertyPage { // // controls // /** The tab folder. */ private TabFolder mMainTab = null; /** button to enable checkstyle for the project. */ private Button mChkEnable; /** button to enable/disable the simple configuration. */ private Button mChkSimpleConfig; /** * button to enable/disable synchronizing the checkstyle configuration with * the formatter configuration. */ private Button mChkSyncFormatter; /** the container holding the file sets editor. */ private Composite mFileSetsContainer; /** the editor for the file sets. */ private IFileSetsEditor mFileSetsEditor; /** viewer to display the known checkstyle filters. */ private CheckboxTableViewer mFilterList; /** button to open a filter editor. */ private Button mBtnEditFilter; /** used to display the filter description. */ private Text mTxtFilterDescription; // // other members // /** controller of this page. */ private PageController mPageController; /** the actual working data for this form. */ private ProjectConfigurationWorkingCopy mProjectConfig; /** the local configurations working set editor. */ private CheckConfigurationWorkingSetEditor mWorkingSetEditor; private boolean mCheckstyleInitiallyActivated; // // methods // /** * Returns the project configuration. * * @return the project configuration */ public ProjectConfigurationWorkingCopy getProjectConfigurationWorkingCopy() { return mProjectConfig; } /** * {@inheritDoc} */ public void setElement(IAdaptable element) { super.setElement(element); IProject project = null; try { // // Get the project. // IResource resource = (IResource) element; if (resource.getType() == IResource.PROJECT) { project = (IProject) resource; } IProjectConfiguration projectConfig = ProjectConfigurationFactory.getConfiguration(project); mProjectConfig = new ProjectConfigurationWorkingCopy(projectConfig); mCheckstyleInitiallyActivated = project.hasNature(CheckstyleNature.NATURE_ID); } catch (CoreException e) { handleConfigFileError(e, project); } catch (CheckstylePluginException e) { handleConfigFileError(e, project); } } private void handleConfigFileError(Exception e, IProject project) { CheckstyleLog.log(e, Messages.errorOpeningPropertiesPage); CheckstyleUIPlugin.warningDialog(null, Messages.errorOpeningPropertiesPage, e); IProjectConfiguration projectConfig = ProjectConfigurationFactory .createDefaultProjectConfiguration(project); mProjectConfig = new ProjectConfigurationWorkingCopy(projectConfig); try { mCheckstyleInitiallyActivated = project.hasNature(CheckstyleNature.NATURE_ID); } catch (CoreException e1) { CheckstyleUIPlugin.errorDialog(null, e1.getMessage(), e1, true); } } /** * {@inheritDoc} */ public Control createContents(Composite parent) { Composite container = null; try { this.mPageController = new PageController(); // suppress default- & apply-buttons noDefaultAndApplyButton(); mMainTab = new TabFolder(parent, SWT.TOP); mMainTab.setLayoutData(new GridData(GridData.FILL_BOTH)); mMainTab.addSelectionListener(mPageController); // create the main container container = new Composite(mMainTab, SWT.NULL); container.setLayout(new FormLayout()); container.setLayoutData(new GridData(GridData.FILL_BOTH)); // create the checkbox to enable/diable the simple configuration this.mChkSimpleConfig = new Button(container, SWT.CHECK); this.mChkSimpleConfig.setText(Messages.CheckstylePropertyPage_btnUseSimpleConfig); this.mChkSimpleConfig.addSelectionListener(this.mPageController); this.mChkSimpleConfig.setSelection(mProjectConfig.isUseSimpleConfig()); FormData fd = new FormData(); // fd.left = new FormAttachment(this.mChkEnable, 0, SWT.RIGHT); fd.top = new FormAttachment(0, 3); fd.right = new FormAttachment(100, -3); this.mChkSimpleConfig.setLayoutData(fd); // create the checkbox to enabel/disable checkstyle this.mChkEnable = new Button(container, SWT.CHECK); this.mChkEnable.setText(Messages.CheckstylePropertyPage_btnActivateCheckstyle); this.mChkEnable.addSelectionListener(this.mPageController); this.mChkEnable.setSelection(mCheckstyleInitiallyActivated); fd = new FormData(); fd.left = new FormAttachment(0, 3); fd.top = new FormAttachment(0, 3); fd.right = new FormAttachment(this.mChkSimpleConfig, 3, SWT.LEFT); this.mChkEnable.setLayoutData(fd); // create the checkbox for formatter synching this.mChkSyncFormatter = new Button(container, SWT.CHECK); this.mChkSyncFormatter.setText(Messages.CheckstylePropertyPage_btnSyncFormatter); this.mChkSyncFormatter.addSelectionListener(this.mPageController); this.mChkSyncFormatter.setSelection(mProjectConfig.isSyncFormatter()); fd = new FormData(); fd.left = new FormAttachment(0, 3); fd.top = new FormAttachment(this.mChkEnable, 3, SWT.BOTTOM); this.mChkSyncFormatter.setLayoutData(fd); // create the configuration area mFileSetsContainer = new Composite(container, SWT.NULL); Control configArea = createFileSetsArea(mFileSetsContainer); fd = new FormData(); fd.left = new FormAttachment(0, 3); fd.top = new FormAttachment(this.mChkSyncFormatter, 6, SWT.BOTTOM); fd.right = new FormAttachment(100, -3); fd.bottom = new FormAttachment(45); configArea.setLayoutData(fd); // create the filter area Control filterArea = createFilterArea(container); fd = new FormData(); fd.left = new FormAttachment(0, 3); fd.top = new FormAttachment(configArea, 3, SWT.BOTTOM); fd.right = new FormAttachment(100, -3); fd.bottom = new FormAttachment(100, -3); fd.width = 500; filterArea.setLayoutData(fd); // create the local configurations area Control localConfigArea = createLocalConfigArea(mMainTab); TabItem mainItem = new TabItem(mMainTab, SWT.NULL); mainItem.setControl(container); mainItem.setText(Messages.CheckstylePropertyPage_tabMain); TabItem localItem = new TabItem(mMainTab, SWT.NULL); localItem.setControl(localConfigArea); localItem.setText(Messages.CheckstylePropertyPage_tabCheckConfigs); } catch (CheckstylePluginException e) { CheckstyleUIPlugin.errorDialog(getShell(), Messages.errorOpeningPropertiesPage, e, true); } return container; } /** * Creates the file sets area. * * @param fileSetsContainer * the container to add the file sets area to */ private Control createFileSetsArea(Composite fileSetsContainer) throws CheckstylePluginException { Control[] controls = fileSetsContainer.getChildren(); for (int i = 0; i < controls.length; i++) { controls[i].dispose(); } if (mProjectConfig.isUseSimpleConfig()) { mFileSetsEditor = new SimpleFileSetsEditor(this); } else { mFileSetsEditor = new ComplexFileSetsEditor(this); } mFileSetsEditor.setFileSets(mProjectConfig.getFileSets()); Control editor = mFileSetsEditor.createContents(mFileSetsContainer); fileSetsContainer.setLayout(new FormLayout()); FormData fd = new FormData(); fd.left = new FormAttachment(0); fd.top = new FormAttachment(0); fd.right = new FormAttachment(100); fd.bottom = new FormAttachment(100); editor.setLayoutData(fd); return fileSetsContainer; } /** * Creates the filter area. * * @param container * the container to add the filter area */ private Control createFilterArea(Composite container) { FormData fd = new FormData(); // group composite containing the filter settings Group filterArea = new Group(container, SWT.NULL); filterArea.setText(Messages.CheckstylePropertyPage_titleFilterGroup); filterArea.setLayout(new FormLayout()); this.mFilterList = CheckboxTableViewer.newCheckList(filterArea, SWT.BORDER); this.mBtnEditFilter = new Button(filterArea, SWT.PUSH); fd.left = new FormAttachment(0, 3); fd.top = new FormAttachment(0, 3); fd.right = new FormAttachment(this.mBtnEditFilter, -3, SWT.LEFT); fd.bottom = new FormAttachment(60, -3); this.mFilterList.getTable().setLayoutData(fd); this.mFilterList.setLabelProvider(new LabelProvider() { public String getText(Object element) { StringBuffer buf = new StringBuffer(); if (element instanceof IFilter) { IFilter filter = (IFilter) element; buf.append(filter.getName()); if (filter.getPresentableFilterData() != null) { buf.append(": ").append(filter.getPresentableFilterData()); //$NON-NLS-1$ } } else { buf.append(super.getText(element)); } return buf.toString(); } }); this.mFilterList.setContentProvider(new ArrayContentProvider()); this.mFilterList.addSelectionChangedListener(this.mPageController); this.mFilterList.addDoubleClickListener(this.mPageController); this.mFilterList.addCheckStateListener(this.mPageController); this.mBtnEditFilter.setText(Messages.CheckstylePropertyPage_btnChangeFilter); this.mBtnEditFilter.addSelectionListener(this.mPageController); fd = new FormData(); fd.top = new FormAttachment(0, 3); fd.right = new FormAttachment(100, -3); this.mBtnEditFilter.setLayoutData(fd); // Description Label lblDesc = new Label(filterArea, SWT.LEFT); lblDesc.setText(Messages.CheckstylePropertyPage_lblDescription); fd = new FormData(); fd.left = new FormAttachment(0, 3); fd.top = new FormAttachment(this.mFilterList.getTable(), 3, SWT.BOTTOM); fd.right = new FormAttachment(100, -3); lblDesc.setLayoutData(fd); this.mTxtFilterDescription = new Text(filterArea, SWT.LEFT | SWT.WRAP | SWT.MULTI | SWT.READ_ONLY | SWT.BORDER | SWT.VERTICAL); fd = new FormData(); fd.left = new FormAttachment(0, 3); fd.top = new FormAttachment(lblDesc, 3, SWT.BOTTOM); fd.right = new FormAttachment(100, -3); fd.bottom = new FormAttachment(100, -3); this.mTxtFilterDescription.setLayoutData(fd); // intialize filter list List<IFilter> filterDefs = mProjectConfig.getFilters(); this.mFilterList.setInput(filterDefs); // set the checked state for (int i = 0; i < filterDefs.size(); i++) { IFilter filter = filterDefs.get(i); this.mFilterList.setChecked(filter, filter.isEnabled()); } // set the readonly state for (int i = 0; i < filterDefs.size(); i++) { IFilter filter = filterDefs.get(i); this.mFilterList.setGrayed(filter, filter.isReadonly()); } this.mBtnEditFilter.setEnabled(false); return filterArea; } private Control createLocalConfigArea(Composite parent) { Composite noteAndEditor = new Composite(parent, SWT.NULL); noteAndEditor.setLayout(new GridLayout(1, false)); noteAndEditor.setLayoutData(new GridData(GridData.FILL_BOTH)); Label lblHint = new Label(noteAndEditor, SWT.WRAP); lblHint.setText(Messages.CheckstylePropertyPage_msgLocalConfigs); GridData gd = new GridData(GridData.FILL_HORIZONTAL); gd.widthHint = 200; lblHint.setLayoutData(gd); mWorkingSetEditor = new CheckConfigurationWorkingSetEditor(mProjectConfig.getLocalCheckConfigWorkingSet(), false); Control editorControl = mWorkingSetEditor.createContents(noteAndEditor); editorControl.setLayoutData(new GridData(GridData.FILL_BOTH)); return noteAndEditor; } /** * {@inheritDoc} */ public boolean isValid() { if (mProjectConfig != null) { // check if all check configurations resolve List<FileSet> fileSets = mProjectConfig.getFileSets(); for (FileSet fileset : fileSets) { ICheckConfiguration checkConfig = fileset.getCheckConfig(); if (checkConfig != null) { try { checkConfig.getCheckstyleConfiguration(); } catch (CheckstylePluginException e) { setErrorMessage(NLS.bind(Messages.errorCannotResolveCheckLocation, checkConfig.getLocation(), checkConfig.getName())); return false; } } } } setErrorMessage(null); return true; } /** * @return the result of the ok action * @see org.eclipse.jface.preference.IPreferencePage#performOk() */ public boolean performOk() { try { IProject project = mProjectConfig.getProject(); // save the edited project configuration if (mProjectConfig.isDirty()) { mProjectConfig.store(); } boolean checkstyleEnabled = mChkEnable.getSelection(); boolean needRebuild = mProjectConfig.isRebuildNeeded(); // check if checkstyle nature has to be configured/deconfigured if (checkstyleEnabled != mCheckstyleInitiallyActivated) { ConfigureDeconfigureNatureJob configOperation = new ConfigureDeconfigureNatureJob(project, CheckstyleNature.NATURE_ID); configOperation.setRule(ResourcesPlugin.getWorkspace().getRoot()); configOperation.schedule(); needRebuild = needRebuild || !mCheckstyleInitiallyActivated; } if (checkstyleEnabled && mProjectConfig.isSyncFormatter()) { TransformCheckstyleRulesJob transFormJob = new TransformCheckstyleRulesJob(project); transFormJob.schedule(); } // if a rebuild is advised, check/prompt if the rebuild should // really be done. if (checkstyleEnabled && needRebuild) { String promptRebuildPref = CheckstyleUIPluginPrefs .getString(CheckstyleUIPluginPrefs.PREF_ASK_BEFORE_REBUILD); boolean doRebuild = MessageDialogWithToggle.ALWAYS.equals(promptRebuildPref) && needRebuild; // // Prompt for rebuild // if (MessageDialogWithToggle.PROMPT.equals(promptRebuildPref) && needRebuild) { MessageDialogWithToggle dialog = MessageDialogWithToggle.openYesNoQuestion(getShell(), Messages.CheckstylePropertyPage_titleRebuild, Messages.CheckstylePropertyPage_msgRebuild, Messages.CheckstylePropertyPage_nagRebuild, false, CheckstyleUIPlugin.getDefault().getPreferenceStore(), CheckstyleUIPluginPrefs.PREF_ASK_BEFORE_REBUILD); doRebuild = dialog.getReturnCode() == IDialogConstants.YES_ID; } // check if a rebuild is necessary if (checkstyleEnabled && doRebuild) { BuildProjectJob rebuildOperation = new BuildProjectJob(project, IncrementalProjectBuilder.FULL_BUILD); rebuildOperation.setRule(ResourcesPlugin.getWorkspace().getRoot()); rebuildOperation.schedule(); } } } catch (CheckstylePluginException e) { CheckstyleUIPlugin.errorDialog(getShell(), e, true); } return true; } /** * This class works as controller for the page. It listenes for events to * occur and handles the pages context. * * @author Lars Kdderitzsch */ private class PageController extends SelectionAdapter implements ISelectionChangedListener, ICheckStateListener, IDoubleClickListener { /** * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) */ public void widgetSelected(SelectionEvent e) { Object source = e.getSource(); // edit filter if (source == mBtnEditFilter) { ISelection selection = mFilterList.getSelection(); openFilterEditor(selection); getContainer().updateButtons(); } if (source == mMainTab) { mFileSetsEditor.refresh(); getContainer().updateButtons(); } else if (source == mChkSyncFormatter) { mProjectConfig.setSyncFormatter(mChkSyncFormatter.getSelection()); } else if (source == mChkSimpleConfig) { try { mProjectConfig.setUseSimpleConfig(mChkSimpleConfig.getSelection()); boolean showWarning = CheckstyleUIPluginPrefs .getBoolean(CheckstyleUIPluginPrefs.PREF_FILESET_WARNING); if (mProjectConfig.isUseSimpleConfig() && showWarning) { MessageDialogWithToggle dialog = new MessageDialogWithToggle(getShell(), Messages.CheckstylePropertyPage_titleWarnFilesets, null, Messages.CheckstylePropertyPage_msgWarnFilesets, MessageDialogWithToggle.WARNING, new String[] { IDialogConstants.OK_LABEL }, 0, Messages.CheckstylePropertyPage_mgsWarnFileSetNagOption, showWarning) { /** * Overwritten because we don't want to store which * button the user pressed but the state of the * toggle. * * @see MessageDialogWithToggle#buttonPressed(int) */ protected void buttonPressed(int buttonId) { getPrefStore().setValue(getPrefKey(), getToggleState()); setReturnCode(buttonId); close(); } }; dialog.setPrefStore(CheckstyleUIPlugin.getDefault().getPreferenceStore()); dialog.setPrefKey(CheckstyleUIPluginPrefs.PREF_FILESET_WARNING); dialog.open(); } createFileSetsArea(mFileSetsContainer); mFileSetsContainer.redraw(); mFileSetsContainer.update(); mFileSetsContainer.layout(); } catch (CheckstylePluginException ex) { CheckstyleUIPlugin.errorDialog(getShell(), Messages.errorChangingFilesetEditor, ex, true); } } } /** * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged * (org.eclipse.jface.viewers.SelectionChangedEvent) */ public void selectionChanged(SelectionChangedEvent event) { Object source = event.getSource(); if (source == mFilterList) { ISelection selection = event.getSelection(); if (selection instanceof IStructuredSelection) { Object selectedElement = ((IStructuredSelection) selection).getFirstElement(); if (selectedElement instanceof IFilter) { IFilter filterDef = (IFilter) selectedElement; mTxtFilterDescription.setText(filterDef.getDescription()); // activate edit button mBtnEditFilter.setEnabled(PluginFilterEditors.hasEditor(filterDef)); } } } } /** * @see org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged * (org.eclipse.jface.viewers.CheckStateChangedEvent) */ public void checkStateChanged(CheckStateChangedEvent event) { Object element = event.getElement(); if (element instanceof IFilter) { IFilter filter = (IFilter) element; if (!filter.isReadonly()) { filter.setEnabled(event.getChecked()); } else { event.getCheckable().setChecked(event.getElement(), true); } } } /** * @see org.eclipse.jface.viewers.IDoubleClickListener#doubleClick(org.eclipse.jface.viewers.DoubleClickEvent) */ public void doubleClick(DoubleClickEvent event) { openFilterEditor(event.getSelection()); } /** * Open the filter editor on a given selection of the list. * * @param selection * the selection */ private void openFilterEditor(ISelection selection) { if (selection instanceof IStructuredSelection) { Object selectedElement = ((IStructuredSelection) selection).getFirstElement(); if (selectedElement instanceof IFilter) { try { IFilter aFilterDef = (IFilter) selectedElement; if (!PluginFilterEditors.hasEditor(aFilterDef)) { return; } IFilterEditor editableFilter = PluginFilterEditors.getNewEditor(aFilterDef); editableFilter.setInputProject(mProjectConfig.getProject()); editableFilter.setFilterData(aFilterDef.getFilterData()); if (Window.OK == editableFilter.openEditor(getShell())) { aFilterDef.setFilterData(editableFilter.getFilterData()); mFilterList.refresh(); } } catch (CheckstylePluginException ex) { CheckstyleUIPlugin.errorDialog(getShell(), ex, true); } } } } } }