/** * @version $Id: DataBaseUserDicImportWizardPage.java 1839 2014-04-16 02:33:51Z yukihiro-kinjyo $ * * 2011/10/05 10:08:26 * @author kenta-uechi * * Copyright 2011-2014 TIDAコンソーシアム All Rights Reserved. */ package com.tida_okinawa.corona.ui.wizards; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; 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.core.runtime.jobs.Job; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.ViewerSorter; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Table; import org.eclipse.ui.dialogs.WizardNewFileCreationPage; import com.tida_okinawa.corona.internal.ui.component.CompositeUtil; import com.tida_okinawa.corona.internal.ui.util.DictionaryPriorityUtil; import com.tida_okinawa.corona.internal.ui.views.model.IUIContainer; import com.tida_okinawa.corona.internal.ui.views.model.IUIDictionary; import com.tida_okinawa.corona.internal.ui.views.model.IUIElement; import com.tida_okinawa.corona.internal.ui.views.model.IUILibFolder; import com.tida_okinawa.corona.internal.ui.views.model.IUILibrary; import com.tida_okinawa.corona.internal.ui.views.model.IUIProduct; import com.tida_okinawa.corona.internal.ui.views.model.impl.CoronaModel; import com.tida_okinawa.corona.io.IoActivator; import com.tida_okinawa.corona.io.model.ICoronaDics; import com.tida_okinawa.corona.io.model.dic.DicType; import com.tida_okinawa.corona.io.model.dic.ICoronaDic; import com.tida_okinawa.corona.io.model.dic.IDicItem; import com.tida_okinawa.corona.io.model.dic.IPattern; import com.tida_okinawa.corona.io.model.dic.IPatternDic; import com.tida_okinawa.corona.ui.UIActivator; import com.tida_okinawa.corona.ui.views.CoronaDicComparator; import com.tida_okinawa.corona.ui.views.CoronaElementLabelProvider; /** * @author kenta-uechi */ public class DataBaseUserDicImportWizardPage extends WizardNewFileCreationPage { /** * @param pageName * @param selection */ public DataBaseUserDicImportWizardPage(String pageName, IStructuredSelection selection) { super(pageName, toContainer(selection)); setDescription(Messages.DataBaseUserDicImportWizardPage_labelDicImportFromDB); } private static IStructuredSelection toContainer(IStructuredSelection selection) { Object item = selection.getFirstElement(); if (item instanceof IUIElement) { item = ((IUIElement) item).getResource(); } if (item instanceof IFile) { item = ((IFile) item).getParent(); } else if (item instanceof IContainer) { // nothing to do } else { item = null; } if (item == null) { return new StructuredSelection(); } return new StructuredSelection(item); } private boolean isUiCreated; @Override protected void createAdvancedControls(Composite parent) { createFieldList(parent); isUiCreated = true; updateImportDicList(); if (dicListViewer.getTable().getItemCount() > 0) { setFileName(((ICoronaDic) dicListViewer.getTable().getItem(0).getData()).getName()); dicListViewer.getTable().select(0); } setPageComplete(validatePage()); setErrorMessage(null); } TableViewer dicListViewer; private void createFieldList(Composite parent) { Composite composite = CompositeUtil.defaultComposite(parent, 1); GridData gd = (GridData) composite.getLayoutData(); gd.heightHint = 200; CompositeUtil.createLabel(composite, Messages.DataBaseUserDicImportWizardPage_labelDics, -1).pack(); dicListViewer = new TableViewer(composite, SWT.FULL_SELECTION | SWT.MULTI | SWT.BORDER); dicListViewer.setContentProvider(new ArrayContentProvider()); dicListViewer.setLabelProvider(new CoronaElementLabelProvider()); dicListViewer.addSelectionChangedListener(tableItemSelectionChangedListener); dicListViewer.setSorter(new ViewerSorter() { CoronaDicComparator comparator = new CoronaDicComparator(); @Override public int category(Object element) { return comparator.category(element); } }); Table t = dicListViewer.getTable(); t.setLayout(new GridLayout()); t.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); } /* **************************************** * 選択された辞書の取得とインポート */ private Set<IUIDictionary> importedDics = new HashSet<IUIDictionary>(); /** * 選択した辞書を返却 * * @return * 辞書リスト */ public Collection<IUIDictionary> getImportedDics() { return importedDics; } /** * @deprecated use {@link #importDics()} */ @Deprecated @Override public IFile createNewFile() { return null; } /** * 辞書のインポート処理 */ public void importDics() { final Object[] importDics = ((IStructuredSelection) dicListViewer.getSelection()).toArray(); final IContainer destDir = getSelectedContainer(); importedDics.clear(); Job importJob = new Job(Messages.DataBaseUserDicImportWizardPage_jobImportFromDB) { @Override protected IStatus run(IProgressMonitor monitor) { CoronaModel model = CoronaModel.INSTANCE; IUIElement targetLibrary = null; if (model.adapter(destDir, false) instanceof IUILibFolder) { targetLibrary = ((IUILibFolder) model.adapter(destDir, false)).getParent(); } if (targetLibrary != null) { /* ターゲット下に作るならば、他の同ターゲットの下にも作る */ IUIElement[] uiElements; if (targetLibrary instanceof IUIProduct) { uiElements = model.adapter(targetLibrary.getObject()).toArray(new IUIElement[model.adapter(targetLibrary.getObject()).size()]); } else { uiElements = new IUIElement[] { targetLibrary }; } monitor.beginTask(Messages.DataBaseUserDicImportWizardPage_monitorImportFromDB, (uiElements.length * importDics.length) + 1); monitor.subTask(Messages.DataBaseUserDicImportWizardPage_monitorPrepare); /* 同時にインポートする親辞書を特定するためのマップを作成 */ Map<Integer, ICoronaDic> allDics = new HashMap<Integer, ICoronaDic>(); for (ICoronaDic dic : IoActivator.getService().getDictionarys(ICoronaDic.class)) { allDics.put(dic.getId(), dic); } IPath libFolderName = new Path(destDir.getName()); /* ファイル作成時の並びを整えるためにSortする */ Set<ICoronaDic> importingDics = new TreeSet<ICoronaDic>(new CoronaDicComparator()); for (Object o : importDics) { ICoronaDic importDic = (ICoronaDic) o; importingDics.add(importDic); /* パターン辞書の場合は参照関係を確認する */ if (importDic instanceof IPatternDic) { checkParentLink(importingDics, importDic); } /* 親辞書を特定する */ for (int parentId : importDic.getParentIds()) { if (parentId != ICoronaDic.UNSAVED_ID) { ICoronaDic parentDic = allDics.get(parentId); if (parentDic != null) { importingDics.add(parentDic); } } } } monitor.worked(1); if (monitor.isCanceled()) { monitor.done(); return Status.OK_STATUS; } /* * 選択された辞書をインポートする * 同じターゲットの下の辞書はまとめてインポートしないといけないので、辞書ごとにループを回す */ for (ICoronaDic importDic : importingDics) { monitor.subTask(importDic.getName()); for (IUIElement uiElement : uiElements) { IUILibrary uiLib = (IUILibrary) uiElement; IResource key = uiLib.getResource().getFolder(libFolderName); IUIContainer uiParent = (IUIContainer) CoronaModel.INSTANCE.adapter(key, true); ICoronaDics dics = uiLib.getObject(); dics.addDictionary(importDic); IUIDictionary uiDic = createUIDic(uiParent, importDic); DictionaryPriorityUtil.addDicPriority(uiDic); monitor.worked(1); } if (monitor.isCanceled()) { break; } } if (getImportedDics().size() > 0) { monitor.done(); } } monitor.done(); return Status.OK_STATUS; } public void checkParentLink(Set<ICoronaDic> importingDics, ICoronaDic importDic) { /* 部品パターンを共有してる辞書も同時インポートする */ List<IDicItem> items = importDic.getItems(); /* パターン辞書のXML要素を抽出 */ StringBuilder xmlString = new StringBuilder(); for (IDicItem item : items) { xmlString.append(((IPattern) item).getText()); } /* XML要素からLINKIDを抽出 */ Pattern linkReg = Pattern.compile("<LINK ID=\""); //$NON-NLS-1$ Matcher match = linkReg.matcher(xmlString); HashSet<Integer> linkItems = new HashSet<Integer>(); while (match.find()) { int idLength = xmlString.substring(match.end()).indexOf("\""); //$NON-NLS-1$ String linkid = xmlString.substring(match.end(), match.end() + idLength); linkItems.add(Integer.parseInt(linkid)); } /* 自辞書以外を参照している場合、参照先の辞書をインポート対象へ追加 */ for (Integer link : linkItems) { int dicId = 0; try { dicId = IoActivator.getDicUtil().getItem(link, DicType.PATTERN).getComprehensionDicId(); } catch (NullPointerException e) { e.printStackTrace(); dicId = importDic.getId(); } if (importDic.getId() != dicId) { ICoronaDic addDic = IoActivator.getService().getDictionary(dicId); if (!importingDics.contains(addDic)) { importingDics.add(addDic); /* 再起呼び出しにより多重リンクに対応 */ checkParentLink(importingDics, addDic); } } } } }; importJob.setUser(true); importJob.schedule(); } IUIDictionary createUIDic(IUIContainer uiParent, ICoronaDic dic) { IFile newParentIFile = uiParent.getResource().getFile(new Path(dic.getName())); IUIDictionary uiDic = (IUIDictionary) CoronaModel.INSTANCE.create(uiParent, dic, newParentIFile); uiDic.update(null); importedDics.add(uiDic); return uiDic; } /* **************************************** */ @Override public void handleEvent(Event event) { super.handleEvent(event); updateImportDicList(); setPageComplete(validatePage()); } protected IContainer getSelectedContainer() { IPath path = getContainerFullPath(); if (path != null) { return createFileHandle(path.append(Messages.DataBaseUserDicImportWizardPage_dummy)).getParent(); } return null; } private List<ICoronaDic> listDics = new ArrayList<ICoronaDic>(); private IUIContainer oldSelectedContainer; private void updateImportDicList() { if (!isUiCreated) { return; } /* * 表示用の辞書一覧作成 */ /* 表示する辞書リストの初期化 */ listDics.clear(); listDics.addAll(IoActivator.getService().getDictionarys(ICoronaDic.class)); /* 現在選択されているフォルダを取得 */ IUIContainer uiContainer = (IUIContainer) CoronaModel.INSTANCE.adapter(getSelectedContainer(), false); if ((uiContainer != null) && !uiContainer.equals(oldSelectedContainer)) { if (uiContainer instanceof IUILibFolder) { IUILibrary uiLib = ((IUILibFolder) uiContainer).getParent(); if (uiLib != null) { /* 選択されているフォルダの辞書を除去 */ ICoronaDics lib = uiLib.getObject(); if (lib != null) { listDics.removeAll(lib.getDictionarys(ICoronaDic.class)); } /* 辞書一覧の表示 */ dicListViewer.setInput(listDics); } } } oldSelectedContainer = uiContainer; } /* **************************************** * Listeners */ private final ISelectionChangedListener tableItemSelectionChangedListener = new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { IStructuredSelection selection = (IStructuredSelection) dicListViewer.getSelection(); if (selection.size() > 0) { /* 選択された辞書名を取得 */ StringBuilder setName = new StringBuilder(128); for (Iterator<?> itr = selection.iterator(); itr.hasNext();) { Object item = itr.next(); setName.append(", ").append(((ICoronaDic) item).getName()); //$NON-NLS-1$ } /* 選択された辞書の名前をファイル名にセット */ if (!getFileName().equals(setName.substring(2))) { setFileName(setName.substring(2)); } } else { /* 入力したファイル名は消さない */ // setFileName(""); } setPageComplete(validatePage()); } }; /* **************************************** * ページチェック */ @Override protected boolean validatePage() { if (!super.validatePage()) { return false; } IContainer selectedContainer = getSelectedContainer(); if (selectedContainer == null) { setErrorMessage(Messages.DataBaseUserDicImportWizardPage_errSelParentFolder); } if (!selectedContainer.exists()) { setErrorMessage(Messages.DataBaseUserDicImportWizardPage_errNonExistParentFolder); return false; } if (!NewDictionaryCreationPage.isLibrary(getSelectedContainer())) { setErrorMessage(Messages.DataBaseUserDicImportWizardPage_errSelDicFolder); return false; } /* * 入力されたファイル名の辞書をリストから選択する * 間違えているファイル名は無視して、あってる奴だけリストから選択する。 * 間違えているのか入力中なのか判断つかないから。 */ String[] fileNames = getFileName().split(Messages.DataBaseUserDicImportWizardPage_10, -1); Collection<Object> select = new ArrayList<Object>(fileNames.length); for (ICoronaDic dic : listDics) { for (String fileName : fileNames) { if (dic.getName().equals(fileName.trim())) { select.add(dic); break; } } } if (select.size() == 0) { setErrorMessage(Messages.DataBaseUserDicImportWizardPage_errNonDics); return false; } /* 無限ループするので、いったん外す */ dicListViewer.removeSelectionChangedListener(tableItemSelectionChangedListener); dicListViewer.setSelection(new StructuredSelection(select.toArray())); dicListViewer.addSelectionChangedListener(tableItemSelectionChangedListener); setErrorMessage(null); return true; } @Override protected IStatus validateLinkedResource() { return new Status(IStatus.OK, UIActivator.PLUGIN_ID, IStatus.OK, "", null); //$NON-NLS-1$ } @Override protected void createLinkTarget() { } }