/* * Copyright (C) 2012-2016 NS Solutions Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.htmlhifive.tools.jslint.dialog; import java.io.ByteArrayInputStream; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import org.apache.commons.lang.StringUtils; import org.eclipse.core.databinding.DataBindingContext; import org.eclipse.core.databinding.observable.value.IObservableValue; import org.eclipse.core.databinding.observable.value.WritableValue; import org.eclipse.core.databinding.validation.MultiValidator; import org.eclipse.core.databinding.validation.ValidationStatus; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; 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.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.jface.databinding.dialog.TitleAreaDialogSupport; import org.eclipse.jface.databinding.swt.SWTObservables; import org.eclipse.jface.databinding.swt.WidgetProperties; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.dialogs.TitleAreaDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Point; 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.Label; import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import com.htmlhifive.tools.jslint.JSLintPlugin; import com.htmlhifive.tools.jslint.engine.download.DownloadEngineSupport; import com.htmlhifive.tools.jslint.engine.download.DownloadJSHintSupport; import com.htmlhifive.tools.jslint.engine.download.DownloadJSLintSupport; import com.htmlhifive.tools.jslint.engine.download.EngineInfo; import com.htmlhifive.tools.jslint.logger.JSLintPluginLogger; import com.htmlhifive.tools.jslint.logger.JSLintPluginLoggerFactory; import com.htmlhifive.tools.jslint.messages.Messages; /** * エンジンファイル(jslint.js等)をダウンロードするダイアログ. * * @author NS Solutions Corporation * */ public class CreateEngineDialog extends TitleAreaDialog { /** * * ダウンロード実行Runnable. * * @author NS Solutions Corporation * */ private static class DownloadRunnable implements IRunnableWithProgress { /** * エンジンファイル情報. */ private EngineInfo result; /** * ダウンロード支援クラス. */ private DownloadEngineSupport support; /** * コンストラクタ. * * @param support ダウンロード支援クラス. */ public DownloadRunnable(DownloadEngineSupport support) { this.support = support; } /* * (非 Javadoc) * * @see * org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse * .core.runtime.IProgressMonitor) */ @Override public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { try { result = support.getEngineInfo(monitor); } catch (IOException e) { throw new InvocationTargetException(e, e.getMessage()); } catch (SecurityException e) { throw new InvocationTargetException(e, e.getMessage()); } catch (IllegalArgumentException e) { throw new InvocationTargetException(e, e.getMessage()); } catch (NoSuchMethodException e) { throw new InvocationTargetException(e, e.getMessage()); } catch (InstantiationException e) { throw new InvocationTargetException(e, e.getMessage()); } catch (IllegalAccessException e) { throw new InvocationTargetException(e, e.getMessage()); } } /** * ダウンロード結果を取得する. * * @return ダウンロード結果. */ public EngineInfo getResult() { return result; } } /** * ロガー. */ private static JSLintPluginLogger logger = JSLintPluginLoggerFactory.getLogger(CreateEngineDialog.class); /** * 出力先ディレクトリ. */ private Text textOutputDir; /** * 出力先ディレクトリWritableValue. */ private WritableValue wvOutputDir = new WritableValue("", String.class); /** * JSLintラジオボタン. */ private Button btnRadioJSLint; /** * JSLint選択WritableValue. */ private WritableValue wvJslint = new WritableValue(true, Boolean.class); /** * JSHint選択ラジオボタン. */ private Button btnRadioJSHint; /** * JSHint選択WritableValue. */ private WritableValue wvJshint = new WritableValue(false, Boolean.class); /** * 選択プロジェクト. */ private IProject project; /** * エンジンファイルパス. */ private String engineFilePath; /** * ダイアログタイトル. */ private String title; /** * コンストラクタ. * * @param parentShell 親シェル. * @param project 選択プロジェクト. * @param title ダイアログタイトル. */ public CreateEngineDialog(Shell parentShell, IProject project, String title) { super(parentShell); setHelpAvailable(false); setShellStyle(SWT.CLOSE | SWT.RESIZE | SWT.TITLE | SWT.APPLICATION_MODAL); this.project = project; this.title = title; } @Override protected void configureShell(Shell newShell) { super.configureShell(newShell); newShell.setText(title); } /* * (非 Javadoc) * * @see * org.eclipse.jface.dialogs.TitleAreaDialog#createDialogArea(org.eclipse * .swt.widgets.Composite) */ @Override protected Control createDialogArea(Composite parent) { setTitle(Messages.DL0023.getText()); Composite area = (Composite) super.createDialogArea(parent); Composite container = new Composite(area, SWT.NONE); container.setLayout(new GridLayout(1, false)); container.setLayoutData(new GridData(GridData.FILL_BOTH)); Composite baseComposite = new Composite(container, SWT.NONE); GridLayout glBaseComposite = new GridLayout(2, false); baseComposite.setLayout(glBaseComposite); baseComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); Label lblType = new Label(baseComposite, SWT.NONE); lblType.setText(Messages.DL0024.getText()); Composite compositeSelectionType = new Composite(baseComposite, SWT.NONE); compositeSelectionType.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); GridLayout glCompositeSelectionType = new GridLayout(2, false); glCompositeSelectionType.horizontalSpacing = 20; compositeSelectionType.setLayout(glCompositeSelectionType); btnRadioJSLint = new Button(compositeSelectionType, SWT.RADIO); btnRadioJSLint.setText(Messages.DL0025.getText()); btnRadioJSHint = new Button(compositeSelectionType, SWT.RADIO); btnRadioJSHint.setText(Messages.DL0026.getText()); Label labelOutputDir = new Label(baseComposite, SWT.NONE); labelOutputDir.setBounds(0, 0, 61, 18); labelOutputDir.setText(Messages.DL0020.getText()); Composite compositeOutputDir = new Composite(baseComposite, SWT.NONE); compositeOutputDir.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); compositeOutputDir.setLayout(new GridLayout(2, false)); textOutputDir = new Text(compositeOutputDir, SWT.BORDER); textOutputDir.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); Button btnSelectionOutputDir = new Button(compositeOutputDir, SWT.NONE); GridData gdBtnSelectionOutputDir = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1); gdBtnSelectionOutputDir.widthHint = 60; btnSelectionOutputDir.setLayoutData(gdBtnSelectionOutputDir); btnSelectionOutputDir.setText(Messages.B0001.getText()); btnSelectionOutputDir.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { FolderSelectionDialog dialog = new FolderSelectionDialog(getShell(), Messages.DT0008.getText(), Messages.DL0022.getText()); dialog.setInitialSelection(project); if (dialog.open() != Window.OK) { return; } IContainer outputDir = (IContainer) dialog.getFirstResult(); textOutputDir.setText(outputDir.getFullPath().toString()); } }); return area; } /* * (非 Javadoc) * * @see * org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse * .swt.widgets.Composite) */ @Override protected void createButtonsForButtonBar(Composite parent) { createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); initialDataBinding(); setMessage(Messages.DL0027.getText(), IMessageProvider.INFORMATION); } /** * データバインド初期化. */ private void initialDataBinding() { DataBindingContext context = new DataBindingContext(); // Validator MultiValidator validator = new MultiValidator() { @Override protected IStatus validate() { StringBuilder sb = new StringBuilder(); if ((Boolean) wvJshint.getValue() && (Boolean) wvJslint.getValue()) { sb.append(Messages.EM0014.getText()); } String outputPath = (String) wvOutputDir.getValue(); if (StringUtils.isEmpty(outputPath)) { sb.append(Messages.EM0009.format(Messages.DL0020.getText())); } else { IPath path = new Path(outputPath); if (!ResourcesPlugin.getWorkspace().getRoot().exists(path)) { sb.append(Messages.EM0000.format(Messages.DL0020.getText())); } } if (StringUtils.isEmpty(sb.toString())) { getButton(IDialogConstants.OK_ID).setEnabled(true); return ValidationStatus.info(Messages.DL0027.getText()); } if (getButton(IDialogConstants.OK_ID) != null) { getButton(IDialogConstants.OK_ID).setEnabled(false); } return ValidationStatus.error(sb.toString()); } }; // 出力先ディレクトリのバインド IObservableValue obsOutputDirText = SWTObservables.observeText(textOutputDir, SWT.Modify); context.bindValue(obsOutputDirText, wvOutputDir, null, null); // JSLint選択のバインド IObservableValue obsSelectJslint = WidgetProperties.selection().observe(btnRadioJSLint); context.bindValue(obsSelectJslint, wvJslint, null, null); // JSHint選択のバインド IObservableValue obsSelectJsHint = WidgetProperties.selection().observe(btnRadioJSHint); context.bindValue(obsSelectJsHint, wvJshint); // バリデータのセッティング context.addValidationStatusProvider(validator); TitleAreaDialogSupport.create(this, context); } /* * (非 Javadoc) * * @see org.eclipse.jface.dialogs.TitleAreaDialog#getInitialSize() */ @Override protected Point getInitialSize() { return new Point(653, 375); } @Override protected void okPressed() { ProgressMonitorDialog progressDialog = new ProgressMonitorDialog(getShell()); DownloadEngineSupport support = createEngineDownload((Boolean) wvJslint.getValue()); try { IFile file = ResourcesPlugin.getWorkspace().getRoot() .getFile(new Path(wvOutputDir.getValue() + "/" + support.getEngine().getFileName())); if (file.exists()) { MessageBox box = new MessageBox(getShell(), SWT.OK | SWT.CANCEL | SWT.ICON_QUESTION); box.setMessage(Messages.DM0004.getText()); box.setText(Messages.DT0011.getText()); if (box.open() == SWT.CANCEL) { return; } } DownloadRunnable progress = new DownloadRunnable(support); progressDialog.run(true, false, progress); EngineInfo info = progress.getResult(); if (info == null) { ErrorDialog.openError(getShell(), Messages.DT0003.getText(), Messages.EM0015.getText(), ValidationStatus.error(Messages.EM0015.getText())); return; } ConfirmLicenseDialog dialog = new ConfirmLicenseDialog(getShell(), StringUtils.trim(info.getLicenseStr()), Messages.DT0009.getText()); if (dialog.open() == IDialogConstants.OK_ID) { if (file.exists()) { file.setContents(new ByteArrayInputStream(info.getMainSource().getBytes()), IResource.FORCE, null); } else { file.create(new ByteArrayInputStream(info.getMainSource().getBytes()), true, null); } this.engineFilePath = file.getFullPath().toString(); } else { return; } } catch (InvocationTargetException e) { ErrorDialog.openError(getShell(), Messages.DT0003.getText(), Messages.EM0015.getText(), new Status(IStatus.ERROR, JSLintPlugin.PLUGIN_ID, e.getMessage(), e)); logger.put(Messages.EM0100, e); } catch (InterruptedException e) { // キャンセル無視しているので来ない. throw new AssertionError(); } catch (CoreException e) { ErrorDialog.openError(getShell(), Messages.DT0003.getText(), Messages.EM0016.getText(), e.getStatus()); logger.put(Messages.EM0100, e); } super.okPressed(); } /** * Download支援クラスを取得する. * * @See {@link DownloadJSHintSupport} * @See {@link DownloadJSLintSupport} * * @param isJslint JSLintかどうか. * @return Download支援クラス. */ private DownloadEngineSupport createEngineDownload(boolean isJslint) { if (isJslint) { return new DownloadJSLintSupport(); } return new DownloadJSHintSupport(); } /** * ダウンロードしファイル生成後のエンジンファイルのパス. * * @return エンジンファイルのパス. */ public String getEngineFilePath() { return engineFilePath; } }