/******************************************************************************* * Copyright (c) 2013 hangum. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Lesser Public License v2.1 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * * Contributors: * hangum - initial API and implementation ******************************************************************************/ package com.hangum.tadpole.mongodb.core.composite.result; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.IJobChangeEvent; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.JobChangeAdapter; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.TreeViewerColumn; import org.eclipse.rap.rwt.RWT; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CTabFolder; import org.eclipse.swt.custom.CTabItem; import org.eclipse.swt.custom.SashForm; 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.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.Label; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Tree; import com.hangum.tadpole.ace.editor.core.widgets.TadpoleEditorWidget; import com.hangum.tadpole.commons.dialogs.message.dao.TadpoleMessageDAO; import com.hangum.tadpole.commons.exception.dialog.ExceptionDetailsErrorDialog; import com.hangum.tadpole.commons.libs.core.define.PublicTadpoleDefine; import com.hangum.tadpole.commons.libs.core.message.CommonMessages; import com.hangum.tadpole.commons.util.JSONUtil; import com.hangum.tadpole.commons.util.TadpoleWidgetUtils; import com.hangum.tadpole.commons.util.download.DownloadServiceHandler; import com.hangum.tadpole.commons.util.download.DownloadUtils; import com.hangum.tadpole.engine.query.dao.system.UserDBDAO; import com.hangum.tadpole.engine.sql.util.tables.DefaultViewerSorter; import com.hangum.tadpole.engine.sql.util.tables.SQLHistoryLabelProvider; import com.hangum.tadpole.engine.sql.util.tables.SQLHistorySorter; import com.hangum.tadpole.engine.sql.util.tables.SQLResultContentProvider; import com.hangum.tadpole.engine.sql.util.tables.SQLResultFilter; import com.hangum.tadpole.engine.sql.util.tables.SQLResultLabelProvider; import com.hangum.tadpole.engine.sql.util.tables.SQLResultSorter; import com.hangum.tadpole.engine.sql.util.tables.TableUtil; import com.hangum.tadpole.engine.sql.util.tables.TreeUtil; import com.hangum.tadpole.engine.utils.EditorDefine; import com.hangum.tadpole.mongodb.core.Activator; import com.hangum.tadpole.mongodb.core.Messages; import com.hangum.tadpole.mongodb.core.define.MongoDBDefine; import com.hangum.tadpole.mongodb.core.dialogs.collection.NewDocumentDialog; import com.hangum.tadpole.mongodb.core.dialogs.collection.index.NewIndexDialog; import com.hangum.tadpole.mongodb.core.dialogs.msg.TadpoleMessageDialog; import com.hangum.tadpole.mongodb.core.dialogs.msg.TadpoleSimpleMessageDialog; import com.hangum.tadpole.mongodb.core.dialogs.resultview.FindOneDetailDialog; import com.hangum.tadpole.mongodb.core.dto.MongodbTreeViewDTO; import com.hangum.tadpole.mongodb.core.query.MongoDBQuery; import com.hangum.tadpole.mongodb.core.utils.MongoDBTableColumn; import com.hangum.tadpole.preference.define.PreferenceDefine; import com.hangum.tadpole.preference.get.GetPreferenceGeneral; import com.mongodb.BasicDBList; import com.mongodb.BasicDBObject; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBCursor; import com.mongodb.DBObject; import com.mongodb.util.JSON; /** * 몽고 디비 결과셋을 출력하는 콤포짖 * * @author hangum * */ public class MongodbResultComposite extends Composite { private static Logger logger = Logger.getLogger(MongodbResultComposite.class); /** 결과 텝창의 정보를 상수로정의 */ private static final int TAB_POSITION_TREE_VIEW = 0; private static final int TAB_POSITION_TABLE_VIEW = 1; private static final int TAB_POSITION_JSON_VIEW = 2; private static final int TAB_POSITION_MESSAGE_VIEW = 3; /** preference default max count */ private int defaultMaxCount = GetPreferenceGeneral.getMongoDefaultMaxCount(); /** preference default result page */ private String defaultResultPage = GetPreferenceGeneral.getMongoDefaultResultPage(); /** data userdb*/ private UserDBDAO userDB; /** collection name */ private String collectionName; /** 사용자가 action을 할수 있는지 */ private boolean isUserAction; /** 기본 검색 조건 */ String strBasicField = ""; //$NON-NLS-1$ String strBasicFind = ""; //$NON-NLS-1$ String strBasicSort = ""; //$NON-NLS-1$ int cntSkip = 0; int cntLimit = 0; /** error console 내용 */ private StringBuffer sbConsoleErrorMsg = new StringBuffer(); /** execute plan console */ private StringBuffer sbConsoleExecuteMsg = new StringBuffer(); /** result tab folder */ private CTabFolder tabFolderMongoDB; /** tree viewer */ private TreeViewer treeViewerMongo; private Label lblTreeViewCount; private Text textFilter; /** collection 결과 */ private TableViewer resultTableViewer; private Label lblTableViewCount; private SashForm sashFormCollectionResult; private SQLResultFilter sqlFilter = new SQLResultFilter(); private SQLResultSorter sqlSorter; private Table tableTadpoleMsg; private TableViewer tableViewerMessage; private List<TadpoleMessageDAO> listMessage = new ArrayList<TadpoleMessageDAO>(); /** browser */ private Composite compositeExternal; /** download servcie handler. */ private DownloadServiceHandler downloadServiceHandler; /** query 의 결과 데이터 -- table의 데이터를 표시하는 용도 <column index, Data> */ private List<Map<Integer, Object>> sourceDataList = new ArrayList<Map<Integer, Object>>(); private Map<Integer, String> mapColumns = new HashMap<Integer, String>(); private List<MongodbTreeViewDTO> listTrees; /** label count string */ private String txtCnt = ""; //$NON-NLS-1$ /** tadpole editor widget */ private TadpoleEditorWidget tadpoleEditor; /** * * @param parent * @param style * @param userDB * @param collectionName */ public MongodbResultComposite(Composite parent, int style, final UserDBDAO userDB, final String collectionName, final boolean isUserAction) { super(parent, style); GridLayout gridLayout = new GridLayout(1, false); gridLayout.verticalSpacing = 1; gridLayout.horizontalSpacing = 1; gridLayout.marginHeight = 1; gridLayout.marginWidth = 1; setLayout(gridLayout); this.userDB = userDB; this.collectionName = collectionName; this.isUserAction = isUserAction; Composite compositeResult = new Composite(this, SWT.NONE); compositeResult.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); GridLayout gl_compositeResult = new GridLayout(1, false); gl_compositeResult.verticalSpacing = 1; gl_compositeResult.horizontalSpacing = 1; gl_compositeResult.marginHeight = 1; gl_compositeResult.marginWidth = 1; compositeResult.setLayout(gl_compositeResult); tabFolderMongoDB = new CTabFolder(compositeResult, SWT.NONE); tabFolderMongoDB.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { if(treeViewerMongo == null) return; selectData(); } }); tabFolderMongoDB.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); tabFolderMongoDB.setSelectionBackground(TadpoleWidgetUtils.getTabFolderBackgroundColor(), TadpoleWidgetUtils.getTabFolderPercents()); CTabItem tbtmTreeView = new CTabItem(tabFolderMongoDB, SWT.NONE); tbtmTreeView.setText(Messages.get().MongodbResultComposite_3); Composite compositeTreeView = new Composite(tabFolderMongoDB, SWT.NONE); tbtmTreeView.setControl(compositeTreeView); GridLayout gl_compositeTreeView = new GridLayout(1, false); gl_compositeTreeView.verticalSpacing = 2; gl_compositeTreeView.horizontalSpacing = 2; gl_compositeTreeView.marginHeight = 2; gl_compositeTreeView.marginWidth = 2; compositeTreeView.setLayout(gl_compositeTreeView); treeViewerMongo = new TreeViewer(compositeTreeView, SWT.BORDER /* | SWT.VIRTUAL */ | SWT.FULL_SELECTION); treeViewerMongo.addDoubleClickListener(new IDoubleClickListener() { public void doubleClick(DoubleClickEvent event) { IStructuredSelection iss = (IStructuredSelection)treeViewerMongo.getSelection(); if(!iss.isEmpty()) { MongodbTreeViewDTO rsResult = (MongodbTreeViewDTO)iss.getFirstElement(); String strKey = rsResult.getKey(); TadpoleSimpleMessageDialog dlg = new TadpoleSimpleMessageDialog(Display.getCurrent().getActiveShell(), collectionName + " [ " + strKey + " ]", JSONUtil.getPretty(rsResult.getDbObject().toString())); //$NON-NLS-1$ //$NON-NLS-2$ dlg.open(); } } }); Tree tree = treeViewerMongo.getTree(); tree.setHeaderVisible(true); tree.setLinesVisible(true); tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); createTreeColumn(); treeViewerMongo.setContentProvider(new TreeMongoContentProvider() ); treeViewerMongo.setLabelProvider(new TreeMongoLabelProvider()); Composite compositeTreeViewTail = new Composite(compositeTreeView, SWT.NONE); compositeTreeViewTail.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); compositeTreeViewTail.setLayout(new GridLayout(6, false)); if(isUserAction) { Button btnTreeInsertDocument = new Button(compositeTreeViewTail, SWT.NONE); btnTreeInsertDocument.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { newDocument(); } }); btnTreeInsertDocument.setText(Messages.get().MongodbResultComposite_4); Button btnTreeDeleteDocument = new Button(compositeTreeViewTail, SWT.NONE); btnTreeDeleteDocument.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { deleteDocumentTree(); } }); btnTreeDeleteDocument.setText(Messages.get().MongodbResultComposite_5); Button btnTreeCreateIndex = new Button(compositeTreeViewTail, SWT.NONE); btnTreeCreateIndex.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { createIndex(); } }); btnTreeCreateIndex.setText(Messages.get().MongodbResultComposite_6); Label labelTreeViewDumy = new Label(compositeTreeViewTail, SWT.NONE); labelTreeViewDumy.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); } lblTreeViewCount = new Label(compositeTreeViewTail, SWT.NONE); lblTreeViewCount.setText(Messages.get().MongodbResultComposite_7); CTabItem tbtmTableView = new CTabItem(tabFolderMongoDB, SWT.NONE); tbtmTableView.setText(Messages.get().MongodbResultComposite_8); sashFormCollectionResult = new SashForm(tabFolderMongoDB, SWT.VERTICAL); tbtmTableView.setControl(sashFormCollectionResult); Composite compositeBodyTable = new Composite(sashFormCollectionResult, SWT.VERTICAL); GridLayout gl_compositeBodyTable = new GridLayout(2, false); gl_compositeBodyTable.marginWidth = 2; gl_compositeBodyTable.marginHeight = 2; gl_compositeBodyTable.verticalSpacing = 2; gl_compositeBodyTable.horizontalSpacing = 2; compositeBodyTable.setLayout(gl_compositeBodyTable); Label lblFilter = new Label(compositeBodyTable, SWT.NONE); lblFilter.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); lblFilter.setText(CommonMessages.get().Filter); textFilter = new Text(compositeBodyTable, SWT.SEARCH | SWT.ICON_SEARCH | SWT.ICON_CANCEL); textFilter.addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { if(e.keyCode == SWT.Selection) setFilter(); } }); textFilter.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); resultTableViewer = new TableViewer(compositeBodyTable, SWT.BORDER /* | SWT.VIRTUAL */ | SWT.FULL_SELECTION); resultTableViewer.addDoubleClickListener(new IDoubleClickListener() { public void doubleClick(DoubleClickEvent event) { IStructuredSelection iss = (IStructuredSelection)resultTableViewer.getSelection(); if(!iss.isEmpty()) { HashMap<Integer, Object> rsResult = (HashMap<Integer, Object>)iss.getFirstElement(); // String jsonString = rsResult.get(MongoDBDefine.PRIMARY_ID_KEY).toString(); DBObject dbObject = (DBObject)rsResult.get(MongoDBDefine.PRIMARY_ID_KEY); FindOneDetailDialog dlg = new FindOneDetailDialog(null, userDB, collectionName, dbObject); dlg.open(); } } }); Table table = resultTableViewer.getTable(); table.setHeaderVisible(true); table.setLinesVisible(true); table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); sqlFilter.setTable(table); Composite compositeTail = new Composite(compositeBodyTable, SWT.NONE); compositeTail.setLayout(new GridLayout(10, false)); compositeTail.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); if(isUserAction) { Button btnInsertDocument = new Button(compositeTail, SWT.NONE); btnInsertDocument.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { newDocument(); } }); btnInsertDocument.setText(Messages.get().MongodbResultComposite_13); Button btnDeleteDocument = new Button(compositeTail, SWT.NONE); btnDeleteDocument.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { deleteDocumentTable(); } }); btnDeleteDocument.setText(Messages.get().MongodbResultComposite_14); Button btnCreateIndex = new Button(compositeTail, SWT.NONE); btnCreateIndex.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { createIndex(); } }); btnCreateIndex.setText(Messages.get().MongodbResultComposite_15); Label labelTableDumy = new Label(compositeTail, SWT.NONE); GridData gd_labelTableDumy = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1); gd_labelTableDumy.widthHint = 5; labelTableDumy.setLayoutData(gd_labelTableDumy); } Button btnExportCSV = new Button(compositeTail, SWT.NONE); btnExportCSV.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { StringBuffer sbExportDataBody = new StringBuffer(); // fixed : https://github.com/hangum/TadpoleForDBTools/issues/284 // column 헤더추가. String tmpStrHead = ""; TableColumn[] tcs = resultTableViewer.getTable().getColumns(); for (TableColumn tableColumn : tcs) { tmpStrHead += tableColumn.getText() + ", "; //$NON-NLS-1$ } tmpStrHead = StringUtils.removeEnd(tmpStrHead, ", "); tmpStrHead += PublicTadpoleDefine.LINE_SEPARATOR; //$NON-NLS-1$ // column 데이터 추가. for(int i=0; i<sourceDataList.size(); i++) { String tmpData = ""; Map<Integer, Object> mapColumns = sourceDataList.get(i); for(int j=0; j<tcs.length; j++) { tmpData += mapColumns.get(j) + ", "; //$NON-NLS-1$ } tmpData = StringUtils.removeEnd(tmpData, ", "); tmpData += PublicTadpoleDefine.LINE_SEPARATOR; sbExportDataBody.append(tmpData); //$NON-NLS-1$ } downloadServiceHandler.setName(userDB.getDisplay_name() + "_ResultSetExport.csv"); //$NON-NLS-1$ downloadServiceHandler.setByteContent((tmpStrHead + sbExportDataBody.toString()).getBytes()); DownloadUtils.provideDownload(compositeExternal, downloadServiceHandler.getId()); } }); btnExportCSV.setText(Messages.get().MongodbResultComposite_16); compositeExternal = new Composite(compositeTail, SWT.NONE); compositeExternal.setLayout(new GridLayout(1, false)); compositeExternal.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1)); Label lblNewLabel_1 = new Label(compositeTail, SWT.NONE); lblNewLabel_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); lblTableViewCount = new Label(compositeTail, SWT.NONE); // JSON View CTabItem tbtmJSONView = new CTabItem(tabFolderMongoDB, SWT.NONE); tbtmJSONView.setText("JSON View"); Composite compositeJSONView = new Composite(tabFolderMongoDB, SWT.NONE); tbtmJSONView.setControl(compositeJSONView); compositeJSONView.setLayout(new GridLayout(1, false)); tadpoleEditor = new TadpoleEditorWidget(compositeJSONView, SWT.BORDER, EditorDefine.EXT_JSON, "", ""); tadpoleEditor.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); // tabpole message CTabItem tbtmTadpoleMessage = new CTabItem(tabFolderMongoDB, SWT.NONE); tbtmTadpoleMessage.setText(Messages.get().MongodbResultComposite_17); Composite compositeTadpoleMsg = new Composite(tabFolderMongoDB, SWT.NONE); tbtmTadpoleMessage.setControl(compositeTadpoleMsg); compositeTadpoleMsg.setLayout(new GridLayout(1, false)); tableViewerMessage = new TableViewer(compositeTadpoleMsg, SWT.BORDER | SWT.FULL_SELECTION); tableViewerMessage.addDoubleClickListener(new IDoubleClickListener() { public void doubleClick(DoubleClickEvent event) { IStructuredSelection is = (IStructuredSelection)event.getSelection(); Object selElement = is.getFirstElement(); if(selElement instanceof TadpoleMessageDAO) { TadpoleMessageDAO tmd = (TadpoleMessageDAO)selElement; TadpoleMessageDialog dlg = new TadpoleMessageDialog(null, "Message", SQLHistoryLabelProvider.dateToStr(tmd.getDateExecute()), tmd.getStrMessage() ); //$NON-NLS-1$ dlg.open(); } } }); tableTadpoleMsg = tableViewerMessage.getTable(); tableTadpoleMsg.setHeaderVisible(true); tableTadpoleMsg.setLinesVisible(true); tableTadpoleMsg.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); tableTadpoleMsg.setSortDirection(SWT.DOWN); SQLHistorySorter sorterMessage = new SQLHistorySorter(); TableViewerColumn tableViewerColumn = new TableViewerColumn(tableViewerMessage, SWT.NONE); TableColumn tblclmnDate = tableViewerColumn.getColumn(); tblclmnDate.setWidth(140); tblclmnDate.setText(CommonMessages.get().Date); tblclmnDate.addSelectionListener(getSelectionAdapter(tableViewerMessage, sorterMessage, tblclmnDate, 0)); TableViewerColumn tableViewerColumn_1 = new TableViewerColumn(tableViewerMessage, SWT.NONE); TableColumn tblclmnSql = tableViewerColumn_1.getColumn(); tblclmnSql.setWidth(500); tblclmnSql.setText(Messages.get().MongodbResultComposite_19); tblclmnSql.addSelectionListener(getSelectionAdapter(tableViewerMessage, sorterMessage, tblclmnSql, 1)); tableViewerMessage.setLabelProvider(new SQLHistoryLabelProvider()); tableViewerMessage.setContentProvider(new ArrayContentProvider()); tableViewerMessage.setInput(listMessage); tableViewerMessage.setComparator(sorterMessage); Composite composite = new Composite(compositeTadpoleMsg, SWT.NONE); composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); composite.setLayout(new GridLayout(3, false)); Button btnExportTadpoleMessage = new Button(composite, SWT.NONE); btnExportTadpoleMessage.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { StringBuffer sbExportData = new StringBuffer(); for(TadpoleMessageDAO dao : listMessage) { sbExportData.append( dao.getStrMessage() ).append(PublicTadpoleDefine.LINE_SEPARATOR); //$NON-NLS-1$ } downloadServiceHandler.setName(userDB.getDisplay_name() + "_Message.txt"); //$NON-NLS-1$ downloadServiceHandler.setByteContent(sbExportData.toString().getBytes()); DownloadUtils.provideDownload(compositeExternal, downloadServiceHandler.getId()); } }); btnExportTadpoleMessage.setText(Messages.get().MongodbResultComposite_20); Label label = new Label(composite, SWT.NONE); label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); Button btnClear = new Button(composite, SWT.NONE); btnClear.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { listMessage.clear(); tableViewerMessage.refresh(); } }); btnClear.setText(Messages.get().MongodbResultComposite_21); registerServiceHandler(); firstTabInit(); } public void find(String strBasicField) { this.strBasicField = strBasicField; find(); } /** * find query * * @param strBasicField * @param strBasicFind * @param strBasicSort * @param cntSkip * @param cntLimit */ public void find(String strBasicField, String strBasicFind, String strBasicSort, int cntSkip, int cntLimit) { this.strBasicField = strBasicField; this.strBasicFind = strBasicFind; this.strBasicSort = strBasicSort; this.cntSkip = cntSkip; this.cntLimit = cntLimit; find(); } /** * */ private void find() { final Display display = getDisplay(); // job Job job = new Job("SQL execute job") { //$NON-NLS-1$ @Override public IStatus run(IProgressMonitor monitor) { monitor.beginTask("Starting JSON query...", IProgressMonitor.UNKNOWN); //$NON-NLS-1$ try { // field BasicDBObject basicFields = (BasicDBObject)JSON.parse(strBasicField); if(null == basicFields) basicFields = new BasicDBObject(); // search DBObject basicWhere = (DBObject)JSON.parse(strBasicFind); if(null == basicWhere) basicWhere = new BasicDBObject(); // sort BasicDBObject basicSort = (BasicDBObject)JSON.parse(strBasicSort); if(null == basicSort) basicSort = new BasicDBObject(); if(logger.isDebugEnabled()) { logger.debug("############[text condition]#####################"); //$NON-NLS-1$ logger.debug("[Fields]" + strBasicField); //$NON-NLS-1$ logger.debug("[Find]" + strBasicFind); //$NON-NLS-1$ logger.debug("[Sort]" + strBasicSort); //$NON-NLS-1$ logger.debug("############[text condition]#####################"); //$NON-NLS-1$ } monitor.setTaskName(basicWhere.toString()); // console 초기화 sbConsoleErrorMsg.setLength(0); sbConsoleExecuteMsg.setLength(0); // 검색 find(basicFields, basicWhere, basicSort, cntSkip, cntLimit); } catch (Exception e) { logger.error("find basic collection exception", e); //$NON-NLS-1$ return new Status(Status.ERROR, Activator.PLUGIN_ID, "findBasic " + e.getMessage()); //$NON-NLS-1$ } finally { monitor.done(); } return Status.OK_STATUS; } }; // job의 event를 처리해 줍니다. job.addJobChangeListener(new JobChangeAdapter() { public void done(IJobChangeEvent event) { final IJobChangeEvent jobEvent = event; display.asyncExec(new Runnable() { public void run() { if(jobEvent.getResult().isOK()) { setResult(); } else { sbConsoleErrorMsg.append(jobEvent.getResult().getMessage()); appendMessage(jobEvent.getResult().getException(), jobEvent.getResult().getMessage()); } } }); // end display.asyncExec } // end done }); // end job job.setName(userDB.getDisplay_name()); job.setUser(true); job.schedule(); } /** * 실제 몽고디비와 접속해서 검색을 수행합니다. * * @param basicFields * @param basicWhere * @param basicSort */ private void find(BasicDBObject basicFields, DBObject basicWhere, BasicDBObject basicSort, int cntSkip, int cntLimit) throws Exception { if( (cntLimit - cntSkip) >= defaultMaxCount) { // "검색 수가 " + defaultMaxCount + "를 넘을수 없습니다. Prefernece에서 값을 조절하십시오." // Search can not exceed the number 5. Set in Perference. throw new Exception(String.format(Messages.get().MongoDBTableEditor_0, ""+defaultMaxCount)); //$NON-NLS-2$ //$NON-NLS-1$ } DB mongoDB = MongoDBQuery.findDB(userDB); DBCollection dbCollection = MongoDBQuery.findCollection(userDB, collectionName); // 데이터 검색 DBCursor dbCursor = null; try { if(cntSkip > 0 && cntLimit > 0) { dbCursor = dbCollection. find(basicWhere, basicFields). sort(basicSort). skip(cntSkip). limit(cntLimit) ; } else if(cntSkip == 0 && cntLimit > 0) { dbCursor = dbCollection. find(basicWhere, basicFields). sort(basicSort). limit(cntLimit); } else { dbCursor = dbCollection. find(basicWhere, basicFields). sort(basicSort); } DBObject explainDBObject = dbCursor.explain(); sbConsoleExecuteMsg.append(JSONUtil.getPretty(explainDBObject.toString())).append("\r\n"); //$NON-NLS-1$ //$NON-NLS-2$ sbConsoleErrorMsg.append(JSONUtil.getPretty(mongoDB.getWriteConcern()==null?"":mongoDB.getWriteConcern().toString())).append("\r\n"); //$NON-NLS-1$ //$NON-NLS-2$ if(logger.isDebugEnabled()) logger.debug(mongoDB.getWriteConcern().toString()); // 결과 데이터를 출력합니다. refreshDBView(dbCursor, dbCursor.count()); } finally { if(dbCursor != null) dbCursor.close(); } } /** * 결과셋을 출력합니다. * * @param iteResult * @param intTotalCnt * @throws Exception */ public void refreshDBView(DBObject dbObject, int intTotalCnt) throws Exception { List<DBObject> listIte = new ArrayList<DBObject>(); listIte.add(dbObject); refreshDBView(listIte, intTotalCnt); } /** * 결과셋을 출력합니다. * * @param iteResult * @param intTotalCnt * @throws Exception */ public void refreshDBView(Iterable<DBObject> iteResult, int intTotalCnt) throws Exception { int totCnt = 0; mapColumns = new HashMap<Integer, String>(); sourceDataList = new ArrayList<Map<Integer, Object>>(); listTrees = new ArrayList<MongodbTreeViewDTO>(); // 헤더를 분석하여 만듭니다. for(DBObject dbObject : iteResult) { MongoDBTableColumn.getTabelColumnView(dbObject, mapColumns); } for(DBObject dbObject : iteResult) { // append tree data columnInfo.get(key) MongodbTreeViewDTO treeDto = new MongodbTreeViewDTO(dbObject, "(" + totCnt + ") {..}", "", "Document"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ parserTreeObject(dbObject, treeDto, dbObject); listTrees.add(treeDto); // append table data HashMap<Integer, Object> dataMap = new HashMap<Integer, Object>(); for(int i=0; i<mapColumns.size(); i++) { Object keyVal = dbObject.get(mapColumns.get(i)); if(keyVal == null) dataMap.put(i, ""); //$NON-NLS-1$ else dataMap.put(i, keyVal.toString()); } // 데이터 삭제 및 수정에서 사용하기 위한 id dataMap.put(MongoDBDefine.PRIMARY_ID_KEY, dbObject); sourceDataList.add(dataMap); // append row text totCnt++; } txtCnt = intTotalCnt + "/" + totCnt; //$NON-NLS-1$ } /** * parser tree obejct * * @param dbObject */ private void parserTreeObject(final DBObject rootDbObject, final MongodbTreeViewDTO treeDto, final DBObject dbObject) throws Exception { List<MongodbTreeViewDTO> listTrees = new ArrayList<MongodbTreeViewDTO>(); Map<Integer, String> tmpMapColumns = MongoDBTableColumn.getTabelColumnView(dbObject); for(int i=0; i<tmpMapColumns.size(); i++) { MongodbTreeViewDTO tmpTreeDto = new MongodbTreeViewDTO(); tmpTreeDto.setDbObject(rootDbObject); String keyName = tmpMapColumns.get(i); Object keyVal = dbObject.get(keyName); tmpTreeDto.setRealKey(keyName); // is sub document if( keyVal instanceof BasicDBObject ) { tmpTreeDto.setKey(tmpMapColumns.get(i) + " {..}"); //$NON-NLS-1$ tmpTreeDto.setType("Document"); //$NON-NLS-1$ parserTreeObject(rootDbObject, tmpTreeDto, (DBObject)keyVal); } else if(keyVal instanceof BasicDBList) { BasicDBList dbObjectList = (BasicDBList)keyVal; tmpTreeDto.setKey(tmpMapColumns.get(i) + " [" + dbObjectList.size() + "]"); //$NON-NLS-1$ //$NON-NLS-2$ tmpTreeDto.setType("Array"); //$NON-NLS-1$ parseObjectArray(rootDbObject, tmpTreeDto, dbObjectList); } else { tmpTreeDto.setKey(tmpMapColumns.get(i)); tmpTreeDto.setType(keyVal != null?keyVal.getClass().getName():"Unknow"); //$NON-NLS-1$ if(keyVal == null) tmpTreeDto.setValue(""); //$NON-NLS-1$ else tmpTreeDto.setValue(keyVal.toString()); } // 컬럼의 데이터를 넣는다. listTrees.add(tmpTreeDto); } treeDto.setChildren(listTrees); } /** * object array * * @param treeDto * @param dbObject * @throws Exception */ private void parseObjectArray(final DBObject rootDbObject, final MongodbTreeViewDTO treeDto, final BasicDBList dbObjectList) throws Exception { List<MongodbTreeViewDTO> listTrees = new ArrayList<MongodbTreeViewDTO>(); for(int i=0; i<dbObjectList.size(); i++) { MongodbTreeViewDTO mongodbDto = new MongodbTreeViewDTO(); mongodbDto.setRealKey("" + i ); //$NON-NLS-1$ mongodbDto.setKey("(" + i + ")"); //$NON-NLS-1$ //$NON-NLS-2$ mongodbDto.setDbObject(rootDbObject); Object keyVal = dbObjectList.get(i); if( keyVal instanceof BasicDBObject ) { mongodbDto.setType("Document"); //$NON-NLS-1$ parserTreeObject(rootDbObject, mongodbDto, (DBObject)keyVal); } else if(keyVal instanceof BasicDBList) { BasicDBList tmpDbObjectList = (BasicDBList)keyVal; mongodbDto.setType("Array"); //$NON-NLS-1$ parseObjectArray(rootDbObject, mongodbDto, tmpDbObjectList); } else { mongodbDto.setType(keyVal != null?keyVal.getClass().getName():"Unknow"); //$NON-NLS-1$ if(keyVal == null) mongodbDto.setValue(""); //$NON-NLS-1$ else mongodbDto.setValue(keyVal.toString()); } listTrees.add(mongodbDto); } treeDto.setChildren(listTrees); } /** * 테이블의 결과를 출력합니다. * */ public void setResult() { // 화면을 초기화 합니다. List<MongodbTreeViewDTO> tmpTree = new ArrayList<MongodbTreeViewDTO>(); treeViewerMongo.setInput(tmpTree); treeViewerMongo.refresh(); List<HashMap<Integer, Object>> tmpTable = new ArrayList<HashMap<Integer,Object>>(); resultTableViewer.setLabelProvider( new SQLResultLabelProvider(GetPreferenceGeneral.getISRDBNumberIsComma(), GetPreferenceGeneral.getResultNull()) ); resultTableViewer.setContentProvider(new SQLResultContentProvider(sourceDataList) ); resultTableViewer.setInput(tmpTable); resultTableViewer.refresh(); lblTreeViewCount.setText(""); //$NON-NLS-1$ lblTableViewCount.setText(""); //$NON-NLS-1$ setJsonView(""); // if(tabFolderMongoDB.getSelectionIndex() == TAB_POSITION_MESSAGE_VIEW) { if(PreferenceDefine.MONGO_DEFAULT_RESULT_TREE.equals( defaultResultPage )) { tabFolderMongoDB.setSelection(TAB_POSITION_TREE_VIEW); } else if(PreferenceDefine.MONGO_DEFAULT_RESULT_TABLE.equals( defaultResultPage )) { tabFolderMongoDB.setSelection(TAB_POSITION_TABLE_VIEW); } else if(PreferenceDefine.MONGO_DEFAULT_RESULT_TABLE.equals( defaultResultPage )) { tabFolderMongoDB.setSelection(TAB_POSITION_JSON_VIEW); } else { tabFolderMongoDB.setSelection(TAB_POSITION_MESSAGE_VIEW); } } selectData(); } /** * select data */ private void selectData() { int selectionIndex = tabFolderMongoDB.getSelectionIndex(); // tree view if(selectionIndex == TAB_POSITION_TREE_VIEW) { treeViewerMongo.setInput(listTrees); treeViewerMongo.expandToLevel(1); lblTreeViewCount.setText(txtCnt); lblTreeViewCount.getParent().layout(); // table view } else if(selectionIndex == TAB_POSITION_TABLE_VIEW) { lblTableViewCount.setText(txtCnt); lblTableViewCount.getParent().layout(); sqlSorter = new SQLResultSorter(-999); createTableColumn(mapColumns, sqlSorter); resultTableViewer.setLabelProvider( new SQLResultLabelProvider() ); resultTableViewer.setContentProvider(new SQLResultContentProvider(sourceDataList) ); resultTableViewer.setInput(sourceDataList); resultTableViewer.setSorter(sqlSorter); sqlFilter.setTable(resultTableViewer.getTable()); } else if(selectionIndex == TAB_POSITION_JSON_VIEW) { StringBuffer sbJsonStr = new StringBuffer(); sbJsonStr.append("{"); for(int i=0; i<sourceDataList.size(); i++) { sbJsonStr.append(i + ": "); String strJson = sourceDataList.get(i).get(MongoDBDefine.PRIMARY_ID_KEY).toString(); if(i < sourceDataList.size()-1) sbJsonStr.append(strJson + ", "); else sbJsonStr.append(strJson); } sbJsonStr.append("}"); setJsonView(sbJsonStr.toString()); } TreeUtil.packTree(treeViewerMongo.getTree()); TableUtil.packTable(resultTableViewer.getTable()); } /** * page를 초기화 합니다. */ private void firstTabInit() { if(PreferenceDefine.MONGO_DEFAULT_RESULT_TREE.equals( defaultResultPage )) { tabFolderMongoDB.setSelection(TAB_POSITION_TREE_VIEW); } else if(PreferenceDefine.MONGO_DEFAULT_RESULT_TABLE.equals( defaultResultPage )) { tabFolderMongoDB.setSelection(TAB_POSITION_TABLE_VIEW); } else if(PreferenceDefine.MONGO_DEFAULT_RESULT_TABLE.equals( defaultResultPage )) { tabFolderMongoDB.setSelection(TAB_POSITION_JSON_VIEW); } else { tabFolderMongoDB.setSelection(TAB_POSITION_MESSAGE_VIEW); } } /** * document insert */ private void newDocument() { NewDocumentDialog dialog = new NewDocumentDialog(Display.getCurrent().getActiveShell(), userDB, collectionName); if(Dialog.OK == dialog.open()) { find(); } } /** * 인덱스를 생성합니다. */ private void createIndex() { NewIndexDialog dialog = new NewIndexDialog(Display.getCurrent().getActiveShell(), userDB, collectionName); dialog.open(); } /** * document del - tree */ private void deleteDocumentTree() { IStructuredSelection iss = (IStructuredSelection)treeViewerMongo.getSelection(); if(iss.isEmpty()) { MessageDialog.openWarning(null, CommonMessages.get().Warning, Messages.get().MongodbResultComposite_10); return; } else if(MessageDialog.openConfirm(null, CommonMessages.get().Confirm, Messages.get().MongodbResultComposite_12)) { MongodbTreeViewDTO dto = (MongodbTreeViewDTO)iss.getFirstElement(); if(logger.isDebugEnabled()) logger.info("[delete object id is]" + dto.getDbObject().toString()); //$NON-NLS-1$ try { MongoDBQuery.deleteDocument(userDB, collectionName, dto.getDbObject()); find(); } catch (Exception e) { logger.error(collectionName + " collection document remove object id is" + dto.getDbObject(), e); //$NON-NLS-1$ Status errStatus = new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e); //$NON-NLS-1$ ExceptionDetailsErrorDialog.openError(null,CommonMessages.get().Error, "Document remove", errStatus); //$NON-NLS-1$ //$NON-NLS-2$ } } } /** * document del - table */ private void deleteDocumentTable() { IStructuredSelection iss = (IStructuredSelection)resultTableViewer.getSelection(); if(iss.isEmpty()) { MessageDialog.openWarning(null, CommonMessages.get().Warning, Messages.get().MongodbResultComposite_10); return; } else if(MessageDialog.openConfirm(null, CommonMessages.get().Confirm, Messages.get().MongodbResultComposite_12)) { HashMap<Integer, Object> rsResult = (HashMap<Integer, Object>)iss.getFirstElement(); Object dbObject = rsResult.get(MongoDBDefine.PRIMARY_ID_KEY); try { MongoDBQuery.deleteDocument(userDB, collectionName, (DBObject)dbObject); find(); } catch (Exception e) { logger.error(collectionName + " collection document remove object id is" + dbObject, e); //$NON-NLS-1$ Status errStatus = new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e); //$NON-NLS-1$ ExceptionDetailsErrorDialog.openError(null,CommonMessages.get().Error, "Document remove", errStatus); //$NON-NLS-1$ //$NON-NLS-2$ } } } /** * treeview create */ private void createTreeColumn() { String[] columnName = {"Key", "Value", "Type"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ int[] columnSize = {170, 300, 170}; try { // reset column for(int i=0; i<columnName.length; i++) { final TreeViewerColumn treeColumn = new TreeViewerColumn(treeViewerMongo, SWT.LEFT); treeColumn.getColumn().setText( columnName[i] ); treeColumn.getColumn().setWidth( columnSize[i] ); treeColumn.getColumn().setResizable(true); treeColumn.getColumn().setMoveable(false); if(isUserAction) { if(i == 1) treeColumn.setEditingSupport(new TreeViewerEditingSupport(userDB, collectionName, treeViewerMongo)); } } // end for } catch(Exception e) { logger.error("MongoDB Tree view Editor", e); //$NON-NLS-1$ } } /** * 필터를 설정합니다. */ private void setFilter() { sqlFilter.setFilter(textFilter.getText()); resultTableViewer.addFilter( sqlFilter ); } /** * table column adapter * * @param column * @param index * @return */ private SelectionAdapter getSelectionAdapter(final TableViewer viewer, final DefaultViewerSorter comparator, final TableColumn column, final int index) { SelectionAdapter selectionAdapter = new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { comparator.setColumn(index); viewer.getTable().setSortDirection(comparator.getDirection()); viewer.getTable().setSortColumn(column); viewer.refresh(); } }; return selectionAdapter; } /** * collection column * * @param mapColumns2 */ private void createTableColumn(Map<Integer, String> mapColumns, final SQLResultSorter tableSorter) { // 기존 column을 삭제한다. Table table = resultTableViewer.getTable(); int columnCount = table.getColumnCount(); for(int i=0; i<columnCount; i++) { table.getColumn(0).dispose(); } try { // reset column for (Integer key : mapColumns.keySet()) { final int index = key; final TableViewerColumn tableColumn = new TableViewerColumn(resultTableViewer, SWT.LEFT); tableColumn.getColumn().setText( mapColumns.get(key) ); tableColumn.getColumn().setResizable(true); tableColumn.getColumn().setMoveable(false); tableColumn.getColumn().addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { tableSorter.setColumn(index); int dir = resultTableViewer.getTable().getSortDirection(); if (resultTableViewer.getTable().getSortColumn() == tableColumn.getColumn()) { dir = dir == SWT.UP ? SWT.DOWN : SWT.UP; } else { dir = SWT.DOWN; } resultTableViewer.getTable().setSortDirection(dir); resultTableViewer.getTable().setSortColumn(tableColumn.getColumn()); resultTableViewer.refresh(); } }); } // end for } catch(Exception e) { logger.error("MongoDB Table Editor", e); //$NON-NLS-1$ } } /** registery service handler */ private void registerServiceHandler() { downloadServiceHandler = new DownloadServiceHandler(); RWT.getServiceManager().registerServiceHandler(downloadServiceHandler.getId(), downloadServiceHandler); } /** * append tadpole message * * @param throwable * @param msg */ public void appendMessage(Throwable throwable, String msg) { tabFolderMongoDB.setSelection(3); listMessage.add(new TadpoleMessageDAO(new Date(), msg, throwable)); tableViewerMessage.refresh(); } @Override protected void checkSubclass() { } public void structureView() { final Display display = getDisplay(); // job Job job = new Job("Structure collection analyized job") { //$NON-NLS-1$ @Override public IStatus run(IProgressMonitor monitor) { monitor.beginTask("Collection structure...", IProgressMonitor.UNKNOWN); //$NON-NLS-1$ List<DBObject> mapOnlyOnDBObject = new ArrayList<>(); try { MongoDBQueryUtil qu = new MongoDBQueryUtil(userDB, collectionName); while(qu.nextQuery()) { // row 단위 List<DBObject> listDBObject = qu.getCollectionDataList(); for (DBObject dbObject : listDBObject) { if(mapOnlyOnDBObject.isEmpty()) mapOnlyOnDBObject.add(dbObject); else { // 검사한 모든 행이 없는지 검사 결과를 넣습니다. Map<Integer, Boolean> mapSearchResult = new HashMap<>(); // 유일한 오브젝트에 모두 들어 있는지 비교한다. for(int i=0; i<mapOnlyOnDBObject.size(); i++) { DBObject alradyDbObject = mapOnlyOnDBObject.get(i); // if(logger.isDebugEnabled()) logger.debug("\t=====> find object is " + alradyDbObject.toString()); // 검사하려는 오브젝트에 비교한다. for (String strKey : dbObject.keySet()) { // if(logger.isDebugEnabled()) logger.debug("\t\t search object is " + strKey); if(!alradyDbObject.containsField(strKey)) { mapSearchResult.put(i, true); break; } } } // end already for int intFoundObject = 0; for (int i=0; i<mapOnlyOnDBObject.size(); i++) { if(mapSearchResult.containsKey(i)) { intFoundObject++; } } if(intFoundObject == mapOnlyOnDBObject.size()) { mapOnlyOnDBObject.add(dbObject); } } // end if } refreshDBView(mapOnlyOnDBObject, mapOnlyOnDBObject.size()); } } catch (Exception e) { logger.error("struct collection exception", e); //$NON-NLS-1$ return new Status(Status.ERROR, Activator.PLUGIN_ID, "collection structure " + e.getMessage()); //$NON-NLS-1$ } finally { monitor.done(); } return Status.OK_STATUS; } }; // job의 event를 처리해 줍니다. job.addJobChangeListener(new JobChangeAdapter() { public void done(IJobChangeEvent event) { final IJobChangeEvent jobEvent = event; display.asyncExec(new Runnable() { public void run() { if(jobEvent.getResult().isOK()) { setResult(); } else { sbConsoleErrorMsg.append(jobEvent.getResult().getMessage()); appendMessage(jobEvent.getResult().getException(), jobEvent.getResult().getMessage()); } } }); // end display.asyncExec } // end done }); // end job job.setName(userDB.getDisplay_name()); job.setUser(true); job.schedule(); } /** * setting json view * * @param strJSON */ private void setJsonView(String strJSON) { try { tadpoleEditor.setText(JSONUtil.getPretty(strJSON)); } catch(Exception e) { logger.error("json view", e); //$NON-NLS-1$ } } /** * error console */ public void consoleError() { DBObject dbObject = (DBObject)JSON.parse(sbConsoleErrorMsg.toString() ); FindOneDetailDialog dlg = new FindOneDetailDialog(null, userDB, collectionName + " " + Messages.get().MongodbResultComposite_25, dbObject); dlg.open(); } /** * execute plan console */ public void consoleExecutePlan() { DBObject dbObject = (DBObject)JSON.parse(sbConsoleExecuteMsg.toString()); FindOneDetailDialog dlg = new FindOneDetailDialog(null, userDB, collectionName + " " + Messages.get().MongodbResultComposite_26, dbObject); dlg.open(); } }