Repository: dboissier/nosql4idea Branch: master Commit: aded21e65cae Files: 175 Total size: 554.1 KB Directory structure: gitextract_ngp6_0ag/ ├── .gitignore ├── CHANGELOG.txt ├── LICENSE.txt ├── README.md ├── fetchIdea.sh ├── nosql4idea.iml.template ├── pom.xml └── src/ ├── main/ │ ├── java/ │ │ └── org/ │ │ └── codinjutsu/ │ │ └── tools/ │ │ └── nosql/ │ │ ├── ConfigurationDialog.java │ │ ├── DatabaseVendor.java │ │ ├── DatabaseVendorClientManager.java │ │ ├── DatabaseVendorUIManager.java │ │ ├── NoSqlComponent.java │ │ ├── NoSqlConfigurable.java │ │ ├── NoSqlConfiguration.java │ │ ├── NoSqlExplorerPanel.form │ │ ├── NoSqlExplorerPanel.java │ │ ├── NoSqlServerTableModel.java │ │ ├── NoSqlTreeRenderer.java │ │ ├── NoSqlWindowManager.java │ │ ├── SelectDatabaseVendorDialog.form │ │ ├── SelectDatabaseVendorDialog.java │ │ ├── ServerConfiguration.java │ │ ├── commons/ │ │ │ ├── DatabaseUI.java │ │ │ ├── logic/ │ │ │ │ ├── ConfigurationException.java │ │ │ │ └── DatabaseClient.java │ │ │ ├── model/ │ │ │ │ ├── AuthenticationSettings.java │ │ │ │ ├── Database.java │ │ │ │ └── DatabaseServer.java │ │ │ ├── style/ │ │ │ │ └── StyleAttributesProvider.java │ │ │ ├── utils/ │ │ │ │ ├── DateUtils.java │ │ │ │ ├── GuiUtils.java │ │ │ │ └── StringUtils.java │ │ │ └── view/ │ │ │ ├── AuthenticationView.java │ │ │ ├── ErrorPanel.java │ │ │ ├── NoSqlResultView.java │ │ │ ├── NoSqlTreeNode.java │ │ │ ├── ServerConfigurationPanel.form │ │ │ ├── ServerConfigurationPanel.java │ │ │ ├── ServerConfigurationPanelFactory.java │ │ │ ├── action/ │ │ │ │ ├── ExecuteQuery.java │ │ │ │ ├── NoSqlDatabaseConsoleAction.java │ │ │ │ ├── OpenPluginSettingsAction.java │ │ │ │ ├── RefreshServerAction.java │ │ │ │ └── ViewCollectionValuesAction.java │ │ │ ├── console/ │ │ │ │ └── NoSqlConsoleView.java │ │ │ ├── editor/ │ │ │ │ ├── NoSqlDatabaseDataEditor.java │ │ │ │ ├── NoSqlDatabaseDataEditorProvider.java │ │ │ │ ├── NoSqlDatabaseFileSystem.java │ │ │ │ └── NoSqlDatabaseObjectFile.java │ │ │ ├── nodedescriptor/ │ │ │ │ └── NodeDescriptor.java │ │ │ ├── renderer/ │ │ │ │ ├── KeyCellRenderer.java │ │ │ │ └── ValueCellRenderer.java │ │ │ └── table/ │ │ │ ├── CellEditor.java │ │ │ └── DateTimePicker.java │ │ ├── couchbase/ │ │ │ ├── CouchbaseUI.java │ │ │ ├── logic/ │ │ │ │ └── CouchbaseClient.java │ │ │ ├── model/ │ │ │ │ ├── CouchbaseDatabase.java │ │ │ │ ├── CouchbaseQuery.java │ │ │ │ └── CouchbaseResult.java │ │ │ └── view/ │ │ │ ├── CouchbaseAuthenticationPanel.java │ │ │ ├── CouchbasePanel.form │ │ │ ├── CouchbasePanel.java │ │ │ ├── CouchbaseTreeModel.java │ │ │ ├── couchbaseAuthenticationPanel.form │ │ │ ├── editor/ │ │ │ │ ├── CouchbaseFakeFileType.java │ │ │ │ └── CouchbaseObjectFile.java │ │ │ └── nodedescriptor/ │ │ │ ├── CouchbaseKeyValueDescriptor.java │ │ │ ├── CouchbaseResultDescriptor.java │ │ │ └── CouchbaseValueDescriptor.java │ │ ├── mongo/ │ │ │ ├── MongoUI.java │ │ │ ├── MongoUtils.java │ │ │ ├── logic/ │ │ │ │ ├── MongoClient.java │ │ │ │ ├── MongoClientURIBuilder.java │ │ │ │ ├── MongoConnectionException.java │ │ │ │ └── MongoExtraSettings.java │ │ │ ├── model/ │ │ │ │ ├── JsonDataType.java │ │ │ │ ├── MongoAggregateOperator.java │ │ │ │ ├── MongoCollection.java │ │ │ │ ├── MongoDatabase.java │ │ │ │ ├── MongoQueryOptions.java │ │ │ │ ├── MongoResult.java │ │ │ │ └── OperatorValueConverter.java │ │ │ ├── runner/ │ │ │ │ ├── MongoCommandLineState.java │ │ │ │ ├── MongoRunConfiguration.java │ │ │ │ ├── MongoRunConfigurationEditor.form │ │ │ │ ├── MongoRunConfigurationEditor.java │ │ │ │ ├── MongoRunConfigurationType.java │ │ │ │ └── MongoScriptRunConfigurationProducer.java │ │ │ └── view/ │ │ │ ├── AbstractAddDialog.java │ │ │ ├── AddKeyDialog.form │ │ │ ├── AddKeyDialog.java │ │ │ ├── AddValueDialog.form │ │ │ ├── AddValueDialog.java │ │ │ ├── JsonTreeTableView.java │ │ │ ├── MongoAuthenticationPanel.form │ │ │ ├── MongoAuthenticationPanel.java │ │ │ ├── MongoEditionPanel.form │ │ │ ├── MongoEditionPanel.java │ │ │ ├── MongoPanel.form │ │ │ ├── MongoPanel.java │ │ │ ├── MongoResultPanel.form │ │ │ ├── MongoResultPanel.java │ │ │ ├── QueryPanel.form │ │ │ ├── QueryPanel.java │ │ │ ├── action/ │ │ │ │ ├── AddMongoDocumentAction.java │ │ │ │ ├── CloseFindEditorAction.java │ │ │ │ ├── CopyResultAction.java │ │ │ │ ├── DropCollectionAction.java │ │ │ │ ├── DropDatabaseAction.java │ │ │ │ ├── EditMongoDocumentAction.java │ │ │ │ ├── EnableAggregateAction.java │ │ │ │ ├── OpenFindAction.java │ │ │ │ ├── OperatorCompletionAction.java │ │ │ │ └── edition/ │ │ │ │ ├── AddKeyAction.java │ │ │ │ ├── AddValueAction.java │ │ │ │ └── DeleteKeyAction.java │ │ │ ├── console/ │ │ │ │ └── MongoConsoleRunner.java │ │ │ ├── editor/ │ │ │ │ ├── MongoFakeFileType.java │ │ │ │ └── MongoObjectFile.java │ │ │ ├── model/ │ │ │ │ └── JsonTreeModel.java │ │ │ ├── nodedescriptor/ │ │ │ │ ├── MongoKeyValueDescriptor.java │ │ │ │ ├── MongoResultDescriptor.java │ │ │ │ └── MongoValueDescriptor.java │ │ │ └── table/ │ │ │ └── MongoDatePickerCellEditor.java │ │ └── redis/ │ │ ├── RedisUI.java │ │ ├── RedisUtils.java │ │ ├── logic/ │ │ │ └── RedisClient.java │ │ ├── model/ │ │ │ ├── RedisDatabase.java │ │ │ ├── RedisKeyType.java │ │ │ ├── RedisQuery.java │ │ │ ├── RedisRecord.java │ │ │ └── RedisResult.java │ │ └── view/ │ │ ├── RedisAuthenticationPanel.form │ │ ├── RedisAuthenticationPanel.java │ │ ├── RedisFragmentedKeyTreeModel.java │ │ ├── RedisPanel.form │ │ ├── RedisPanel.java │ │ ├── RedisTreeModel.java │ │ ├── action/ │ │ │ ├── EnableGroupingAction.java │ │ │ └── SetSeparatorAction.java │ │ ├── console/ │ │ │ └── RedisConsoleRunner.java │ │ ├── editor/ │ │ │ ├── RedisFakeFileType.java │ │ │ └── RedisObjectFile.java │ │ └── nodedescriptor/ │ │ ├── FragmentedKeyNodeDescriptor.java │ │ ├── RedisKeyValueDescriptor.java │ │ ├── RedisResultDescriptor.java │ │ └── RedisValueDescriptor.java │ └── resources/ │ ├── META-INF/ │ │ └── plugin.xml │ └── assemblies/ │ └── plugin-assembly.xml └── test/ ├── java/ │ └── org/ │ └── codinjutsu/ │ └── tools/ │ └── nosql/ │ ├── commons/ │ │ ├── utils/ │ │ │ ├── DateUtilsTest.java │ │ │ └── StringUtilsTest.java │ │ └── view/ │ │ └── TableCellReader.java │ ├── couchbase/ │ │ ├── CouchbaseClientTest.java │ │ └── view/ │ │ ├── CouchbasePanelTest.java │ │ └── ServerConfigurationPanelTest.java │ ├── mongo/ │ │ ├── logic/ │ │ │ ├── MongoClientTest.java │ │ │ └── MongoClientURIBuilderTest.java │ │ └── view/ │ │ ├── MongoEditionPanelTest.java │ │ ├── MongoResultPanelTest.java │ │ ├── ServerConfigurationPanelTest.java │ │ └── model/ │ │ └── JsonTreeModelTest.java │ └── redis/ │ ├── logic/ │ │ └── RedisClientTest.java │ └── view/ │ ├── RedisPanelTest.java │ └── ServerConfigurationPanelTest.java └── resources/ └── org/ └── codinjutsu/ └── tools/ └── nosql/ └── mongo/ ├── logic/ │ └── dummyCollection.json └── view/ ├── arrayOfDocuments.json ├── model/ │ ├── arrayOfDocuments.json │ ├── simpleDocument.json │ ├── simpleDocumentWithInnerNodes.json │ └── simpleDocumentWithSubList.json ├── simpleArray.json ├── simpleDocument.json ├── simpleDocumentForEdition.json ├── simpleDocumentWithSubList.json └── structuredDocument.json ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ *.iml *.ipr *.iws target/ ================================================ FILE: CHANGELOG.txt ================================================ 0.1.0 - Initial version * RedisDB: view database content with filter (KEYS instruction is temporary used) and group with separator pattern * Couchbase: view bucket content with row limit options * MongoDB: all features from the mongo4idea-0.7.3 ;) ================================================ FILE: LICENSE.txt ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright {yyyy} {name of copyright owner} 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. ================================================ FILE: README.md ================================================ # NoSql Plugin for IntelliJ IDEA version 0.1.0-SNAPSHOT ## Description This plugin is a fork from [mongo4idea](https://github.com/dboissier/mongo4idea) and intends to integrate Redis and Couchbase databases. Please note that the Couchbase integration is experimental because I am not a strong user of this database. ## Current status: EAP * [Download the current SNAPSHOT for Idea 14](https://github.com/dboissier/nosql4idea/raw/master/snapshot/nosql4idea-0.1.0-SNAPSHOT-distribution.zip) * [Download the current SNAPSHOT for Idea 15](https://github.com/dboissier/nosql4idea/raw/master/snapshot/nosql4idea-0.1.0-SNAPSHOT-Idea15-distribution.zip) ## Plugin Compatibility This plugin is built with JDK 1.7 and idea 14.1 version. The plugin has been tested with the following databases: * MongoDB 2.7 and 3.0 * Redis 2.8.21 * Couchbase Community 4.0.0 ## Installation To install it : `Settings > Plugins > Install plugin from Disk` ## Configuration On the right, you will see a new tool window named NoSql Explorer ![NoSqlBrowser](https://github.com/dboissier/nosql4idea/raw/master/doc/explorer.png) * Click on the Wrench Icon from the toolbar and you will be redirected to the Plugin Settings. * You can specify the mongo and redis CLI paths at the top of the panel * To add a server, click on the **\[+\]** button and choose you database vendor ![SettingsAddAServer](https://github.com/dboissier/nosql4idea/raw/master/doc/settings_add_a_server.png) * Click on the **OK** button and enter the settings of your database ![MongoSettings](https://github.com/dboissier/nosql4idea/raw/master/doc/mongo_settings.png) * When all your dabatase are configured you should see then in the explorer panel ![NoSqlBrowserWithServers](https://github.com/dboissier/nosql4idea/raw/master/doc/explorer_with_servers.png) ## Viewing the Redis database content Double click on the database icon from your redis server and the results will appear as a tab ![RedisResults](https://github.com/dboissier/nosql4idea/raw/master/doc/redis_results.png) You can filter the results (Currently, it runs a `KEYS ` command. A `SCAN ` will replace it in the future for optimization purpose.) Like the **Properties editor**, you can group your data by prefix. Click on the corresponding icon and then click on the Elipsis icon to set you separator ![RedisResultsGroupedByPrefix](https://github.com/dboissier/nosql4idea/raw/master/doc/redis_group_by_prefix.png) ## Viewing the Couchbase database content Double click on the database icon from your couchbase server and the results will appear as a tab ![CouchbaseResults](https://github.com/dboissier/nosql4idea/raw/master/doc/couchbase_results.png) **Important note** To get the results from each bucket, an **Index** must be created. Otherwise an error message is raised. ## Roadmap ### 0.1.0 * integrate Redis : view results with 'Group by prefix' feature like **properties editor** * integrate Couchbase : view results ### 0.2.0 * delete, update and add features for Redis and Couchbase ================================================ FILE: fetchIdea.sh ================================================ #!/usr/bin/env bash # original file from https://github.com/go-lang-plugin-org/go-lang-idea-plugin # thanks zolotov :) ideaVersion='14.1.5' ideaVersionForMaven='14.1' #ideaVersion='15.0' #ideaVersionForMaven='15.0' rm -rf ./idea-IC # Get our IDEA dependency wget http://download.jetbrains.com/idea/ideaIC-${ideaVersion}.tar.gz # Unzip IDEA tar -xzf ideaIC-${ideaVersion}.tar.gz rm -rf ideaIC-${ideaVersion}.tar.gz # Move the versioned IDEA folder to a known location ideaPath=$(find . -name 'idea-IC*' | head -n 1) echo 'Found Intellij path:' + ${ideaPath} mv ${ideaPath} ./idea-IC cd ./idea-IC # install IDEA dependencies IDEA_HOME=$(pwd) libs=( 'forms_rt' 'openapi' 'util' 'idea' 'resources' 'resources_en' 'swingx-core-1.6.2' 'annotations' 'extensions' 'jna' 'jdom' 'icons') for lib in "${libs[@]}" do mvn install:install-file -Dfile=${IDEA_HOME}/lib/${lib}.jar -DgroupId=com.intellij -DartifactId=${lib} -Dversion=${ideaVersionForMaven} -Dpackaging=jar done ================================================ FILE: nosql4idea.iml.template ================================================ ================================================ FILE: pom.xml ================================================ 4.0.0 org.codinjutsu.tools.nosql nosql4idea 0.1.0-SNAPSHOT UTF-8 1.7 1.7 141.2735.5 14.1 ${env.IDEA_HOME}/lib jar NoSQL Idea Plugin NoSQL databases integration for Intellij 2015 David Boissier david [dot] boissier [at] gmail [dot] com Codinjutsu +1 org.mongodb mongo-java-driver 3.0.4 org.slf4j slf4j-nop 1.7.12 redis.clients jedis 2.7.3 com.couchbase.client java-client 2.2.1 commons-lang commons-lang 2.4 log4j log4j 1.2.14 com.intellij forms_rt ${intellij.sdk.version} com.intellij openapi ${intellij.sdk.version} com.intellij util ${intellij.sdk.version} junit junit 4.10 test org.mockito mockito-all 1.8.5 test org.easytesting fest-swing 1.2 test org.easytesting fest-util 1.1.3 test commons-io commons-io 1.4 test com.intellij idea system ${intellij.lib.path}/idea.jar ${intellij.sdk.version} com.intellij extensions system ${intellij.lib.path}/extensions.jar ${intellij.sdk.version} com.intellij icons system ${intellij.lib.path}/icons.jar ${intellij.sdk.version} com.intellij trove4j system ${intellij.lib.path}/trove4j.jar ${intellij.sdk.version} com.intellij annotations system ${intellij.lib.path}/annotations.jar ${intellij.sdk.version} com.intellij jdom system ${intellij.lib.path}/jdom.jar ${intellij.sdk.version} com.intellij swingx-core system ${intellij.lib.path}/swingx-core-1.6.2.jar ${intellij.sdk.version} com.intellij jna system ${intellij.lib.path}/jna.jar ${intellij.sdk.version} com.intellij resources system ${intellij.lib.path}/resources.jar ${intellij.sdk.version} com.intellij resources_en system ${intellij.lib.path}/resources_en.jar ${intellij.sdk.version} org.codehaus.mojo ideauidesigner-maven-plugin 1.0-beta-1 compile javac2 true false true true maven-assembly-plugin 2.2.1 package assembly ${project.artifactId}-${project.version} src/main/resources/assemblies/plugin-assembly.xml src/main/resources src/test/resources The Apache Software License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0.txt scm:git:ssh://git@github.com/dboissier/nosql4idea.git git:ssh://git@github.com/dboissier/nosql4idea.git ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/ConfigurationDialog.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.ValidationInfo; import org.codinjutsu.tools.nosql.commons.view.ServerConfigurationPanel; import org.codinjutsu.tools.nosql.commons.view.ServerConfigurationPanelFactory; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; class ConfigurationDialog extends DialogWrapper { private final ServerConfigurationPanelFactory serverConfigurationPanelFactory; private final ServerConfiguration configuration; private ServerConfigurationPanel serverConfigurationPanel; ConfigurationDialog(Component parent, ServerConfigurationPanelFactory serverConfigurationPanelFactory, ServerConfiguration configuration) { super(parent, true); this.serverConfigurationPanelFactory = serverConfigurationPanelFactory; this.configuration = configuration; init(); } @Nullable @Override protected JComponent createCenterPanel() { serverConfigurationPanel = this.serverConfigurationPanelFactory.create(configuration.getDatabaseVendor()); serverConfigurationPanel.loadConfigurationData(configuration); return serverConfigurationPanel; } @Nullable @Override protected ValidationInfo doValidate() { return serverConfigurationPanel.validateInputs(); } @Override protected void doOKAction() { super.doOKAction(); serverConfigurationPanel.applyConfigurationData(configuration); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/DatabaseVendor.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql; import org.codinjutsu.tools.nosql.commons.utils.GuiUtils; import javax.swing.*; public enum DatabaseVendor { MONGO("MongoDB", "mongodb.png", "localhost:27017", "format: host:port. If replicat set: host:port1,host:port2,..."), REDIS("RedisDB", "redis.png", "localhost:6379", "format: host:port. If cluster: host:port1,host:port2,..."), COUCHBASE("Couchbase", "couchbase.png", "localhost", "format: host:port. If cluster: host:port1,host:port2,..."); public final String name; public final Icon icon; public final String defaultUrl; public final String tips; DatabaseVendor(String name, String iconFilename, String defaultUrl, String tips) { this.name = name; this.icon = GuiUtils.loadIcon(iconFilename); this.defaultUrl = defaultUrl; this.tips = tips; } @Override public String toString() { return "DatabaseVendor{name='" + name + "'}"; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/DatabaseVendorClientManager.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import org.codinjutsu.tools.nosql.commons.logic.DatabaseClient; import org.codinjutsu.tools.nosql.commons.model.DatabaseServer; import org.codinjutsu.tools.nosql.couchbase.logic.CouchbaseClient; import org.codinjutsu.tools.nosql.mongo.logic.MongoClient; import org.codinjutsu.tools.nosql.redis.logic.RedisClient; import java.util.HashMap; import java.util.Map; public class DatabaseVendorClientManager { private static final Map> dataClientByVendor = new HashMap<>(); static { dataClientByVendor.put(DatabaseVendor.MONGO, MongoClient.class); dataClientByVendor.put(DatabaseVendor.REDIS, RedisClient.class); dataClientByVendor.put(DatabaseVendor.COUCHBASE, CouchbaseClient.class); } private final Project project; public DatabaseVendorClientManager(Project project) { this.project = project; } public static DatabaseVendorClientManager getInstance(Project project) { return ServiceManager.getService(project, DatabaseVendorClientManager.class); } public DatabaseClient get(DatabaseVendor databaseVendor) { return ServiceManager.getService(project, dataClientByVendor.get(databaseVendor)); } public void cleanUpServers() { for (DatabaseVendor databaseVendor : dataClientByVendor.keySet()) { this.get(databaseVendor).cleanUpServers(); } } public void registerServer(DatabaseServer databaseServer) { this.get(databaseServer.getConfiguration().getDatabaseVendor()).registerServer(databaseServer); } public void loadServer(DatabaseServer databaseServer) { this.get(databaseServer.getConfiguration().getDatabaseVendor()).loadServer(databaseServer); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/DatabaseVendorUIManager.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import org.codinjutsu.tools.nosql.commons.DatabaseUI; import org.codinjutsu.tools.nosql.couchbase.CouchbaseUI; import org.codinjutsu.tools.nosql.couchbase.view.editor.CouchbaseObjectFile; import org.codinjutsu.tools.nosql.mongo.MongoUI; import org.codinjutsu.tools.nosql.mongo.view.editor.MongoObjectFile; import org.codinjutsu.tools.nosql.redis.RedisUI; import org.codinjutsu.tools.nosql.redis.view.editor.RedisObjectFile; import java.util.HashMap; import java.util.Map; public class DatabaseVendorUIManager { private static final Map> databaseUIByVendor = new HashMap<>(); static { databaseUIByVendor.put(DatabaseVendor.MONGO, MongoUI.class); databaseUIByVendor.put(DatabaseVendor.REDIS, RedisUI.class); databaseUIByVendor.put(DatabaseVendor.COUCHBASE, CouchbaseUI.class); } private final Project project; public DatabaseVendorUIManager(Project project) { this.project = project; } public static DatabaseVendorUIManager getInstance(Project project) { return ServiceManager.getService(project, DatabaseVendorUIManager.class); } public DatabaseUI get(DatabaseVendor databaseVendor) { return ServiceManager.getService(project, databaseUIByVendor.get(databaseVendor)); } public boolean accept(VirtualFile file) { return file instanceof MongoObjectFile || file instanceof RedisObjectFile || file instanceof CouchbaseObjectFile; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/NoSqlComponent.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql; import com.intellij.openapi.components.AbstractProjectComponent; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; public class NoSqlComponent extends AbstractProjectComponent { private static final String COMPONENT_NAME = "NoSql"; public NoSqlComponent(Project project) { super(project); } @NotNull public String getComponentName() { return COMPONENT_NAME; } public void projectOpened() { NoSqlWindowManager.getInstance(myProject); } public void projectClosed() { NoSqlWindowManager.getInstance(myProject).unregisterMyself(); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/NoSqlConfigurable.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql; import com.intellij.execution.ExecutionException; import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.execution.process.CapturingProcessHandler; import com.intellij.execution.process.ProcessOutput; import com.intellij.openapi.Disposable; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.options.BaseConfigurable; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.LabeledComponent; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.ThrowableComputable; import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.ui.*; import com.intellij.ui.table.JBTable; import org.apache.commons.lang.StringUtils; import org.codinjutsu.tools.nosql.commons.view.ServerConfigurationPanelFactory; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.table.TableCellEditor; import javax.swing.table.TableColumn; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.LinkedList; import java.util.List; import java.util.concurrent.TimeoutException; import static org.apache.commons.lang.StringUtils.isBlank; public class NoSqlConfigurable extends BaseConfigurable { private final Project project; private final NoSqlConfiguration configuration; private final List configurations; private final ServerConfigurationPanelFactory serverConfigurationPanelFactory; private final DatabaseVendorClientManager databaseVendorClientManager; private JPanel mainPanel; private JBTable table; private final NoSqlServerTableModel tableModel; private ShellPathPanel mongoShellPanel; private ShellPathPanel redisShellPanel; public NoSqlConfigurable(Project project) { this.project = project; this.configuration = NoSqlConfiguration.getInstance(project); databaseVendorClientManager = DatabaseVendorClientManager.getInstance(project); this.serverConfigurationPanelFactory = new ServerConfigurationPanelFactory( project, databaseVendorClientManager, DatabaseVendorUIManager.getInstance(project) ); configurations = new LinkedList<>(this.configuration.getServerConfigurations()); tableModel = new NoSqlServerTableModel(configurations); mainPanel = new JPanel(new BorderLayout()); } @Nls @Override public String getDisplayName() { return "NoSql Servers"; } @Nullable @Override public String getHelpTopic() { return "preferences.noSqlOptions"; } @Nullable @Override public JComponent createComponent() { JPanel databaseVendorShellOptionsPanel = new JPanel(); databaseVendorShellOptionsPanel.setLayout(new BoxLayout(databaseVendorShellOptionsPanel, BoxLayout.Y_AXIS)); mongoShellPanel = new ShellPathPanel(DatabaseVendor.MONGO, "--version"); databaseVendorShellOptionsPanel.add(mongoShellPanel); redisShellPanel = new ShellPathPanel(DatabaseVendor.REDIS, "--version"); databaseVendorShellOptionsPanel.add(redisShellPanel); mainPanel.add(databaseVendorShellOptionsPanel, BorderLayout.NORTH); PanelWithButtons panelWithButtons = new PanelWithButtons() { { initPanel(); } @Nullable @Override protected String getLabelText() { return "Servers"; } @Override protected JButton[] createButtons() { return new JButton[]{}; } @Override protected JComponent createMainComponent() { table = new JBTable(tableModel); table.getEmptyText().setText("No server configuration set"); table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); table.setDefaultRenderer(DatabaseVendor.class, new ColoredTableCellRenderer() { @Override protected void customizeCellRenderer(JTable jTable, Object value, boolean b, boolean b1, int i, int i1) { DatabaseVendor databaseVendor = (DatabaseVendor) value; this.setIcon(databaseVendor.icon); this.append(databaseVendor.name); } }); TableColumn autoConnectColumn = table.getColumnModel().getColumn(3); int autoConnectColumnWidth = table.getFontMetrics(table.getFont()).stringWidth(table.getColumnName(3)) + 10; autoConnectColumn.setPreferredWidth(autoConnectColumnWidth); autoConnectColumn.setMaxWidth(autoConnectColumnWidth); autoConnectColumn.setMinWidth(autoConnectColumnWidth); return ToolbarDecorator.createDecorator(table) .setAddAction(new AnActionButtonRunnable() { @Override public void run(AnActionButton button) { stopEditing(); SelectDatabaseVendorDialog databaseVendorDialog = new SelectDatabaseVendorDialog(mainPanel); databaseVendorDialog.setTitle("Add a NoSql Server"); databaseVendorDialog.show(); if (!databaseVendorDialog.isOK()) { return; } DatabaseVendor selectedDatabaseVendor = databaseVendorDialog.getSelectedDatabaseVendor(); ServerConfiguration serverConfiguration = databaseVendorClientManager.get(selectedDatabaseVendor).defaultConfiguration(); serverConfiguration.setDatabaseVendor(selectedDatabaseVendor); ConfigurationDialog dialog = new ConfigurationDialog( mainPanel, serverConfigurationPanelFactory, serverConfiguration ); dialog.setTitle("Add a NoSql Server"); dialog.show(); if (!dialog.isOK()) { return; } configurations.add(serverConfiguration); int index = configurations.size() - 1; tableModel.fireTableRowsInserted(index, index); table.getSelectionModel().setSelectionInterval(index, index); table.scrollRectToVisible(table.getCellRect(index, 0, true)); } }) .setAddActionName("addServer") .setEditAction(new AnActionButtonRunnable() { @Override public void run(AnActionButton button) { stopEditing(); int selectedIndex = table.getSelectedRow(); if (selectedIndex < 0 || selectedIndex >= tableModel.getRowCount()) { return; } ServerConfiguration sourceConfiguration = configurations.get(selectedIndex); ServerConfiguration copiedConfiguration = sourceConfiguration.clone(); ConfigurationDialog dialog = new ConfigurationDialog( mainPanel, serverConfigurationPanelFactory, copiedConfiguration ); dialog.setTitle("Edit a NoSql Server"); dialog.show(); if (!dialog.isOK()) { return; } configurations.set(selectedIndex, copiedConfiguration); tableModel.fireTableRowsUpdated(selectedIndex, selectedIndex); table.getSelectionModel().setSelectionInterval(selectedIndex, selectedIndex); } }) .setEditActionName("editServer") .setRemoveAction(new AnActionButtonRunnable() { @Override public void run(AnActionButton button) { stopEditing(); int selectedIndex = table.getSelectedRow(); if (selectedIndex < 0 || selectedIndex >= tableModel.getRowCount()) { return; } TableUtil.removeSelectedItems(table); } }) .setRemoveActionName("removeServer") .disableUpDownActions().createPanel(); } }; mainPanel.add(panelWithButtons, BorderLayout.CENTER); return mainPanel; } public boolean isModified() { return areConfigurationsModified() || isRedisShellPathModified(); } @Override public void apply() throws ConfigurationException { stopEditing(); if (areConfigurationsModified()) { configuration.setServerConfigurations(configurations); } if (isMongoShellPathModified()) { configuration.setShellPath(DatabaseVendor.MONGO, mongoShellPanel.getShellPath()); } if (isRedisShellPathModified()) { configuration.setShellPath(DatabaseVendor.REDIS, redisShellPanel.getShellPath()); } NoSqlWindowManager.getInstance(project).apply(); } private boolean isMongoShellPathModified() { return mongoShellPanel.isShellPathModified(NoSqlConfiguration.getInstance(project).getShellPath(DatabaseVendor.MONGO)); } private boolean isRedisShellPathModified() { return redisShellPanel.isShellPathModified(NoSqlConfiguration.getInstance(project).getShellPath(DatabaseVendor.REDIS)); } private boolean areConfigurationsModified() { List existingConfigurations = NoSqlConfiguration.getInstance(project).getServerConfigurations(); if (configurations.size() != existingConfigurations.size()) { return true; } for (ServerConfiguration existingConfiguration : existingConfigurations) { if (!configurations.contains(existingConfiguration)) { return true; } } return false; } @Override public void reset() { } @Override public void disposeUIResources() { mainPanel = null; tableModel.removeTableModelListener(table); mongoShellPanel.dispose(); redisShellPanel.dispose(); table = null; } private void stopEditing() { if (table.isEditing()) { TableCellEditor editor = table.getCellEditor(); if (editor != null) { editor.stopCellEditing(); } } } private class ShellPathPanel extends JPanel implements Disposable { private static final int TIMEOUT_MS = 60 * 1000; private final String testParameter; private LabeledComponent shellPathField; private ShellPathPanel(DatabaseVendor databaseVendor, String testParameter) { this.testParameter = testParameter; setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); add(createLabel(databaseVendor.name)); shellPathField = createShellPathField(databaseVendor); add(shellPathField); add(createTestButton(databaseVendor)); } private JLabel createLabel(String databaseVendorName) { return new JLabel(String.format("Path to %s CLI:\t\t", databaseVendorName)); } private JButton createTestButton(final DatabaseVendor databaseVendorName) { JButton testButton = new JButton("Test"); testButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { testPath(databaseVendorName); } }); return testButton; } private void testPath(final DatabaseVendor databaseVendor) { ProcessOutput processOutput; try { processOutput = ProgressManager.getInstance().runProcessWithProgressSynchronously(new ThrowableComputable() { @Override public ProcessOutput compute() throws Exception { return checkShellPath(databaseVendor, getShellPath()); } }, "Testing " + databaseVendor.name + " CLI Executable...", true, NoSqlConfigurable.this.project); } catch (ProcessCanceledException pce) { return; } catch (Exception e) { Messages.showErrorDialog(mainPanel, e.getMessage(), "Something wrong happened"); return; } if (processOutput != null && processOutput.getExitCode() == 0) { Messages.showInfoMessage(mainPanel, processOutput.getStdout(), databaseVendor.name + " CLI Path Checked"); } } public ProcessOutput checkShellPath(DatabaseVendor databaseVendor, String shellPath) throws ExecutionException, TimeoutException { if (isBlank(shellPath)) { return null; } GeneralCommandLine commandLine = new GeneralCommandLine(); commandLine.setExePath(shellPath); if (testParameter != null) { commandLine.addParameter(testParameter); } CapturingProcessHandler handler = new CapturingProcessHandler(commandLine.createProcess(), CharsetToolkit.getDefaultSystemCharset()); ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); ProcessOutput result = indicator == null ? handler.runProcess(TIMEOUT_MS) : handler.runProcessWithProgressIndicator(indicator); if (result.isTimeout()) { throw new TimeoutException("Couldn't check " + databaseVendor.name + " CLI executable - stopped by timeout."); } else if (result.isCancelled()) { throw new ProcessCanceledException(); } else if (result.getExitCode() != 0 || !result.getStderr().isEmpty()) { throw new ExecutionException(String.format("Errors while executing %s. exitCode=%s errors: %s", commandLine.toString(), result.getExitCode(), result.getStderr())); } return result; } public String getShellPath() { String shellPath = shellPathField.getComponent().getText(); if (StringUtils.isNotBlank(shellPath)) { return shellPath; } return null; } public boolean isShellPathModified(String shellPath) { return !StringUtils.equals(shellPath, getShellPath()); } private LabeledComponent createShellPathField(DatabaseVendor databaseVendor) { LabeledComponent shellPathField = new LabeledComponent<>(); TextFieldWithBrowseButton component = new TextFieldWithBrowseButton(); component.getChildComponent().setName("shellPathField"); shellPathField.setComponent(component); shellPathField.getComponent().addBrowseFolderListener(String.format("%s CLI configuration", databaseVendor.name), "", null, new FileChooserDescriptor(true, false, false, false, false, false)); shellPathField.getComponent().setText(configuration.getShellPath(databaseVendor)); return shellPathField; } @Override public void dispose() { shellPathField = null; } } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/NoSqlConfiguration.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql; import com.intellij.openapi.components.*; import com.intellij.openapi.project.Project; import com.intellij.util.xmlb.XmlSerializerUtil; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; @SuppressWarnings("unused") @State( name = "NoSqlConfiguration", storages = { @Storage(file = "$PROJECT_FILE$"), @Storage(file = "$PROJECT_CONFIG_DIR$/noSqlSettings.xml", scheme = StorageScheme.DIRECTORY_BASED) } ) public class NoSqlConfiguration implements PersistentStateComponent { private List serverConfigurations = new LinkedList(); private Map shellPathByDatabaseVendor = new HashMap(); public static NoSqlConfiguration getInstance(Project project) { return ServiceManager.getService(project, NoSqlConfiguration.class); } public NoSqlConfiguration getState() { return this; } public void loadState(NoSqlConfiguration noSqlConfiguration) { XmlSerializerUtil.copyBean(noSqlConfiguration, this); } public void setServerConfigurations(List serverConfigurations) { this.serverConfigurations = serverConfigurations; } public List getServerConfigurations() { return serverConfigurations; } public String getShellPath(DatabaseVendor databaseVendor) { return shellPathByDatabaseVendor.get(databaseVendor); } public void setShellPathByDatabaseVendor(Map shellPathByDatabaseVendor) { this.shellPathByDatabaseVendor = shellPathByDatabaseVendor; } public Map getShellPathByDatabaseVendor() { return shellPathByDatabaseVendor; } public void setShellPath(DatabaseVendor databaseVendor, String shellPath) { shellPathByDatabaseVendor.put(databaseVendor, shellPath); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/NoSqlExplorerPanel.form ================================================
================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/NoSqlExplorerPanel.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql; import com.intellij.ide.CommonActionsManager; import com.intellij.ide.TreeExpander; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.popup.Balloon; import com.intellij.openapi.util.Disposer; import com.intellij.ui.PopupHandler; import com.intellij.ui.components.JBScrollPane; import com.intellij.ui.treeStructure.Tree; import com.intellij.util.ui.tree.TreeUtil; import org.codinjutsu.tools.nosql.commons.logic.ConfigurationException; import org.codinjutsu.tools.nosql.commons.logic.DatabaseClient; import org.codinjutsu.tools.nosql.commons.model.Database; import org.codinjutsu.tools.nosql.commons.model.DatabaseServer; import org.codinjutsu.tools.nosql.commons.utils.GuiUtils; import org.codinjutsu.tools.nosql.commons.view.action.NoSqlDatabaseConsoleAction; import org.codinjutsu.tools.nosql.commons.view.action.OpenPluginSettingsAction; import org.codinjutsu.tools.nosql.commons.view.action.RefreshServerAction; import org.codinjutsu.tools.nosql.commons.view.action.ViewCollectionValuesAction; import org.codinjutsu.tools.nosql.commons.view.editor.NoSqlDatabaseFileSystem; import org.codinjutsu.tools.nosql.commons.view.editor.NoSqlDatabaseObjectFile; import org.codinjutsu.tools.nosql.couchbase.model.CouchbaseDatabase; import org.codinjutsu.tools.nosql.couchbase.view.editor.CouchbaseObjectFile; import org.codinjutsu.tools.nosql.mongo.logic.MongoClient; import org.codinjutsu.tools.nosql.mongo.model.MongoCollection; import org.codinjutsu.tools.nosql.mongo.model.MongoDatabase; import org.codinjutsu.tools.nosql.mongo.view.action.DropCollectionAction; import org.codinjutsu.tools.nosql.mongo.view.action.DropDatabaseAction; import org.codinjutsu.tools.nosql.mongo.view.editor.MongoObjectFile; import org.codinjutsu.tools.nosql.redis.model.RedisDatabase; import org.codinjutsu.tools.nosql.redis.view.editor.RedisObjectFile; import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeSelectionModel; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.net.URL; import java.util.List; import static org.codinjutsu.tools.nosql.commons.utils.GuiUtils.showNotification; public class NoSqlExplorerPanel extends JPanel implements Disposable { private static final URL pluginSettingsUrl = GuiUtils.isUnderDarcula() ? GuiUtils.getIconResource("pluginSettings_dark.png") : GuiUtils.getIconResource("pluginSettings.png"); private JPanel rootPanel; private JPanel treePanel; private Tree databaseTree; private JPanel toolBarPanel; private final Project project; private final DatabaseVendorClientManager databaseVendorClientManager; public NoSqlExplorerPanel(Project project, DatabaseVendorClientManager databaseVendorClientManager) { this.project = project; this.databaseVendorClientManager = databaseVendorClientManager; treePanel.setLayout(new BorderLayout()); databaseTree = createTree(); databaseTree.setCellRenderer(new NoSqlTreeRenderer()); databaseTree.setName("databaseTree"); JBScrollPane mongoTreeScrollPane = new JBScrollPane(databaseTree); setLayout(new BorderLayout()); treePanel.add(mongoTreeScrollPane, BorderLayout.CENTER); add(rootPanel, BorderLayout.CENTER); toolBarPanel.setLayout(new BorderLayout()); ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { reloadAllServerConfigurations(); } }); } public void reloadAllServerConfigurations() { this.databaseVendorClientManager.cleanUpServers(); databaseTree.setRootVisible(false); List serverConfigurations = getServerConfigurations(); if (serverConfigurations.size() == 0) { databaseTree.setModel(null); return; } final DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(); databaseTree.setModel(new DefaultTreeModel(rootNode)); for (ServerConfiguration serverConfiguration : serverConfigurations) { DatabaseServer mongoServer = new DatabaseServer(serverConfiguration); this.databaseVendorClientManager.registerServer(mongoServer); DefaultMutableTreeNode serverNode = new DefaultMutableTreeNode(mongoServer); rootNode.add(serverNode); if (serverConfiguration.isConnectOnIdeStartup()) { this.reloadServerConfiguration(serverNode, false); } } TreeUtil.expand(databaseTree, 2); } public void reloadServerConfiguration(final DefaultMutableTreeNode serverNode, final boolean expandAfterLoading) { databaseTree.setPaintBusy(true); ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { @Override public void run() { final DatabaseServer databaseServer = (DatabaseServer) serverNode.getUserObject(); try { databaseVendorClientManager.loadServer(databaseServer); GuiUtils.runInSwingThread(new Runnable() { @Override public void run() { databaseTree.invalidate(); serverNode.removeAllChildren(); addDatabasesIfAny(databaseServer, serverNode); ((DefaultTreeModel) databaseTree.getModel()).reload(serverNode); databaseTree.revalidate(); if (expandAfterLoading) { GuiUtils.expand(databaseTree, TreeUtil.getPathFromRoot(serverNode), 1); } } }); } catch (ConfigurationException confEx) { databaseServer.setStatus(DatabaseServer.Status.ERROR); showNotification(treePanel, MessageType.ERROR, String.format("Error when connecting on %s", databaseServer.getLabel()), Balloon.Position.atLeft); } finally { databaseTree.setPaintBusy(false); } } }); } private void addDatabasesIfAny(DatabaseServer databaseServer, DefaultMutableTreeNode serverNode) { for (Database database : databaseServer.getDatabases()) { DefaultMutableTreeNode databaseNode = new DefaultMutableTreeNode(database); if (database instanceof MongoDatabase) { MongoDatabase mongoDatabase = (MongoDatabase) database; for (MongoCollection collection : mongoDatabase.getCollections()) { databaseNode.add(new DefaultMutableTreeNode(collection)); } } serverNode.add(databaseNode); } } private List getServerConfigurations() { return NoSqlConfiguration.getInstance(project).getServerConfigurations(); } public void installActions() { final TreeExpander treeExpander = new TreeExpander() { @Override public void expandAll() { NoSqlExplorerPanel.this.expandAll(); } @Override public boolean canExpand() { return true; } @Override public void collapseAll() { NoSqlExplorerPanel.this.collapseAll(); } @Override public boolean canCollapse() { return true; } }; CommonActionsManager actionsManager = CommonActionsManager.getInstance(); final AnAction expandAllAction = actionsManager.createExpandAllAction(treeExpander, rootPanel); final AnAction collapseAllAction = actionsManager.createCollapseAllAction(treeExpander, rootPanel); Disposer.register(this, new Disposable() { @Override public void dispose() { collapseAllAction.unregisterCustomShortcutSet(rootPanel); expandAllAction.unregisterCustomShortcutSet(rootPanel); } }); DefaultActionGroup actionGroup = new DefaultActionGroup("NoSqlExplorerGroup", false); ViewCollectionValuesAction viewCollectionValuesAction = new ViewCollectionValuesAction(this); RefreshServerAction refreshServerAction = new RefreshServerAction(this); if (ApplicationManager.getApplication() != null) { actionGroup.add(refreshServerAction); actionGroup.add(new NoSqlDatabaseConsoleAction(this)); actionGroup.add(viewCollectionValuesAction); actionGroup.add(expandAllAction); actionGroup.add(collapseAllAction); actionGroup.addSeparator(); actionGroup.add(new OpenPluginSettingsAction()); } GuiUtils.installActionGroupInToolBar(actionGroup, toolBarPanel, ActionManager.getInstance(), "NoSqlExplorerActions", true); DefaultActionGroup actionPopupGroup = new DefaultActionGroup("NoSqlExplorerPopupGroup", true); if (ApplicationManager.getApplication() != null) { actionPopupGroup.add(refreshServerAction); actionPopupGroup.add(viewCollectionValuesAction); actionPopupGroup.add(new DropCollectionAction(this)); actionPopupGroup.add(new DropDatabaseAction(this)); } PopupHandler.installPopupHandler(databaseTree, actionPopupGroup, "POPUP", ActionManager.getInstance()); databaseTree.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent mouseEvent) { if (!(mouseEvent.getSource() instanceof JTree)) { return; } DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) databaseTree.getLastSelectedPathComponent(); if (treeNode == null) { return; } if (mouseEvent.getClickCount() == 2) { if (treeNode.getUserObject() instanceof DatabaseServer && treeNode.getChildCount() == 0) { reloadServerConfiguration(getSelectedServerNode(), true); } if (treeNode.getUserObject() instanceof MongoCollection) { loadRecords(); } if (treeNode.getUserObject() instanceof RedisDatabase) { loadRecords(); } if (treeNode.getUserObject() instanceof CouchbaseDatabase) { loadRecords(); } } } }); } private void expandAll() { TreeUtil.expandAll(databaseTree); } private void collapseAll() { TreeUtil.collapseAll(databaseTree, 1); } @Override public void dispose() { databaseTree = null; } public DefaultMutableTreeNode getSelectedServerNode() { DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) databaseTree.getLastSelectedPathComponent(); if (treeNode != null) { Object userObject = treeNode.getUserObject(); if (userObject instanceof MongoCollection) { return (DefaultMutableTreeNode) treeNode.getParent().getParent(); } if (userObject instanceof Database) { return (DefaultMutableTreeNode) treeNode.getParent(); } if (userObject instanceof DatabaseServer) { return treeNode; } } return null; } private DefaultMutableTreeNode getSelectedDatabaseNode() { DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) databaseTree.getLastSelectedPathComponent(); if (treeNode != null) { Object userObject = treeNode.getUserObject(); // if (userObject instanceof MongoCollection) { // return (DefaultMutableTreeNode) treeNode.getParent(); // } if (userObject instanceof Database) { return treeNode; } } return null; } private DefaultMutableTreeNode getSelectedCollectionNode() { DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) databaseTree.getLastSelectedPathComponent(); if (treeNode != null) { Object userObject = treeNode.getUserObject(); if (userObject instanceof MongoCollection) { return treeNode; } } return null; } public ServerConfiguration getConfiguration() { DefaultMutableTreeNode serverNode = getSelectedServerNode(); if (serverNode == null) { return null; } return ((DatabaseServer) serverNode.getUserObject()).getConfiguration(); } public RedisDatabase getSelectedRedisDatabase() { DefaultMutableTreeNode databaseNode = getSelectedDatabaseNode(); if (databaseNode == null) { return null; } Object database = databaseNode.getUserObject(); if (!(database instanceof RedisDatabase)) { return null; } return (RedisDatabase) database; } public CouchbaseDatabase getSelectedCouchaseDatabase() { DefaultMutableTreeNode databaseNode = getSelectedDatabaseNode(); if (databaseNode == null) { return null; } Object database = databaseNode.getUserObject(); if (!(database instanceof CouchbaseDatabase)) { return null; } return (CouchbaseDatabase) database; } public MongoDatabase getSelectedMongoDatabase() { DefaultMutableTreeNode databaseNode = getSelectedDatabaseNode(); if (databaseNode == null) { return null; } Object database = databaseNode.getUserObject(); if (!(database instanceof MongoDatabase)) { return null; } return (MongoDatabase) databaseNode.getUserObject(); } public MongoCollection getSelectedCollection() { DefaultMutableTreeNode collectionNode = getSelectedCollectionNode(); if (collectionNode == null) { return null; } return (MongoCollection) collectionNode.getUserObject(); } public void loadRecords() { NoSqlDatabaseFileSystem.getInstance().openEditor(createNoSqlObjectFile()); } @NotNull private NoSqlDatabaseObjectFile createNoSqlObjectFile() { // TODO need to put in the database UI manager ServerConfiguration selectedConfiguration = getConfiguration(); if (DatabaseVendor.MONGO.equals(selectedConfiguration.getDatabaseVendor())) { return new MongoObjectFile(project, selectedConfiguration, getSelectedCollection()); } else if (DatabaseVendor.COUCHBASE.equals(selectedConfiguration.getDatabaseVendor())) { return new CouchbaseObjectFile(project, selectedConfiguration, getSelectedCouchaseDatabase()); } return new RedisObjectFile(project, selectedConfiguration, getSelectedRedisDatabase()); } public void dropCollection() {// TODO need to put in a customizer MongoClient databaseClient = (MongoClient) databaseVendorClientManager.get(DatabaseVendor.MONGO); databaseClient.dropCollection(getConfiguration(), getSelectedCollection()); reloadServerConfiguration(getSelectedServerNode(), true); } public void dropDatabase() {// TODO need to put in a customizer MongoClient databaseClient = (MongoClient) databaseVendorClientManager.get(DatabaseVendor.MONGO); databaseClient.dropDatabase(getConfiguration(), getSelectedMongoDatabase()); reloadServerConfiguration(getSelectedServerNode(), true); } private Tree createTree() { Tree tree = new Tree() { private final JLabel myLabel = new JLabel( String.format("
NoSql server list is empty

You may use to add configuration
", pluginSettingsUrl) ); @Override protected void paintComponent(Graphics g) { super.paintComponent(g); if (!getServerConfigurations().isEmpty()) return; myLabel.setFont(getFont()); myLabel.setBackground(getBackground()); myLabel.setForeground(getForeground()); Rectangle bounds = getBounds(); Dimension size = myLabel.getPreferredSize(); myLabel.setBounds(0, 0, size.width, size.height); int x = (bounds.width - size.width) / 2; Graphics g2 = g.create(bounds.x + x, bounds.y + 20, bounds.width, bounds.height); try { myLabel.paint(g2); } finally { g2.dispose(); } } }; tree.getEmptyText().clear(); tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); return tree; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/NoSqlServerTableModel.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql; import com.intellij.util.ui.ItemRemovable; import javax.swing.table.AbstractTableModel; import java.util.List; class NoSqlServerTableModel extends AbstractTableModel implements ItemRemovable { private final String[] columnNames = new String[]{ "Label", "Vendor", "URL", "Autoconnect" }; private final Class[] columnClasses = new Class[]{String.class, DatabaseVendor.class, String.class, Boolean.class}; private final List mongoServerConfigurations; public NoSqlServerTableModel(List mongoServerConfigurations) { this.mongoServerConfigurations = mongoServerConfigurations; } public String getColumnName(int column) { return columnNames[column]; } public Class getColumnClass(int column) { return columnClasses[column]; } public int getColumnCount() { return columnNames.length; } public int getRowCount() { return mongoServerConfigurations.size(); } @Override public boolean isCellEditable(int rowIndex, int columnIndex) { return false; } public Object getValueAt(int row, int column) { ServerConfiguration configuration = mongoServerConfigurations.get(row); switch (column) { case 0: { // "Label" column return configuration.getLabel(); } case 1: { // "Vendor" column return configuration.getDatabaseVendor(); } case 2: { // "URL" column return configuration.getServerUrl(); } case 3: { // "Autoconnect" column return configuration.isConnectOnIdeStartup(); } default: { throw new IllegalArgumentException(); } } } public void setValueAt(Object value, int row, int column) { ServerConfiguration configuration = mongoServerConfigurations.get(row); switch (column) { case 0: { configuration.setLabel((String) value); break; } case 1: { //do nothing ?? break; } case 2: { //do nothing url = serverHosts break; } case 3: { configuration.setConnectOnIdeStartup((Boolean) value); break; } default: { throw new IllegalArgumentException(); } } } public void removeRow(int index) { mongoServerConfigurations.remove(index); fireTableRowsDeleted(index, index); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/NoSqlTreeRenderer.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql; import com.intellij.icons.AllIcons; import com.intellij.ui.ColoredTreeCellRenderer; import com.intellij.ui.JBColor; import org.apache.commons.lang.StringUtils; import org.codinjutsu.tools.nosql.commons.model.Database; import org.codinjutsu.tools.nosql.commons.model.DatabaseServer; import org.codinjutsu.tools.nosql.commons.utils.GuiUtils; import org.codinjutsu.tools.nosql.mongo.model.MongoCollection; import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; public class NoSqlTreeRenderer extends ColoredTreeCellRenderer { private static final Icon DATABASE = GuiUtils.loadIcon("database.png"); private static final Icon MONGO_COLLECTION = AllIcons.Nodes.Folder; @Override public void customizeCellRenderer(@NotNull JTree mongoTree, Object value, boolean isSelected, boolean isExpanded, boolean isLeaf, int row, boolean focus) { DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; Object userObject = node.getUserObject(); if (userObject instanceof DatabaseServer) { DatabaseServer mongoServer = (DatabaseServer) userObject; String label = mongoServer.getLabel(); String host = mongoServer.getServerUrl(); append(StringUtils.isBlank(label) ? host : label); if (DatabaseServer.Status.OK.equals(mongoServer.getStatus())) { setToolTipText(host); setIcon(mongoServer.getConfiguration().getDatabaseVendor().icon); } else { setForeground(JBColor.RED); setToolTipText("Unable to connect"); } } else if (userObject instanceof Database) { Database noSqlDatabase = (Database) userObject; append(noSqlDatabase.getName()); setIcon(DATABASE); } else if (userObject instanceof MongoCollection) { MongoCollection mongoCollection = (MongoCollection) userObject; append(mongoCollection.getName()); setIcon(MONGO_COLLECTION); } } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/NoSqlWindowManager.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowAnchor; import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.ui.content.Content; import com.intellij.ui.content.ContentFactory; import org.codinjutsu.tools.nosql.commons.utils.GuiUtils; import javax.swing.*; public class NoSqlWindowManager { private static final Icon NOSQL_ICON = GuiUtils.loadIcon("nosql_13x13.png"); public static final String NOSQL_RUNNER = "NoSql Runner"; private static final String NOSQL_EXPLORER = "NoSql Explorer"; private final Project project; private final NoSqlExplorerPanel noSqlExplorerPanel; public static NoSqlWindowManager getInstance(Project project) { return ServiceManager.getService(project, NoSqlWindowManager.class); } public NoSqlWindowManager(Project project) { this.project = project; ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(project); noSqlExplorerPanel = new NoSqlExplorerPanel(project, DatabaseVendorClientManager.getInstance(project)); noSqlExplorerPanel.installActions(); Content nosqlExplorer = ContentFactory.SERVICE.getInstance().createContent(noSqlExplorerPanel, null, false); ToolWindow toolNoSqlExplorerWindow = toolWindowManager.registerToolWindow(NOSQL_EXPLORER, false, ToolWindowAnchor.RIGHT); toolNoSqlExplorerWindow.getContentManager().addContent(nosqlExplorer); toolNoSqlExplorerWindow.setIcon(NOSQL_ICON); } public void unregisterMyself() { ToolWindowManager.getInstance(project).unregisterToolWindow(NOSQL_RUNNER); ToolWindowManager.getInstance(project).unregisterToolWindow(NOSQL_EXPLORER); } public void apply() { ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { noSqlExplorerPanel.reloadAllServerConfigurations(); } }); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/SelectDatabaseVendorDialog.form ================================================
================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/SelectDatabaseVendorDialog.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql; import com.intellij.openapi.ui.ComboBox; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.ui.ColoredListCellRenderer; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; public class SelectDatabaseVendorDialog extends DialogWrapper { private JPanel mainPanel; private ComboBox databaseVendorCombobox; protected SelectDatabaseVendorDialog(Component parent) { super(parent, true); databaseVendorCombobox.setName("databaseVendorCombobox"); init(); } @Nullable @Override protected JComponent createCenterPanel() { return mainPanel; } @Override protected void init() { super.init(); initCombobox(); } private void initCombobox() { databaseVendorCombobox.setModel(new DefaultComboBoxModel(DatabaseVendor.values())); databaseVendorCombobox.setRenderer(new ColoredListCellRenderer() { @Override protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) { DatabaseVendor databaseVendor = (DatabaseVendor) value; setIcon(databaseVendor.icon); append(databaseVendor.name); } }); databaseVendorCombobox.setSelectedItem(DatabaseVendor.MONGO); } public DatabaseVendor getSelectedDatabaseVendor() { return (DatabaseVendor) databaseVendorCombobox.getSelectedItem(); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/ServerConfiguration.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql; import org.codinjutsu.tools.nosql.commons.model.AuthenticationSettings; public class ServerConfiguration implements Cloneable { private String label; private DatabaseVendor databaseVendor = DatabaseVendor.MONGO; private String serverUrl; private String userDatabase; private boolean connectOnIdeStartup = false; private String shellArgumentsLine; private String shellWorkingDir; private AuthenticationSettings authenticationSettings = new AuthenticationSettings(); public DatabaseVendor getDatabaseVendor() { return databaseVendor; } public void setDatabaseVendor(DatabaseVendor databaseVendor) { this.databaseVendor = databaseVendor; } public String getServerUrl() { return serverUrl; } public void setServerUrl(String serverUrl) { this.serverUrl = serverUrl; } public void setUserDatabase(String userDatabase) { this.userDatabase = userDatabase; } public String getUserDatabase() { return userDatabase; } public boolean isConnectOnIdeStartup() { return connectOnIdeStartup; } public void setConnectOnIdeStartup(boolean connectOnIdeStartup) { this.connectOnIdeStartup = connectOnIdeStartup; } public String getLabel() { return label; } public void setLabel(String label) { this.label = label; } public String getShellArgumentsLine() { return shellArgumentsLine; } public void setShellArgumentsLine(String shellArgumentsLine) { this.shellArgumentsLine = shellArgumentsLine; } public String getShellWorkingDir() { return shellWorkingDir; } public void setShellWorkingDir(String shellWorkingDir) { this.shellWorkingDir = shellWorkingDir; } public boolean isSingleServer() { return serverUrl.split(",").length == 1; } public void setAuthenticationSettings(AuthenticationSettings authenticationSettings) { this.authenticationSettings = authenticationSettings; } public AuthenticationSettings getAuthenticationSettings() { return authenticationSettings; } public ServerConfiguration clone() { try { return (ServerConfiguration) super.clone(); } catch (CloneNotSupportedException e) { return null; } } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ServerConfiguration that = (ServerConfiguration) o; if (connectOnIdeStartup != that.connectOnIdeStartup) return false; if (!label.equals(that.label)) return false; if (databaseVendor != that.databaseVendor) return false; if (!serverUrl.equals(that.serverUrl)) return false; if (userDatabase != null ? !userDatabase.equals(that.userDatabase) : that.userDatabase != null) return false; if (shellArgumentsLine != null ? !shellArgumentsLine.equals(that.shellArgumentsLine) : that.shellArgumentsLine != null) return false; if (shellWorkingDir != null ? !shellWorkingDir.equals(that.shellWorkingDir) : that.shellWorkingDir != null) return false; return !(authenticationSettings != null ? !authenticationSettings.equals(that.authenticationSettings) : that.authenticationSettings != null); } @Override public int hashCode() { int result = label.hashCode(); result = 31 * result + databaseVendor.hashCode(); result = 31 * result + serverUrl.hashCode(); result = 31 * result + (userDatabase != null ? userDatabase.hashCode() : 0); result = 31 * result + (connectOnIdeStartup ? 1 : 0); result = 31 * result + (shellArgumentsLine != null ? shellArgumentsLine.hashCode() : 0); result = 31 * result + (shellWorkingDir != null ? shellWorkingDir.hashCode() : 0); result = 31 * result + (authenticationSettings != null ? authenticationSettings.hashCode() : 0); return result; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/DatabaseUI.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons; import com.intellij.openapi.project.Project; import org.codinjutsu.tools.nosql.commons.view.AuthenticationView; import org.codinjutsu.tools.nosql.commons.view.NoSqlResultView; import org.codinjutsu.tools.nosql.commons.view.editor.NoSqlDatabaseObjectFile; public interface DatabaseUI { AuthenticationView createAythenticationView(); NoSqlResultView createResultPanel(Project project, NoSqlDatabaseObjectFile objectFile); } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/logic/ConfigurationException.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.logic; public class ConfigurationException extends RuntimeException { public ConfigurationException(String message) { super(message); } public ConfigurationException(Exception ex) { super(ex); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/logic/DatabaseClient.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.logic; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.codinjutsu.tools.nosql.commons.model.DatabaseServer; public interface DatabaseClient { void connect(ServerConfiguration serverConfiguration); void loadServer(DatabaseServer databaseServer); void cleanUpServers(); void registerServer(DatabaseServer databaseServer); ServerConfiguration defaultConfiguration(); } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/model/AuthenticationSettings.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.model; import java.util.HashMap; import java.util.Map; public class AuthenticationSettings { private String username = null; private String password = null; private Map extras = new HashMap<>(); public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Map getExtras() { return extras; } public void setExtras(Map extras) { this.extras = extras; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; AuthenticationSettings that = (AuthenticationSettings) o; if (username != null ? !username.equals(that.username) : that.username != null) return false; if (password != null ? !password.equals(that.password) : that.password != null) return false; return !(extras != null ? !extras.equals(that.extras) : that.extras != null); } @Override public int hashCode() { int result = username != null ? username.hashCode() : 0; result = 31 * result + (password != null ? password.hashCode() : 0); result = 31 * result + (extras != null ? extras.hashCode() : 0); return result; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/model/Database.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.model; public class Database { protected final String name; public Database(String name) { this.name = name; } public String getName() { return name; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/model/DatabaseServer.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.model; import org.codinjutsu.tools.nosql.ServerConfiguration; import java.util.LinkedList; import java.util.List; public class DatabaseServer { public enum Status { OK, LOADING, ERROR } private List databases = new LinkedList(); private final ServerConfiguration configuration; private Status status = Status.OK; public DatabaseServer(ServerConfiguration configuration) { this.configuration = configuration; } public String getServerUrl() { return configuration.getServerUrl(); } public String getLabel() { return configuration.getLabel(); } public void setDatabases(List databases) { this.databases = databases; } public boolean hasDatabases() { return !databases.isEmpty(); } public List getDatabases() { return databases; } public Status getStatus() { return status; } public void setStatus(Status status) { this.status = status; } public ServerConfiguration getConfiguration() { return configuration; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/style/StyleAttributesProvider.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.style; import com.intellij.ui.Gray; import com.intellij.ui.JBColor; import com.intellij.ui.SimpleTextAttributes; import java.awt.*; public class StyleAttributesProvider { private static final Color LIGNT_GREEN = new JBColor(new Color(0, 128, 0), new Color(165, 194, 97)); private static final Color LIGHT_GRAY = Gray._128; public static final Color KEY_COLOR = new JBColor(new Color(102, 14, 122), new Color(204, 120, 50)); public static final Color NUMBER_COLOR = JBColor.BLUE; private static final SimpleTextAttributes INDEX = new SimpleTextAttributes(Font.BOLD, JBColor.BLACK); private static final SimpleTextAttributes KEY_VALUE = new SimpleTextAttributes(Font.BOLD, KEY_COLOR); private static final SimpleTextAttributes INTEGER_TEXT_ATTRIBUTE = new SimpleTextAttributes(Font.PLAIN, NUMBER_COLOR); private static final SimpleTextAttributes BOOLEAN_TEXT_ATTRIBUTE = INTEGER_TEXT_ATTRIBUTE; private static final SimpleTextAttributes STRING_TEXT_ATTRIBUTE = new SimpleTextAttributes(Font.PLAIN, LIGNT_GREEN); private static final SimpleTextAttributes NULL_TEXT_ATTRIBUTE = new SimpleTextAttributes(Font.ITALIC, LIGHT_GRAY); private static final SimpleTextAttributes OBJECT_TEXT_ATTRIBUTE = new SimpleTextAttributes(Font.BOLD, LIGHT_GRAY); private static final SimpleTextAttributes OBJECT_ID_TEXT_ATTRIBUTE = INTEGER_TEXT_ATTRIBUTE; public static SimpleTextAttributes getIndexAttribute() { return INDEX; } public static SimpleTextAttributes getKeyValueAttribute() { return KEY_VALUE; } public static SimpleTextAttributes getNumberAttribute() { return INTEGER_TEXT_ATTRIBUTE; } public static SimpleTextAttributes getBooleanAttribute() { return BOOLEAN_TEXT_ATTRIBUTE; } public static SimpleTextAttributes getStringAttribute() { return STRING_TEXT_ATTRIBUTE; } public static SimpleTextAttributes getNullAttribute() { return NULL_TEXT_ATTRIBUTE; } public static SimpleTextAttributes getObjectAttribute() { return OBJECT_TEXT_ATTRIBUTE; } public static SimpleTextAttributes getObjectIdAttribute() { return OBJECT_ID_TEXT_ATTRIBUTE; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/utils/DateUtils.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.utils; import java.text.DateFormat; import java.util.Locale; import java.util.TimeZone; public class DateUtils { public static DateFormat utcDateTime(Locale locale) { DateFormat format = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG, locale); format.setTimeZone(TimeZone.getTimeZone("UTC")); return format; } public static DateFormat utcTime(Locale locale) { DateFormat format = DateFormat.getTimeInstance(DateFormat.MEDIUM, locale); format.setTimeZone(TimeZone.getTimeZone("UTC")); return format; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/utils/GuiUtils.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.utils; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.popup.Balloon; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.util.IconLoader; import com.intellij.ui.awt.RelativePoint; import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import java.awt.*; import java.net.URL; import java.util.Enumeration; public class GuiUtils { private static final String ICON_FOLDER = "/icons/"; public static Icon loadIcon(String iconFilename) { return IconLoader.findIcon(ICON_FOLDER + iconFilename); } public static Icon loadIcon(String iconFilename, String darkIconFilename) { String iconPath = ICON_FOLDER; if (isUnderDarcula()) { iconPath += darkIconFilename; } else { iconPath += iconFilename; } return IconLoader.findIcon(iconPath); } public static URL getIconResource(String iconFilename) { return GuiUtils.class.getResource(ICON_FOLDER + iconFilename); } public static void installActionGroupInToolBar(DefaultActionGroup actionGroup, JPanel toolBarPanel, ActionManager actionManager, String toolbarName, boolean horizontal) { if (actionManager == null) { return; } JComponent actionToolbar = ActionManager.getInstance().createActionToolbar(toolbarName, actionGroup, horizontal).getComponent(); toolBarPanel.add(actionToolbar, BorderLayout.CENTER); } public static boolean isUnderDarcula() { return UIManager.getLookAndFeel().getName().contains("Darcula"); } public static void runInSwingThread(Runnable runnable) { ApplicationManager.getApplication().invokeLater(runnable); } // Copy from private method com.intellij.util.ui.tree.TreeUtils#expand need to expand specifically some node instead of the whole tree public static void expand(@NotNull JTree tree, @NotNull TreePath path, int levels) { if (levels == 0) return; tree.expandPath(path); TreeNode node = (TreeNode) path.getLastPathComponent(); Enumeration children = node.children(); while (children.hasMoreElements()) { expand(tree, path.pathByAddingChild(children.nextElement()), levels - 1); } } public static Dimension enlargeWidth(Dimension preferredSize, double factor) { int enlargedWidth = new Double(preferredSize.width * factor).intValue(); return new Dimension(enlargedWidth, preferredSize.height); } public static void showNotification(final JComponent component, final MessageType info, final String message, final Balloon.Position position) { runInSwingThread(new Runnable() { @Override public void run() { JBPopupFactory.getInstance().createBalloonBuilder(new JLabel(message)) .setFillColor(info.getPopupBackground()) .createBalloon() .show(new RelativePoint(component, new Point(0, 0)), position); } }); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/utils/StringUtils.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.utils; public class StringUtils { private static final String ELLIPSIS = "..."; public static String abbreviateInCenter(String stringToAbbreviate, int length) { int halfLength = length / 2; int firstPartLastIndex = halfLength - ELLIPSIS.length(); int stringLength = stringToAbbreviate.length(); return String.format("%s%s%s", stringToAbbreviate.substring(0, firstPartLastIndex), ELLIPSIS, stringToAbbreviate.substring(stringLength - halfLength, stringLength)); } public static Number parseNumber(String number) { try { return Integer.parseInt(number); } catch (NumberFormatException ex) { ; //UGLY :( } try { return Long.parseLong(number); } catch (NumberFormatException ex) { ; //UGLY :( } return Double.parseDouble(number); } public static String[] explode(String key, String separator) { return org.apache.commons.lang.StringUtils.split(key, separator); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/view/AuthenticationView.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.view; import org.codinjutsu.tools.nosql.commons.model.AuthenticationSettings; import javax.swing.*; public interface AuthenticationView { JPanel getComponent(); AuthenticationSettings create(); void load(AuthenticationSettings settings); } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/view/ErrorPanel.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.view; import com.intellij.openapi.ui.Messages; import com.intellij.ui.HoverHyperlinkLabel; import com.intellij.ui.JBColor; import com.intellij.ui.components.JBLabel; import javax.swing.*; import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener; import java.awt.*; public class ErrorPanel extends JPanel { public ErrorPanel(final Exception ex) { setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); JBLabel comp = new JBLabel("Error during query execution:"); comp.setForeground(JBColor.RED); add(comp); final HoverHyperlinkLabel hoverHyperlinkLabel = new HoverHyperlinkLabel("more detail..."); hoverHyperlinkLabel.addHyperlinkListener(new HyperlinkListener() { @Override public void hyperlinkUpdate(HyperlinkEvent hyperlinkEvent) { if (hyperlinkEvent.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { Messages.showErrorDialog(ex.toString(), "Error During Query Execution"); } } }); add(Box.createRigidArea(new Dimension(10, 10))); add(hoverHyperlinkLabel); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/view/NoSqlResultView.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.view; import com.intellij.openapi.Disposable; import javax.swing.*; public abstract class NoSqlResultView extends JPanel implements Disposable { public abstract void showResults(); public abstract JPanel getResultPanel(); public abstract R getRecords(); public abstract void executeQuery(); } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/view/NoSqlTreeNode.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.view; import org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor; import javax.swing.tree.DefaultMutableTreeNode; public class NoSqlTreeNode extends DefaultMutableTreeNode { public NoSqlTreeNode(NodeDescriptor nodeDescriptor) { setUserObject(nodeDescriptor); } public NodeDescriptor getDescriptor() { return (NodeDescriptor) this.getUserObject(); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/view/ServerConfigurationPanel.form ================================================
================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/view/ServerConfigurationPanel.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.view; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.*; import com.intellij.openapi.util.Ref; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.RawCommandLineEditor; import org.apache.commons.lang.StringUtils; import org.codinjutsu.tools.nosql.DatabaseVendor; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.codinjutsu.tools.nosql.commons.logic.ConfigurationException; import org.codinjutsu.tools.nosql.commons.logic.DatabaseClient; import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class ServerConfigurationPanel extends JPanel { private JPanel rootPanel; private JTextField labelField; private JPanel authenticationContainer; private JTextField serverUrlField; private JTextField userDatabaseField; private JCheckBox autoConnectCheckBox; private JButton testConnectionButton; private JPanel mongoShellOptionsPanel; private TextFieldWithBrowseButton shellWorkingDirField; private RawCommandLineEditor shellArgumentsLineField; private JLabel databaseTipsLabel; private JLabel databaseVendorLabel; private final Project project; private final DatabaseClient databaseClient; private final DatabaseVendor databaseVendor; private final AuthenticationView authenticationView; public ServerConfigurationPanel(Project project, DatabaseVendor databaseVendor, DatabaseClient databaseClient, AuthenticationView authenticationView) { this.project = project; this.databaseClient = databaseClient; this.databaseVendor = databaseVendor; this.authenticationView = authenticationView; setLayout(new BorderLayout()); add(rootPanel, BorderLayout.CENTER); authenticationContainer.add(authenticationView.getComponent()); labelField.setName("labelField"); databaseVendorLabel.setName("databaseVendorLabel"); databaseVendorLabel.setText(databaseVendor.name); databaseVendorLabel.setIcon(databaseVendor.icon); databaseTipsLabel.setName("databaseTipsLabel"); databaseTipsLabel.setText(databaseVendor.tips); serverUrlField.setName("serverUrlField"); authenticationContainer.setBorder(IdeBorderFactory.createTitledBorder("Authentication settings", true)); userDatabaseField.setName("userDatabaseField"); userDatabaseField.setToolTipText("If your access is restricted to a specific database (e.g.: MongoLab), you can set it right here"); autoConnectCheckBox.setName("autoConnectField"); mongoShellOptionsPanel.setBorder(IdeBorderFactory.createTitledBorder("Mongo shell options", true)); shellArgumentsLineField.setDialogCaption("Mongo arguments"); testConnectionButton.setName("testConnection"); shellWorkingDirField.setText(null); initListeners(); } private void initListeners() { testConnectionButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { final Ref excRef = new Ref<>(); final ProgressManager progressManager = ProgressManager.getInstance(); progressManager.runProcessWithProgressSynchronously(new Runnable() { @Override public void run() { ServerConfiguration configuration = createServerConfigurationForTesting(); final ProgressIndicator progressIndicator = progressManager.getProgressIndicator(); if (progressIndicator != null) { progressIndicator.setText("Connecting to " + configuration.getServerUrl()); } try { databaseClient.connect(configuration); } catch (Exception ex) { excRef.set(ex); } } }, "Testing connection for " + databaseVendor.name, true, ServerConfigurationPanel.this.project); if (!excRef.isNull()) { Messages.showErrorDialog(rootPanel, excRef.get().getMessage(), "Connection test failed"); } else { Messages.showInfoMessage(rootPanel, "Connection test successful for " + databaseVendor.name, "Connection test successful"); } } }); } public void loadConfigurationData(ServerConfiguration configuration) { labelField.setText(configuration.getLabel()); serverUrlField.setText(configuration.getServerUrl()); userDatabaseField.setText(configuration.getUserDatabase()); shellArgumentsLineField.setText(configuration.getShellArgumentsLine()); shellWorkingDirField.setText(configuration.getShellWorkingDir()); autoConnectCheckBox.setSelected(configuration.isConnectOnIdeStartup()); authenticationView.load(configuration.getAuthenticationSettings()); } @NotNull private ServerConfiguration createServerConfigurationForTesting() { ServerConfiguration configuration = new ServerConfiguration(); configuration.setDatabaseVendor(databaseVendor); configuration.setServerUrl(getServerUrls()); configuration.setAuthenticationSettings(authenticationView.create()); configuration.setUserDatabase(getUserDatabase()); return configuration; } public void applyConfigurationData(ServerConfiguration configuration) { configuration.setLabel(getLabel()); configuration.setDatabaseVendor(databaseVendor); configuration.setServerUrl(getServerUrls()); configuration.setAuthenticationSettings(authenticationView.create()); configuration.setUserDatabase(getUserDatabase()); configuration.setShellArgumentsLine(getShellArgumentsLine()); configuration.setShellWorkingDir(getShellWorkingDir()); configuration.setConnectOnIdeStartup(isAutoConnect()); } public ValidationInfo validateInputs() { if (StringUtils.isEmpty(getLabel())) { return new ValidationInfo("Label should be set"); } String serverUrl = getServerUrls(); if (serverUrl == null) { return new ValidationInfo("URL(s) should be set"); } return null; } private void validateUrls() { String serverUrl = getServerUrls(); if (serverUrl == null) { throw new ConfigurationException("URL(s) should be set"); } for (String subServerUrl : serverUrl.split(",")) { String[] host_port = subServerUrl.split(":"); if (host_port.length < 2) { throw new ConfigurationException(String.format("URL '%s' format is incorrect. It should be 'host:port'", subServerUrl)); } try { Integer.valueOf(host_port[1].trim()); } catch (NumberFormatException e) { throw new ConfigurationException(String.format("Port in the URL '%s' is incorrect. It should be a number", subServerUrl)); } } } private String getLabel() { String label = labelField.getText(); if (StringUtils.isNotBlank(label)) { return label; } return null; } private String getServerUrls() { String serverUrl = serverUrlField.getText(); if (StringUtils.isNotBlank(serverUrl)) { return serverUrl; } return null; } private String getUserDatabase() { String userDatabase = userDatabaseField.getText(); if (StringUtils.isNotBlank(userDatabase)) { return userDatabase; } return null; } private String getShellArgumentsLine() { String shellArgumentsLine = shellArgumentsLineField.getText(); if (StringUtils.isNotBlank(shellArgumentsLine)) { return shellArgumentsLine; } return null; } private String getShellWorkingDir() { String shellWorkingDir = shellWorkingDirField.getText(); if (StringUtils.isNotBlank(shellWorkingDir)) { return shellWorkingDir; } return null; } private boolean isAutoConnect() { return autoConnectCheckBox.isSelected(); } private void createUIComponents() { shellWorkingDirField = new TextFieldWithBrowseButton(); FileChooserDescriptor fileChooserDescriptor = new FileChooserDescriptor(false, true, false, false, false, false); ComponentWithBrowseButton.BrowseFolderActionListener browseFolderActionListener = new ComponentWithBrowseButton.BrowseFolderActionListener<>("Shell working directory", null, shellWorkingDirField, null, fileChooserDescriptor, TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT); shellWorkingDirField.addBrowseFolderListener(null, browseFolderActionListener, false); shellWorkingDirField.setName("shellWorkingDirField"); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/view/ServerConfigurationPanelFactory.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.view; import com.intellij.openapi.project.Project; import org.codinjutsu.tools.nosql.DatabaseVendor; import org.codinjutsu.tools.nosql.DatabaseVendorClientManager; import org.codinjutsu.tools.nosql.DatabaseVendorUIManager; public class ServerConfigurationPanelFactory { private final Project project; private final DatabaseVendorClientManager databaseVendorClientManager; private final DatabaseVendorUIManager databaseVendorUIManager; public ServerConfigurationPanelFactory(Project project, DatabaseVendorClientManager databaseVendorClientManager, DatabaseVendorUIManager databaseVendorUIManager) { this.project = project; this.databaseVendorClientManager = databaseVendorClientManager; this.databaseVendorUIManager = databaseVendorUIManager; } public ServerConfigurationPanel create(DatabaseVendor databaseVendor) { return new ServerConfigurationPanel( this.project, databaseVendor, databaseVendorClientManager.get(databaseVendor), databaseVendorUIManager.get(databaseVendor).createAythenticationView() ); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/view/action/ExecuteQuery.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.view.action; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import org.codinjutsu.tools.nosql.commons.view.NoSqlResultView; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; public class ExecuteQuery extends AnAction { private final G resultView; public ExecuteQuery(G resultView) { super("Execute query", "Execute query with options", AllIcons.Actions.Execute); this.resultView = resultView; registerCustomShortcutSet(KeyEvent.VK_ENTER, InputEvent.CTRL_MASK, resultView); } @Override public void actionPerformed(AnActionEvent anActionEvent) { resultView.executeQuery(); } @Override public void update(AnActionEvent event) { event.getPresentation().setEnabled(resultView.getRecords() != null); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/view/action/NoSqlDatabaseConsoleAction.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.view.action; import com.intellij.execution.ExecutionException; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import org.apache.commons.lang.StringUtils; import org.codinjutsu.tools.nosql.DatabaseVendor; import org.codinjutsu.tools.nosql.NoSqlConfiguration; import org.codinjutsu.tools.nosql.NoSqlExplorerPanel; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.codinjutsu.tools.nosql.commons.utils.GuiUtils; import org.codinjutsu.tools.nosql.mongo.view.console.MongoConsoleRunner; import org.codinjutsu.tools.nosql.redis.view.console.RedisConsoleRunner; public class NoSqlDatabaseConsoleAction extends AnAction implements DumbAware { private final NoSqlExplorerPanel noSqlExplorerPanel; public NoSqlDatabaseConsoleAction(NoSqlExplorerPanel noSqlExplorerPanel) { super("DB Shell...", "DB Shell", GuiUtils.loadIcon("toolConsole.png")); this.noSqlExplorerPanel = noSqlExplorerPanel; } @Override public void update(AnActionEvent e) { final Project project = e.getData(PlatformDataKeys.PROJECT); boolean enabled = project != null; if (!enabled) { return; } NoSqlConfiguration configuration = NoSqlConfiguration.getInstance(project); e.getPresentation().setVisible( configuration != null && (StringUtils.isNotBlank(configuration.getShellPath(DatabaseVendor.MONGO)) || StringUtils.isNotBlank(configuration.getShellPath(DatabaseVendor.REDIS)) ) && noSqlExplorerPanel.getConfiguration() != null && noSqlExplorerPanel.getConfiguration().isSingleServer() ); e.getPresentation().setEnabled( noSqlExplorerPanel.getSelectedMongoDatabase() != null || noSqlExplorerPanel.getSelectedRedisDatabase() != null ); } @Override public void actionPerformed(AnActionEvent e) { final Project project = e.getData(PlatformDataKeys.PROJECT); assert project != null; runShell(project); } private void runShell(Project project) { ServerConfiguration configuration = noSqlExplorerPanel.getConfiguration(); if (DatabaseVendor.MONGO.equals(configuration.getDatabaseVendor())) { MongoConsoleRunner consoleRunner = new MongoConsoleRunner(project, configuration, noSqlExplorerPanel.getSelectedMongoDatabase()); try { consoleRunner.initAndRun(); } catch (ExecutionException e1) { throw new RuntimeException(e1); } } else if (DatabaseVendor.REDIS.equals(configuration.getDatabaseVendor())) { RedisConsoleRunner consoleRunner = new RedisConsoleRunner(project, configuration, noSqlExplorerPanel.getSelectedRedisDatabase()); try { consoleRunner.initAndRun(); } catch (ExecutionException e1) { throw new RuntimeException(e1); } } } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/view/action/OpenPluginSettingsAction.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.view.action; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.options.ShowSettingsUtil; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; public class OpenPluginSettingsAction extends AnAction implements DumbAware { public OpenPluginSettingsAction() { super("NoSql Settings", "Edit the NoSql settings for the current project", AllIcons.General.Settings); } @Override public void actionPerformed(AnActionEvent event) { showSettingsFor(getProject(event)); } private static void showSettingsFor(Project project) { ShowSettingsUtil.getInstance().showSettingsDialog(project, "NoSql Servers"); } private static Project getProject(AnActionEvent event) { DataContext dataContext = event.getDataContext(); return PlatformDataKeys.PROJECT.getData(dataContext); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/view/action/RefreshServerAction.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.view.action; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.project.DumbAware; import org.codinjutsu.tools.nosql.NoSqlExplorerPanel; import org.codinjutsu.tools.nosql.commons.utils.GuiUtils; import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; public class RefreshServerAction extends AnAction implements DumbAware { private static final Icon CONNECT_ICON = GuiUtils.loadIcon("connector.png", "connector_dark.png"); private static final Icon REFRESH_ICON = AllIcons.Actions.Refresh; private static final String REFRESH_TEXT = "Refresh this server"; private static final String CONNECT_TEXT = "Connect to this server"; private final NoSqlExplorerPanel noSqlExplorerPanel; public RefreshServerAction(NoSqlExplorerPanel noSqlExplorerPanel) { super(REFRESH_TEXT); this.noSqlExplorerPanel = noSqlExplorerPanel; } @Override public void actionPerformed(@NotNull AnActionEvent anActionEvent) { noSqlExplorerPanel.reloadServerConfiguration(noSqlExplorerPanel.getSelectedServerNode(), true); } @Override public void update(@NotNull AnActionEvent event) { DefaultMutableTreeNode selectedServerNode = noSqlExplorerPanel.getSelectedServerNode(); event.getPresentation().setVisible(selectedServerNode != null); if (selectedServerNode == null) { return; } boolean isConnected = selectedServerNode.getChildCount() > 0; event.getPresentation().setIcon(isConnected ? REFRESH_ICON : CONNECT_ICON); event.getPresentation().setText(isConnected ? REFRESH_TEXT : CONNECT_TEXT); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/view/action/ViewCollectionValuesAction.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.view.action; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.project.DumbAware; import org.codinjutsu.tools.nosql.NoSqlExplorerPanel; import javax.swing.*; public class ViewCollectionValuesAction extends AnAction implements DumbAware { private static Icon ICON = AllIcons.Nodes.DataSchema; private final NoSqlExplorerPanel noSqlExplorerPanel; public ViewCollectionValuesAction(NoSqlExplorerPanel noSqlExplorerPanel) { super("View collection content", "View collection content", ICON); this.noSqlExplorerPanel = noSqlExplorerPanel; } @Override public void actionPerformed(AnActionEvent anActionEvent) { noSqlExplorerPanel.loadRecords(); } public void update(AnActionEvent event) { event.getPresentation().setVisible(noSqlExplorerPanel.getSelectedCollection() != null || noSqlExplorerPanel.getSelectedRedisDatabase() != null || noSqlExplorerPanel.getSelectedCouchaseDatabase() != null); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/view/console/NoSqlConsoleView.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.view.console; import com.intellij.execution.console.LanguageConsoleImpl; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; import org.codinjutsu.tools.nosql.ServerConfiguration; public class NoSqlConsoleView extends LanguageConsoleImpl { public NoSqlConsoleView(Project project, String title, ServerConfiguration configuration) { super(project, title, StdFileTypes.PLAIN_TEXT.getLanguage()); setPrompt(String.format("%s> ", configuration.getServerUrl())); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/view/editor/NoSqlDatabaseDataEditor.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.view.editor; import com.intellij.codeHighlighting.BackgroundEditorHighlighter; import com.intellij.ide.structureView.StructureViewBuilder; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.FileEditorLocation; import com.intellij.openapi.fileEditor.FileEditorState; import com.intellij.openapi.fileEditor.FileEditorStateLevel; import com.intellij.openapi.util.UserDataHolderBase; import org.codinjutsu.tools.nosql.commons.view.NoSqlResultView; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.beans.PropertyChangeListener; public class NoSqlDatabaseDataEditor extends UserDataHolderBase implements FileEditor { private NoSqlResultView panel; private boolean disposed; public NoSqlDatabaseDataEditor(NoSqlResultView noSqlResultView) { panel = noSqlResultView; ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { panel.showResults(); } }); } @NotNull @Override public JComponent getComponent() { return isDisposed() ? new JPanel() : panel; } @Nullable @Override public JComponent getPreferredFocusedComponent() { return panel == null ? null : panel.getResultPanel(); } @NotNull @Override public String getName() { return "NoSql Data"; } @Override public void dispose() { if (!disposed) { panel.dispose(); panel = null; disposed = true; } } public boolean isDisposed() { return disposed; } @NotNull @Override public FileEditorState getState(@NotNull FileEditorStateLevel level) { return FileEditorState.INSTANCE; } // Unused methods @Override public void setState(@NotNull FileEditorState state) { } @Override public boolean isModified() { return false; } @Override public boolean isValid() { return true; } @Override public void selectNotify() { } @Override public void deselectNotify() { } @Override public void addPropertyChangeListener(@NotNull PropertyChangeListener listener) { } @Override public void removePropertyChangeListener(@NotNull PropertyChangeListener listener) { } @Nullable @Override public BackgroundEditorHighlighter getBackgroundHighlighter() { return null; } @Nullable @Override public FileEditorLocation getCurrentLocation() { return null; } @Nullable @Override public StructureViewBuilder getStructureViewBuilder() { return null; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/view/editor/NoSqlDatabaseDataEditorProvider.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.view.editor; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.FileEditorPolicy; import com.intellij.openapi.fileEditor.FileEditorProvider; import com.intellij.openapi.fileEditor.FileEditorState; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import org.codinjutsu.tools.nosql.DatabaseVendorUIManager; import org.codinjutsu.tools.nosql.commons.DatabaseUI; import org.jdom.Element; import org.jetbrains.annotations.NotNull; public class NoSqlDatabaseDataEditorProvider implements FileEditorProvider, ApplicationComponent, DumbAware { @Override public boolean accept(@NotNull Project project, @NotNull VirtualFile file) { return DatabaseVendorUIManager.getInstance(project).accept(file); } @NotNull @Override public FileEditor createEditor(@NotNull Project project, @NotNull VirtualFile file) { NoSqlDatabaseObjectFile objectFile = (NoSqlDatabaseObjectFile) file; DatabaseUI databaseUI = DatabaseVendorUIManager.getInstance(project).get(objectFile.getConfiguration().getDatabaseVendor()); if (databaseUI == null) { throw new IllegalStateException("Unsupported file"); } return new NoSqlDatabaseDataEditor(databaseUI.createResultPanel(project, objectFile)); } @Override public void disposeEditor(@NotNull FileEditor editor) { editor.dispose(); } @Override public void initComponent() { } @Override public void disposeComponent() { } @NotNull @Override public FileEditorState readState(@NotNull Element sourceElement, @NotNull Project project, @NotNull VirtualFile file) { return FileEditorState.INSTANCE; } @Override public void writeState(@NotNull FileEditorState state, @NotNull Project project, @NotNull Element targetElement) { } @NotNull @Override public String getEditorTypeId() { return "NoSqlData"; } @NotNull @Override public FileEditorPolicy getPolicy() { return FileEditorPolicy.HIDE_DEFAULT_EDITOR; } @NotNull @Override public String getComponentName() { return "NoSqlPlugin.NoSqlEditorProvider"; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/view/editor/NoSqlDatabaseFileSystem.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.view.editor; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileListener; import com.intellij.openapi.vfs.VirtualFileSystem; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.IOException; public class NoSqlDatabaseFileSystem extends VirtualFileSystem implements ApplicationComponent { private static final String PROTOCOL = "nosql"; public static NoSqlDatabaseFileSystem getInstance() { return ApplicationManager.getApplication().getComponent(NoSqlDatabaseFileSystem.class); } @NotNull @Override public String getComponentName() { return "NoSqlPlugin.NoSqlDatabaseFileSystem"; } @NotNull @Override public String getProtocol() { return PROTOCOL; } @Override public void initComponent() { } @Override public void disposeComponent() { } public void openEditor(final NoSqlDatabaseObjectFile databaseObjectFile) { FileEditorManager fileEditorManager = FileEditorManager.getInstance(databaseObjectFile.getProject()); fileEditorManager.openFile(databaseObjectFile, true); } // Unused methods @Nullable @Override public VirtualFile findFileByPath(@NotNull @NonNls String path) { return null; } @Override public void refresh(boolean asynchronous) { } @Nullable @Override public VirtualFile refreshAndFindFileByPath(@NotNull String path) { return null; } @Override public void addVirtualFileListener(@NotNull VirtualFileListener listener) { } @Override public void removeVirtualFileListener(@NotNull VirtualFileListener listener) { } @Override protected void deleteFile(Object requestor, @NotNull VirtualFile vFile) throws IOException { } @Override protected void moveFile(Object requestor, @NotNull VirtualFile vFile, @NotNull VirtualFile newParent) throws IOException { } @Override protected void renameFile(Object requestor, @NotNull VirtualFile vFile, @NotNull String newName) throws IOException { } @Override protected VirtualFile createChildFile(Object requestor, @NotNull VirtualFile vDir, @NotNull String fileName) throws IOException { return null; } @NotNull @Override protected VirtualFile createChildDirectory(Object requestor, @NotNull VirtualFile vDir, @NotNull String dirName) throws IOException { throw new UnsupportedOperationException("No file management in this plugin"); } @Override protected VirtualFile copyFile(Object requestor, @NotNull VirtualFile virtualFile, @NotNull VirtualFile newParent, @NotNull String copyName) throws IOException { return null; } @Override public boolean isReadOnly() { return false; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/view/editor/NoSqlDatabaseObjectFile.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.view.editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileSystem; import com.intellij.util.LocalTimeCounter; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public abstract class NoSqlDatabaseObjectFile extends VirtualFile { private final Project project; private final ServerConfiguration configuration; private final String name; private final long myModStamp; protected NoSqlDatabaseObjectFile(Project project, ServerConfiguration configuration, String name) { this.project = project; this.configuration = configuration; this.name = name; this.myModStamp = LocalTimeCounter.currentTime(); } @NotNull @Override public String getName() { return name; } @NotNull @Override public VirtualFileSystem getFileSystem() { return NoSqlDatabaseFileSystem.getInstance(); } @NotNull @Override public String getPath() { return name; } @Override public boolean isValid() { return true; } @Override public boolean isWritable() { return false; } @Override public boolean isDirectory() { return false; } public ServerConfiguration getConfiguration() { return configuration; } public Project getProject() { return project; } // Unused methods @Override public VirtualFile getParent() { return null; } @Override public VirtualFile[] getChildren() { return new VirtualFile[0]; } @NotNull @Override public OutputStream getOutputStream(Object requestor, long newModificationStamp, long newTimeStamp) throws IOException { throw new UnsupportedOperationException("NoSqlResultFile is read-only"); } @Override public long getModificationStamp() { return myModStamp; } @NotNull @Override public byte[] contentsToByteArray() throws IOException { return new byte[0]; } @Override public long getTimeStamp() { return 0; } @Override public long getLength() { return 0; } @Override public void refresh(boolean asynchronous, boolean recursive, @Nullable Runnable postRunnable) { } @Override public InputStream getInputStream() throws IOException { return null; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/view/nodedescriptor/NodeDescriptor.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.view.nodedescriptor; import com.intellij.ui.ColoredTableCellRenderer; import com.intellij.ui.ColoredTreeCellRenderer; public interface NodeDescriptor { int MAX_LENGTH = 150; void renderValue(ColoredTableCellRenderer cellRenderer, boolean isNodeExpanded); void renderNode(ColoredTreeCellRenderer cellRenderer); String getFormattedKey(); String getFormattedValue(); Object getValue(); void setValue(Object value); } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/view/renderer/KeyCellRenderer.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.view.renderer; import com.intellij.ui.ColoredTreeCellRenderer; import org.codinjutsu.tools.nosql.commons.view.NoSqlTreeNode; import org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor; import org.jetbrains.annotations.NotNull; import javax.swing.*; public class KeyCellRenderer extends ColoredTreeCellRenderer { @Override public void customizeCellRenderer(@NotNull JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { NodeDescriptor descriptor = ((NoSqlTreeNode) value).getDescriptor(); descriptor.renderNode(this); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/view/renderer/ValueCellRenderer.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.view.renderer; import com.intellij.ui.ColoredTableCellRenderer; import com.intellij.ui.treeStructure.treetable.TreeTable; import com.intellij.ui.treeStructure.treetable.TreeTableTree; import org.codinjutsu.tools.nosql.commons.view.NoSqlTreeNode; import javax.swing.*; import javax.swing.tree.TreePath; public class ValueCellRenderer extends ColoredTableCellRenderer { @Override protected void customizeCellRenderer(JTable table, Object value, boolean selected, boolean hasFocus, int row, int column) { TreeTableTree tree = ((TreeTable) table).getTree(); TreePath pathForRow = tree.getPathForRow(row); final NoSqlTreeNode node = (NoSqlTreeNode) pathForRow.getLastPathComponent(); node.getDescriptor().renderValue(this, tree.isExpanded(pathForRow)); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/view/table/CellEditor.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.view.table; import com.intellij.ui.treeStructure.treetable.TreeTable; import org.codinjutsu.tools.nosql.commons.view.NoSqlTreeNode; import javax.swing.*; import java.awt.*; public class CellEditor extends DefaultCellEditor { public CellEditor() { super(new JTextField()); } @Override public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { JTextField stringEditor = (JTextField) getComponent(); final NoSqlTreeNode jsonNode = (NoSqlTreeNode) ((TreeTable) table).getTree(). getPathForRow(row).getLastPathComponent(); stringEditor.setText(String.valueOf(jsonNode.getDescriptor().getValue())); return stringEditor; } @Override public Object getCellEditorValue() { return ((JTextField) getComponent()).getText(); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/commons/view/table/DateTimePicker.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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. */ /** * This is licensed under LGPL. License can be found here: http://www.gnu.org/licenses/lgpl-3.0.txt *

* This is provided as is. If you have questions please direct them to charlie.hubbard at gmail dot you know what. */ package org.codinjutsu.tools.nosql.commons.view.table; import com.intellij.ui.JBColor; import com.intellij.util.ui.UIUtil; import org.codinjutsu.tools.nosql.commons.style.StyleAttributesProvider; import org.codinjutsu.tools.nosql.commons.utils.DateUtils; import org.jdesktop.swingx.JXDatePicker; import org.jdesktop.swingx.JXMonthView; import org.jdesktop.swingx.calendar.SingleDaySelectionModel; import javax.swing.*; import javax.swing.text.DateFormatter; import javax.swing.text.DefaultFormatterFactory; import java.awt.*; import java.text.DateFormat; import java.text.ParseException; import java.util.*; public class DateTimePicker extends JXDatePicker { private static Color backgroundColor = JBColor.background(); private static Color foregroundColor = JBColor.foreground(); private static Color selectionBackgroundColor = UIUtil.getTableSelectionBackground(); private static Color selectionForegroundColor = UIUtil.getTableSelectionForeground(); private static Color monthForegroundColor = StyleAttributesProvider.NUMBER_COLOR; private static Color dayOfTheWeekForegroundColor = StyleAttributesProvider.KEY_COLOR; private static Color todayBackgroundColor = JBColor.WHITE; private JSpinner timeSpinner; private JPanel timePanel; private DateFormat timeFormat; public static DateTimePicker create() { DateTimePicker dateTimePicker = new DateTimePicker(); dateTimePicker.setFormats(DateUtils.utcDateTime(Locale.getDefault())); dateTimePicker.setTimeFormat(DateUtils.utcTime(Locale.getDefault())); dateTimePicker.setTimeZone(TimeZone.getTimeZone("UTC")); dateTimePicker.applyUIStyle(); return dateTimePicker; } private DateTimePicker() { super(null, Locale.getDefault()); getMonthView().setSelectionModel(new SingleDaySelectionModel()); } public void commitEdit() throws ParseException { commitTime(); super.commitEdit(); } public void cancelEdit() { super.cancelEdit(); setTimeSpinners(); } @Override public JPanel getLinkPanel() { super.getLinkPanel(); if (timePanel == null) { timePanel = createTimePanel(); } setTimeSpinners(); return timePanel; } @Override public Date getDate() { return super.getDate(); } private JPanel createTimePanel() { JPanel newPanel = new JPanel(); newPanel.setLayout(new FlowLayout()); SpinnerDateModel dateModel = new SpinnerDateModel(); timeSpinner = new JSpinner(dateModel); if (timeFormat == null) timeFormat = DateFormat.getTimeInstance(DateFormat.SHORT); updateTextFieldFormat(); newPanel.add(timeSpinner); return newPanel; } private void updateTextFieldFormat() { if (timeSpinner == null) return; JFormattedTextField tf = ((JSpinner.DefaultEditor) timeSpinner.getEditor()).getTextField(); DefaultFormatterFactory factory = (DefaultFormatterFactory) tf.getFormatterFactory(); DateFormatter formatter = (DateFormatter) factory.getDefaultFormatter(); // Change the date format to only show the hours formatter.setFormat(timeFormat); } private void commitTime() { Date date = getDate(); if (date != null) { Date time = (Date) timeSpinner.getValue(); GregorianCalendar timeCalendar = new GregorianCalendar(); timeCalendar.setTime(time); GregorianCalendar calendar = new GregorianCalendar(); calendar.setTime(date); calendar.set(Calendar.HOUR_OF_DAY, timeCalendar.get(Calendar.HOUR_OF_DAY)); calendar.set(Calendar.MINUTE, timeCalendar.get(Calendar.MINUTE)); calendar.set(Calendar.SECOND, timeCalendar.get(Calendar.SECOND)); calendar.set(Calendar.MILLISECOND, 0); Date newDate = calendar.getTime(); setDate(newDate); } } private void setTimeSpinners() { Date date = getDate(); if (date != null) { timeSpinner.setValue(date); } } public void setTimeFormat(DateFormat timeFormat) { this.timeFormat = timeFormat; updateTextFieldFormat(); } private void applyUIStyle() { JXMonthView monthView = getMonthView(); monthView.setMonthStringBackground(backgroundColor); monthView.setMonthStringForeground(monthForegroundColor); monthView.setSelectionBackground(selectionBackgroundColor); monthView.setSelectionForeground(selectionForegroundColor); monthView.setDaysOfTheWeekForeground(dayOfTheWeekForegroundColor); monthView.setBackground(backgroundColor); monthView.setForeground(foregroundColor); monthView.setTodayBackground(todayBackgroundColor); getLinkPanel().setBackground(backgroundColor); getLinkPanel().setForeground(foregroundColor); } public static void main(String[] args) { String[] ids = TimeZone.getAvailableIDs(); for (String id : ids) { if (!id.startsWith("Etc")) { TimeZone zone = TimeZone.getTimeZone(id); int offset = zone.getRawOffset() / 1000; int hour = offset / 3600; int minutes = (offset % 3600) / 60; System.out.println(String.format("(GMT%+d:%02d) %s", hour, minutes, id)); } } } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/couchbase/CouchbaseUI.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.couchbase; import com.intellij.openapi.project.Project; import org.codinjutsu.tools.nosql.commons.DatabaseUI; import org.codinjutsu.tools.nosql.commons.view.AuthenticationView; import org.codinjutsu.tools.nosql.commons.view.NoSqlResultView; import org.codinjutsu.tools.nosql.commons.view.editor.NoSqlDatabaseObjectFile; import org.codinjutsu.tools.nosql.couchbase.logic.CouchbaseClient; import org.codinjutsu.tools.nosql.couchbase.view.CouchbaseAuthenticationPanel; import org.codinjutsu.tools.nosql.couchbase.view.CouchbasePanel; import org.codinjutsu.tools.nosql.couchbase.view.editor.CouchbaseObjectFile; public class CouchbaseUI implements DatabaseUI { @Override public AuthenticationView createAythenticationView() { return new CouchbaseAuthenticationPanel(); } @Override public NoSqlResultView createResultPanel(Project project, NoSqlDatabaseObjectFile objectFile) { CouchbaseObjectFile couchbaseObjectFile = (CouchbaseObjectFile) objectFile; return new CouchbasePanel(project, CouchbaseClient.getInstance(project), couchbaseObjectFile.getConfiguration(), couchbaseObjectFile.getDatabase()); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/couchbase/logic/CouchbaseClient.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.couchbase.logic; import com.couchbase.client.java.Bucket; import com.couchbase.client.java.Cluster; import com.couchbase.client.java.ConnectionString; import com.couchbase.client.java.CouchbaseCluster; import com.couchbase.client.java.cluster.BucketSettings; import com.couchbase.client.java.cluster.ClusterManager; import com.couchbase.client.java.document.json.JsonObject; import com.couchbase.client.java.env.DefaultCouchbaseEnvironment; import com.couchbase.client.java.query.N1qlQuery; import com.couchbase.client.java.query.N1qlQueryResult; import com.couchbase.client.java.query.N1qlQueryRow; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.codinjutsu.tools.nosql.DatabaseVendor; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.codinjutsu.tools.nosql.commons.logic.ConfigurationException; import org.codinjutsu.tools.nosql.commons.logic.DatabaseClient; import org.codinjutsu.tools.nosql.commons.model.AuthenticationSettings; import org.codinjutsu.tools.nosql.commons.model.Database; import org.codinjutsu.tools.nosql.commons.model.DatabaseServer; import org.codinjutsu.tools.nosql.couchbase.model.CouchbaseDatabase; import org.codinjutsu.tools.nosql.couchbase.model.CouchbaseQuery; import org.codinjutsu.tools.nosql.couchbase.model.CouchbaseResult; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import java.util.concurrent.TimeUnit; import static com.couchbase.client.java.query.Select.select; import static com.couchbase.client.java.query.dsl.Expression.i; public class CouchbaseClient implements DatabaseClient { public static CouchbaseClient getInstance(Project project) { return ServiceManager.getService(project, CouchbaseClient.class); } @Override public void connect(ServerConfiguration serverConfiguration) { CouchbaseCluster cluster = CouchbaseCluster.create(serverConfiguration.getServerUrl()); String userDatabase = serverConfiguration.getUserDatabase(); Bucket bucket = null; try { if (StringUtils.isEmpty(userDatabase)) { bucket = cluster.openBucket(); } else { bucket = cluster.openBucket(userDatabase); } } catch (Exception ex) { throw new ConfigurationException(ex); } finally { if (bucket != null) { bucket.close(); } cluster.disconnect(); } } @Override public void loadServer(DatabaseServer databaseServer) { Cluster cluster = CouchbaseCluster.create(databaseServer.getConfiguration().getServerUrl()); AuthenticationSettings authenticationSettings = databaseServer.getConfiguration().getAuthenticationSettings(); ClusterManager clusterManager = cluster.clusterManager(authenticationSettings.getUsername(), authenticationSettings.getPassword()); List couchbaseDatabases = new LinkedList<>(); String userBucket = databaseServer.getConfiguration().getUserDatabase(); if (StringUtils.isNotBlank(userBucket)) { BucketSettings bucketSettings = clusterManager.getBucket(userBucket); couchbaseDatabases.add(new CouchbaseDatabase(bucketSettings.name())); } else { List buckets = clusterManager.getBuckets(); for (BucketSettings bucketSettings : buckets) { CouchbaseDatabase database = new CouchbaseDatabase(bucketSettings.name()); couchbaseDatabases.add(database); } } databaseServer.setDatabases(couchbaseDatabases); cluster.disconnect(); } @Override public void cleanUpServers() { } @Override public void registerServer(DatabaseServer databaseServer) { } @Override public ServerConfiguration defaultConfiguration() { ServerConfiguration configuration = new ServerConfiguration(); configuration.setDatabaseVendor(DatabaseVendor.COUCHBASE); configuration.setServerUrl("localhost"); configuration.setAuthenticationSettings(new AuthenticationSettings()); return configuration; } public CouchbaseResult loadRecords(ServerConfiguration configuration, CouchbaseDatabase database, CouchbaseQuery couchbaseQuery) { Cluster cluster = CouchbaseCluster.create(DefaultCouchbaseEnvironment .builder() .queryEnabled(true) .build(), configuration.getServerUrl()); // AuthenticationSettings authenticationSettings = configuration.getAuthenticationSettings(); // ClusterManager clusterManager = cluster.clusterManager(authenticationSettings.getUsername(), authenticationSettings.getPassword()); Bucket beerBucket = cluster.openBucket(database.getName(), 10, TimeUnit.SECONDS); N1qlQueryResult queryResult = beerBucket.query(N1qlQuery.simple(select("*").from(i(database.getName())).limit(couchbaseQuery.getLimit()))); //TODO dirty zone :( CouchbaseResult result = new CouchbaseResult(database.getName()); List errors = queryResult.errors(); if (!errors.isEmpty()) { cluster.disconnect(); result.addErrors(errors); return result; } for (N1qlQueryRow row : queryResult.allRows()) { result.add(row.value()); } cluster.disconnect(); return result; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/couchbase/model/CouchbaseDatabase.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.couchbase.model; import org.codinjutsu.tools.nosql.commons.model.Database; public class CouchbaseDatabase extends Database { public CouchbaseDatabase(String name) { super(name); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/couchbase/model/CouchbaseQuery.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.couchbase.model; public class CouchbaseQuery { private final int limit; public CouchbaseQuery(int limit) { this.limit = limit; } public int getLimit() { return limit; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/couchbase/model/CouchbaseResult.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.couchbase.model; import com.couchbase.client.java.document.json.JsonObject; import java.util.LinkedList; import java.util.List; public class CouchbaseResult { private final List jsonObjects = new LinkedList<>(); private final List errors = new LinkedList<>(); private final String name; public CouchbaseResult(String name) { this.name = name; } public void add(JsonObject jsonObject) { this.jsonObjects.add(jsonObject); } public void addErrors(List errors) { this.errors.addAll(errors); } public String getName() { return null; } public List getRecords() { return jsonObjects; } public boolean hasErrors() { return !errors.isEmpty(); } public List getErrors() { return errors; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/couchbase/view/CouchbaseAuthenticationPanel.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.couchbase.view; import org.apache.commons.lang.StringUtils; import org.codinjutsu.tools.nosql.commons.model.AuthenticationSettings; import org.codinjutsu.tools.nosql.commons.view.AuthenticationView; import javax.swing.*; public class CouchbaseAuthenticationPanel implements AuthenticationView { private JTextField usernameField; private JPasswordField passwordField; private JPanel mainPanel; public CouchbaseAuthenticationPanel() { usernameField.setName("usernameField"); passwordField.setName("passwordField"); } @Override public JPanel getComponent() { return mainPanel; } @Override public AuthenticationSettings create() { AuthenticationSettings authenticationSettings = new AuthenticationSettings(); authenticationSettings.setUsername(getUsername()); authenticationSettings.setPassword(getPassword()); return authenticationSettings; } @Override public void load(AuthenticationSettings settings) { usernameField.setText(settings.getUsername()); passwordField.setText(settings.getPassword()); } private String getUsername() { String username = usernameField.getText(); if (StringUtils.isNotBlank(username)) { return username; } return null; } private String getPassword() { char[] password = passwordField.getPassword(); if (password != null && password.length != 0) { return String.valueOf(password); } return null; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/couchbase/view/CouchbasePanel.form ================================================

================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/couchbase/view/CouchbasePanel.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.couchbase.view; import com.intellij.icons.AllIcons; import com.intellij.ide.CommonActionsManager; import com.intellij.ide.TreeExpander; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.ActionToolbar; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.LoadingDecorator; import com.intellij.openapi.util.Disposer; import com.intellij.ui.NumberDocument; import com.intellij.ui.components.JBLabel; import com.intellij.ui.components.JBScrollPane; import com.intellij.ui.components.panels.NonOpaquePanel; import com.intellij.ui.treeStructure.treetable.TreeTableTree; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.tree.TreeUtil; import org.apache.commons.lang.StringUtils; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.codinjutsu.tools.nosql.commons.utils.GuiUtils; import org.codinjutsu.tools.nosql.commons.view.ErrorPanel; import org.codinjutsu.tools.nosql.commons.view.NoSqlResultView; import org.codinjutsu.tools.nosql.commons.view.NoSqlTreeNode; import org.codinjutsu.tools.nosql.commons.view.action.ExecuteQuery; import org.codinjutsu.tools.nosql.couchbase.logic.CouchbaseClient; import org.codinjutsu.tools.nosql.couchbase.model.CouchbaseDatabase; import org.codinjutsu.tools.nosql.couchbase.model.CouchbaseQuery; import org.codinjutsu.tools.nosql.couchbase.model.CouchbaseResult; import org.codinjutsu.tools.nosql.mongo.view.JsonTreeTableView; import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; public class CouchbasePanel extends NoSqlResultView { private JPanel mainPanel; private JPanel toolBarPanel; private JPanel containerPanel; private JPanel errorPanel; private JPanel resultPanel; private final LoadingDecorator loadingDecorator; private final JTextField rowLimitField = new JTextField(""); private final Project project; private final CouchbaseClient couchbaseClient; private final ServerConfiguration configuration; private final CouchbaseDatabase database; private CouchbaseResult couchbaseResult; private JsonTreeTableView resultTableView; public CouchbasePanel(Project project, CouchbaseClient couchbaseClient, ServerConfiguration configuration, CouchbaseDatabase database) { this.project = project; this.couchbaseClient = couchbaseClient; this.configuration = configuration; this.database = database; this.resultPanel = new JPanel(new BorderLayout()); loadingDecorator = new LoadingDecorator(resultPanel, this, 0); containerPanel.add(loadingDecorator.getComponent()); initToolbar(); setLayout(new BorderLayout()); add(mainPanel); } private void loadAndDisplayResults(final int limit) throws Exception { couchbaseResult = couchbaseClient.loadRecords(configuration, database, new CouchbaseQuery(limit)); if (couchbaseResult.hasErrors()) { throw new Exception(StringUtils.join(couchbaseResult.getErrors(), " ")); //TODO need to improve it } updateResultTableTree(couchbaseResult); } void updateResultTableTree(CouchbaseResult couchbaseResult) { NoSqlTreeNode rootNode = CouchbaseTreeModel.buildTree(couchbaseResult); resultTableView = new JsonTreeTableView(rootNode, JsonTreeTableView.COLUMNS_FOR_READING); resultTableView.setName("resultTreeTable"); resultPanel.invalidate(); resultPanel.removeAll(); resultPanel.add(new JBScrollPane(resultTableView)); resultPanel.validate(); } private void initToolbar() { toolBarPanel.setLayout(new BorderLayout()); rowLimitField.setColumns(5); rowLimitField.setDocument(new NumberDocument()); rowLimitField.setText("100"); JPanel rowLimitPanel = new NonOpaquePanel(); rowLimitPanel.add(new JLabel("Row limit:"), BorderLayout.WEST); rowLimitPanel.add(rowLimitField, BorderLayout.CENTER); rowLimitPanel.add(Box.createHorizontalStrut(5), BorderLayout.EAST); toolBarPanel.add(rowLimitPanel, BorderLayout.WEST); addCommonsActions(); } protected void addCommonsActions() { final TreeExpander treeExpander = new TreeExpander() { @Override public void expandAll() { CouchbasePanel.this.expandAll(); } @Override public boolean canExpand() { return true; } @Override public void collapseAll() { CouchbasePanel.this.collapseAll(); } @Override public boolean canCollapse() { return true; } }; CommonActionsManager actionsManager = CommonActionsManager.getInstance(); final AnAction expandAllAction = actionsManager.createExpandAllAction(treeExpander, resultPanel); final AnAction collapseAllAction = actionsManager.createCollapseAllAction(treeExpander, resultPanel); Disposer.register(this, new Disposable() { @Override public void dispose() { collapseAllAction.unregisterCustomShortcutSet(resultPanel); expandAllAction.unregisterCustomShortcutSet(resultPanel); } }); DefaultActionGroup actionResultGroup = new DefaultActionGroup("CouchbaseResultGroup", true); actionResultGroup.add(new ExecuteQuery<>(this)); actionResultGroup.addSeparator(); actionResultGroup.add(expandAllAction); actionResultGroup.add(collapseAllAction); ActionToolbar actionToolBar = ActionManager.getInstance().createActionToolbar("CouchbaseResultGroupActions", actionResultGroup, true); actionToolBar.setLayoutPolicy(ActionToolbar.AUTO_LAYOUT_POLICY); JComponent actionToolBarComponent = actionToolBar.getComponent(); actionToolBarComponent.setBorder(null); actionToolBarComponent.setOpaque(false); toolBarPanel.add(actionToolBarComponent, BorderLayout.CENTER); } private int getLimit() { return Integer.parseInt(rowLimitField.getText()); } void expandAll() { TreeUtil.expandAll(resultTableView.getTree()); } void collapseAll() { TreeTableTree tree = resultTableView.getTree(); TreeUtil.collapseAll(tree, 1); } @Override public void showResults() { executeQuery(); } @Override public JPanel getResultPanel() { return resultPanel; } @Override public CouchbaseDatabase getRecords() { return database; } @Override public void executeQuery() { ProgressManager.getInstance().run(new Task.Backgroundable(project, "Executing query", true) { //TODO need to abstract this method @Override public void run(@NotNull final ProgressIndicator indicator) { try { loadAndDisplayResults(getLimit()); } catch (final Exception ex) { GuiUtils.runInSwingThread(new Runnable() { @Override public void run() { errorPanel.invalidate(); errorPanel.removeAll(); errorPanel.add(new ErrorPanel(ex), BorderLayout.CENTER); errorPanel.validate(); errorPanel.setVisible(true); } }); } finally { GuiUtils.runInSwingThread(new Runnable() { @Override public void run() { loadingDecorator.stopLoading(); } }); } } }); } @Override public void dispose() { } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/couchbase/view/CouchbaseTreeModel.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.couchbase.view; import com.couchbase.client.java.document.json.JsonArray; import com.couchbase.client.java.document.json.JsonObject; import org.codinjutsu.tools.nosql.commons.view.NoSqlTreeNode; import org.codinjutsu.tools.nosql.couchbase.model.CouchbaseResult; import org.codinjutsu.tools.nosql.couchbase.view.nodedescriptor.CouchbaseKeyValueDescriptor; import org.codinjutsu.tools.nosql.couchbase.view.nodedescriptor.CouchbaseResultDescriptor; import org.codinjutsu.tools.nosql.couchbase.view.nodedescriptor.CouchbaseValueDescriptor; import javax.swing.tree.DefaultTreeModel; public class CouchbaseTreeModel extends DefaultTreeModel { public CouchbaseTreeModel(CouchbaseResult result) { super(buildTree(result)); } public static NoSqlTreeNode buildTree(CouchbaseResult couchbaseResult) { NoSqlTreeNode resultTreeNode = new NoSqlTreeNode(new CouchbaseResultDescriptor(couchbaseResult.getName())); for (JsonObject record : couchbaseResult.getRecords()) { processRecord(resultTreeNode, record); } return resultTreeNode; } private static void processRecord(NoSqlTreeNode parentNode, JsonObject record) { for (String key : record.getNames()) { Object value = record.get(key); NoSqlTreeNode currentNode = new NoSqlTreeNode(CouchbaseKeyValueDescriptor.createDescriptor(key, value)); if (value instanceof JsonArray) { processRecordListValues(currentNode, (JsonArray) value); } else if (value instanceof JsonObject) { processRecord(currentNode, (JsonObject) value); } parentNode.add(currentNode); } } private static void processRecordListValues(NoSqlTreeNode parentNode, JsonArray values) { int index = 0; for (Object value : values) { NoSqlTreeNode currentValueNode = new NoSqlTreeNode(CouchbaseValueDescriptor.createDescriptor(index++, value)); if (value instanceof JsonArray) { processRecordListValues(currentValueNode, (JsonArray) value); } else if (value instanceof JsonObject) { processRecord(currentValueNode, (JsonObject) value); } parentNode.add(currentValueNode); } } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/couchbase/view/couchbaseAuthenticationPanel.form ================================================
================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/couchbase/view/editor/CouchbaseFakeFileType.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.couchbase.view.editor; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.ex.FakeFileType; import com.intellij.openapi.vfs.VirtualFile; import org.codinjutsu.tools.nosql.commons.utils.GuiUtils; import org.jetbrains.annotations.NotNull; import javax.swing.*; public class CouchbaseFakeFileType extends FakeFileType { private static final Icon ICON = GuiUtils.loadIcon("couchbase.png"); private static final String NAME = "COUCHBASE"; public static final FileType INSTANCE = new CouchbaseFakeFileType(); @Override public Icon getIcon() { return ICON; } @Override public boolean isMyFileType(VirtualFile file) { return false; } @NotNull @Override public String getDefaultExtension() { return "json"; } @NotNull @Override public String getName() { return NAME; } @NotNull @Override public String getDescription() { return NAME; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/couchbase/view/editor/CouchbaseObjectFile.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.couchbase.view.editor; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.project.Project; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.codinjutsu.tools.nosql.commons.view.editor.NoSqlDatabaseObjectFile; import org.codinjutsu.tools.nosql.couchbase.model.CouchbaseDatabase; import org.jetbrains.annotations.NotNull; public class CouchbaseObjectFile extends NoSqlDatabaseObjectFile { private final CouchbaseDatabase couchbaseDatabase; public CouchbaseObjectFile(Project project, ServerConfiguration configuration, CouchbaseDatabase database) { super(project, configuration, String.format("%s/%s", configuration.getLabel(), database.getName())); this.couchbaseDatabase = database; } @NotNull public FileType getFileType() { return CouchbaseFakeFileType.INSTANCE; } public CouchbaseDatabase getDatabase() { return couchbaseDatabase; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/couchbase/view/nodedescriptor/CouchbaseKeyValueDescriptor.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.couchbase.view.nodedescriptor; import com.couchbase.client.java.document.json.JsonArray; import com.couchbase.client.java.document.json.JsonObject; import com.intellij.ui.ColoredTableCellRenderer; import com.intellij.ui.ColoredTreeCellRenderer; import com.intellij.ui.SimpleTextAttributes; import org.codinjutsu.tools.nosql.commons.style.StyleAttributesProvider; import org.codinjutsu.tools.nosql.commons.utils.StringUtils; import org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor; public class CouchbaseKeyValueDescriptor implements NodeDescriptor { protected static final String TO_STRING_TEMPLATE = "\"%s\" : %s"; protected final String key; protected final Object value; private final SimpleTextAttributes valueTextAttributes; public static CouchbaseKeyValueDescriptor createDescriptor(String key, Object value) { if (value == null) { return new CouchbaseKeyNullValueDescriptor(key); } if (value instanceof String) { return new CouchbaseKeyStringValueDescriptor(key, (String) value); } SimpleTextAttributes textAttributes = StyleAttributesProvider.getStringAttribute(); if (value instanceof Boolean) { textAttributes = StyleAttributesProvider.getBooleanAttribute(); } else if (value instanceof Number) { textAttributes = StyleAttributesProvider.getNumberAttribute(); } else if (value instanceof JsonObject || value instanceof JsonArray) { textAttributes = StyleAttributesProvider.getObjectAttribute(); } return new CouchbaseKeyValueDescriptor(key, value, textAttributes); } private CouchbaseKeyValueDescriptor(String key, Object value, SimpleTextAttributes valueTextAttributes) { this.key = key; this.value = value; this.valueTextAttributes = valueTextAttributes; } public void renderValue(ColoredTableCellRenderer cellRenderer, boolean isNodeExpanded) { if (!isNodeExpanded) { cellRenderer.append(getValueAndAbbreviateIfNecessary(), valueTextAttributes); } } public void renderNode(ColoredTreeCellRenderer cellRenderer) { cellRenderer.append(getFormattedKey(), StyleAttributesProvider.getKeyValueAttribute()); } public String getFormattedKey() { return key; } public String getFormattedValue() { return getValueAndAbbreviateIfNecessary(); } public String getKey() { return key; } public Object getValue() { return value; } public void setValue(Object value) { } @Override public String toString() { return String.format(TO_STRING_TEMPLATE, key, value); } protected String getValueAndAbbreviateIfNecessary() { String stringifiedValue = value.toString(); if (stringifiedValue.length() > MAX_LENGTH) { return StringUtils.abbreviateInCenter(stringifiedValue, MAX_LENGTH); } return stringifiedValue; } private static class CouchbaseKeyNullValueDescriptor extends CouchbaseKeyValueDescriptor { private CouchbaseKeyNullValueDescriptor(String key) { super(key, null, StyleAttributesProvider.getNullAttribute()); } protected String getValueAndAbbreviateIfNecessary() { return "null"; } } private static class CouchbaseKeyStringValueDescriptor extends CouchbaseKeyValueDescriptor { private static final String STRING_SURROUNDED = "\"%s\""; private static final String TO_STRING_FOR_STRING_VALUE_TEMPLATE = "\"%s\" : \"%s\""; private CouchbaseKeyStringValueDescriptor(String key, String value) { super(key, value, StyleAttributesProvider.getStringAttribute()); } @Override protected String getValueAndAbbreviateIfNecessary() { return String.format(STRING_SURROUNDED, value); } @Override public String toString() { return String.format(TO_STRING_FOR_STRING_VALUE_TEMPLATE, key, value); } } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/couchbase/view/nodedescriptor/CouchbaseResultDescriptor.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.couchbase.view.nodedescriptor; import com.intellij.ui.ColoredTableCellRenderer; import com.intellij.ui.ColoredTreeCellRenderer; import org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor; public class CouchbaseResultDescriptor implements NodeDescriptor { private final String formattedText; public CouchbaseResultDescriptor(String collectionName) { formattedText = String.format("results of '%s'", collectionName); } public CouchbaseResultDescriptor() { this(""); } public void renderValue(ColoredTableCellRenderer cellRenderer, boolean isNodeExpanded) { } public void renderNode(ColoredTreeCellRenderer cellRenderer) { } public String getFormattedKey() { return formattedText; } @Override public String getFormattedValue() { return ""; } @Override public String getValue() { return null; } @Override public void setValue(Object value) { } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/couchbase/view/nodedescriptor/CouchbaseValueDescriptor.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.couchbase.view.nodedescriptor; import com.intellij.ui.ColoredTableCellRenderer; import com.intellij.ui.ColoredTreeCellRenderer; import com.intellij.ui.SimpleTextAttributes; import org.codinjutsu.tools.nosql.commons.style.StyleAttributesProvider; import org.codinjutsu.tools.nosql.commons.utils.StringUtils; import org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor; public class CouchbaseValueDescriptor implements NodeDescriptor { private final int index; protected Object value; private final SimpleTextAttributes valueTextAttributes; public static CouchbaseValueDescriptor createDescriptor(int index, Object value) { if (value instanceof String) { return new CouchbaseStringValueDescriptor(index, (String) value); } return new CouchbaseValueDescriptor(index, value, StyleAttributesProvider.getStringAttribute()); } private CouchbaseValueDescriptor(int index, Object value, SimpleTextAttributes valueTextAttributes) { this.index = index; this.value = value; this.valueTextAttributes = valueTextAttributes; } public void renderValue(ColoredTableCellRenderer cellRenderer, boolean isNodeExpanded) { if (!isNodeExpanded) { cellRenderer.append(getFormattedValue(), valueTextAttributes); } } public void renderNode(ColoredTreeCellRenderer cellRenderer) { cellRenderer.append(getFormattedKey(), StyleAttributesProvider.getIndexAttribute()); } public String getFormattedKey() { return String.format("[%s]", index); } public String getFormattedValue() { return String.format("%s", getValueAndAbbreviateIfNecessary()); } protected String getValueAndAbbreviateIfNecessary() { String stringifiedValue = value.toString(); if (stringifiedValue.length() > MAX_LENGTH) { return StringUtils.abbreviateInCenter(stringifiedValue, MAX_LENGTH); } return stringifiedValue; } public Object getValue() { return value; } public void setValue(Object value) { this.value = value; } @Override public String toString() { return value.toString(); } private static class CouchbaseStringValueDescriptor extends CouchbaseValueDescriptor { private CouchbaseStringValueDescriptor(int index, String value) { super(index, value, StyleAttributesProvider.getStringAttribute()); } @Override public String getFormattedValue() { return String.format("\"%s\"", getValueAndAbbreviateIfNecessary()); } } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/MongoUI.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo; import com.intellij.openapi.project.Project; import org.codinjutsu.tools.nosql.commons.DatabaseUI; import org.codinjutsu.tools.nosql.commons.view.AuthenticationView; import org.codinjutsu.tools.nosql.commons.view.NoSqlResultView; import org.codinjutsu.tools.nosql.commons.view.editor.NoSqlDatabaseObjectFile; import org.codinjutsu.tools.nosql.mongo.logic.MongoClient; import org.codinjutsu.tools.nosql.mongo.view.MongoAuthenticationPanel; import org.codinjutsu.tools.nosql.mongo.view.MongoPanel; import org.codinjutsu.tools.nosql.mongo.view.editor.MongoObjectFile; public class MongoUI implements DatabaseUI { @Override public AuthenticationView createAythenticationView() { return new MongoAuthenticationPanel(); } @Override public NoSqlResultView createResultPanel(Project project, NoSqlDatabaseObjectFile objectFile) { MongoObjectFile mongoObjectFile = (MongoObjectFile) objectFile; return new MongoPanel(project, MongoClient.getInstance(project), mongoObjectFile.getConfiguration(), mongoObjectFile.getCollection()); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/MongoUtils.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.codinjutsu.tools.nosql.mongo.model.MongoDatabase; public class MongoUtils { private MongoUtils() { } public static String buildMongoUrl(ServerConfiguration serverConfiguration, MongoDatabase database) { return String.format("%s/%s", serverConfiguration.getServerUrl(), database == null ? "test" : database.getName()); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/logic/MongoClient.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.logic; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import com.mongodb.*; import com.mongodb.client.MongoIterable; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.codinjutsu.tools.nosql.DatabaseVendor; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.codinjutsu.tools.nosql.commons.logic.ConfigurationException; import org.codinjutsu.tools.nosql.commons.logic.DatabaseClient; import org.codinjutsu.tools.nosql.commons.model.AuthenticationSettings; import org.codinjutsu.tools.nosql.commons.model.Database; import org.codinjutsu.tools.nosql.commons.model.DatabaseServer; import org.codinjutsu.tools.nosql.mongo.model.MongoCollection; import org.codinjutsu.tools.nosql.mongo.model.MongoDatabase; import org.codinjutsu.tools.nosql.mongo.model.MongoQueryOptions; import org.codinjutsu.tools.nosql.mongo.model.MongoResult; import java.io.IOException; import java.net.UnknownHostException; import java.util.*; public class MongoClient implements DatabaseClient { private static final Logger LOG = Logger.getLogger(MongoClient.class); private final List databaseServers = new LinkedList<>(); public static MongoClient getInstance(Project project) { return ServiceManager.getService(project, MongoClient.class); } public void connect(ServerConfiguration configuration) { com.mongodb.MongoClient mongo = null; try { String userDatabase = configuration.getUserDatabase(); mongo = createMongoClient(configuration); MongoIterable collectionNames; if (StringUtils.isNotEmpty(userDatabase)) { collectionNames = mongo.getDatabase(userDatabase).listCollectionNames(); } else { collectionNames = mongo.getDatabase("test").listCollectionNames(); } collectionNames.first(); } catch (IOException ex) { throw new MongoConnectionException(ex); } catch (MongoException ex) { LOG.error("Error when accessing Mongo server", ex); throw new MongoConnectionException(ex.getMessage()); } finally { if (mongo != null) { mongo.close(); } } } public void cleanUpServers() { databaseServers.clear(); } public void registerServer(DatabaseServer databaseServer) { databaseServers.add(databaseServer); } @Override public ServerConfiguration defaultConfiguration() { ServerConfiguration serverConfiguration = new ServerConfiguration(); serverConfiguration.setDatabaseVendor(DatabaseVendor.MONGO); serverConfiguration.setServerUrl(DatabaseVendor.MONGO.defaultUrl); return serverConfiguration; } public List getServers() { return databaseServers; } public void loadServer(DatabaseServer databaseServer) { databaseServer.setStatus(DatabaseServer.Status.LOADING); List mongoDatabases = loadDatabaseCollections(databaseServer.getConfiguration()); databaseServer.setDatabases(mongoDatabases); databaseServer.setStatus(DatabaseServer.Status.OK); } List loadDatabaseCollections(ServerConfiguration configuration) { com.mongodb.MongoClient mongo = null; List mongoDatabases = new LinkedList<>(); try { String userDatabase = configuration.getUserDatabase(); mongo = createMongoClient(configuration); if (StringUtils.isNotEmpty(userDatabase)) { DB database = mongo.getDB(userDatabase); mongoDatabases.add(createMongoDatabaseAndItsCollections(database)); } else { List databaseNames = mongo.getDatabaseNames(); Collections.sort(databaseNames); for (String databaseName : databaseNames) { DB database = mongo.getDB(databaseName); mongoDatabases.add(createMongoDatabaseAndItsCollections(database)); } } return mongoDatabases; } catch (MongoException | UnknownHostException mongoEx) { throw new ConfigurationException(mongoEx); } finally { if (mongo != null) { mongo.close(); } } } private MongoDatabase createMongoDatabaseAndItsCollections(DB database) { MongoDatabase mongoDatabase = new MongoDatabase(database.getName()); Set collectionNames = database.getCollectionNames(); for (String collectionName : collectionNames) { mongoDatabase.addCollection(new MongoCollection(collectionName, database.getName())); } return mongoDatabase; } public void update(ServerConfiguration configuration, MongoCollection mongoCollection, DBObject mongoDocument) { com.mongodb.MongoClient mongo = null; try { String databaseName = mongoCollection.getDatabaseName(); mongo = createMongoClient(configuration); DB database = mongo.getDB(databaseName); DBCollection collection = database.getCollection(mongoCollection.getName()); collection.save(mongoDocument); } catch (UnknownHostException ex) { throw new ConfigurationException(ex); } finally { if (mongo != null) { mongo.close(); } } } public void delete(ServerConfiguration configuration, MongoCollection mongoCollection, Object _id) { com.mongodb.MongoClient mongo = null; try { String databaseName = mongoCollection.getDatabaseName(); mongo = createMongoClient(configuration); DB database = mongo.getDB(databaseName); DBCollection collection = database.getCollection(mongoCollection.getName()); collection.remove(new BasicDBObject("_id", _id)); } catch (UnknownHostException ex) { throw new ConfigurationException(ex); } finally { if (mongo != null) { mongo.close(); } } } public void dropCollection(ServerConfiguration configuration, MongoCollection mongoCollection) { com.mongodb.MongoClient mongo = null; try { String databaseName = mongoCollection.getDatabaseName(); mongo = createMongoClient(configuration); DB database = mongo.getDB(databaseName); DBCollection collection = database.getCollection(mongoCollection.getName()); collection.drop(); } catch (UnknownHostException ex) { throw new ConfigurationException(ex); } finally { if (mongo != null) { mongo.close(); } } } public void dropDatabase(ServerConfiguration configuration, MongoDatabase selectedDatabase) { com.mongodb.MongoClient mongo = null; try { mongo = createMongoClient(configuration); mongo.dropDatabase(selectedDatabase.getName()); } catch (UnknownHostException ex) { throw new ConfigurationException(ex); } finally { if (mongo != null) { mongo.close(); } } } public MongoResult loadCollectionValues(ServerConfiguration configuration, MongoCollection mongoCollection, MongoQueryOptions mongoQueryOptions) { com.mongodb.MongoClient mongo = null; try { String databaseName = mongoCollection.getDatabaseName(); mongo = createMongoClient(configuration); DB database = mongo.getDB(databaseName); DBCollection collection = database.getCollection(mongoCollection.getName()); MongoResult mongoResult = new MongoResult(mongoCollection.getName()); if (mongoQueryOptions.isAggregate()) { return aggregate(mongoQueryOptions, mongoResult, collection); } return find(mongoQueryOptions, mongoResult, collection); } catch (UnknownHostException ex) { throw new ConfigurationException(ex); } finally { if (mongo != null) { mongo.close(); } } } public DBObject findMongoDocument(ServerConfiguration configuration, MongoCollection mongoCollection, Object _id) { com.mongodb.MongoClient mongo = null; try { String databaseName = mongoCollection.getDatabaseName(); mongo = createMongoClient(configuration); DB database = mongo.getDB(databaseName); DBCollection collection = database.getCollection(mongoCollection.getName()); return collection.findOne(new BasicDBObject("_id", _id)); } catch (UnknownHostException ex) { throw new ConfigurationException(ex); } finally { if (mongo != null) { mongo.close(); } } } private MongoResult aggregate(MongoQueryOptions mongoQueryOptions, MongoResult mongoResult, DBCollection collection) { AggregationOutput aggregate = collection.aggregate(mongoQueryOptions.getOperations()); int index = 0; Iterator iterator = aggregate.results().iterator(); while (iterator.hasNext() && index < mongoQueryOptions.getResultLimit()) { mongoResult.add(iterator.next()); } return mongoResult; } private MongoResult find(MongoQueryOptions mongoQueryOptions, MongoResult mongoResult, DBCollection collection) { DBObject filter = mongoQueryOptions.getFilter(); DBObject projection = mongoQueryOptions.getProjection(); DBObject sort = mongoQueryOptions.getSort(); DBCursor cursor; if (projection == null) { cursor = collection.find(filter); } else { cursor = collection.find(filter, projection); } if (sort != null) { cursor = cursor.sort(sort); } try { int index = 0; while (cursor.hasNext() && index < mongoQueryOptions.getResultLimit()) { mongoResult.add(cursor.next()); index++; } } finally { cursor.close(); } return mongoResult; } private com.mongodb.MongoClient createMongoClient(ServerConfiguration configuration) throws UnknownHostException { String serverUrl = configuration.getServerUrl(); if (StringUtils.isEmpty(serverUrl)) { throw new ConfigurationException("server host is not set"); } MongoClientURIBuilder uriBuilder = MongoClientURIBuilder.builder(); uriBuilder.setServerAddresses(serverUrl); AuthenticationSettings authenticationSettings = configuration.getAuthenticationSettings(); MongoExtraSettings mongoExtraSettings = new MongoExtraSettings(authenticationSettings.getExtras()); if (StringUtils.isNotEmpty(authenticationSettings.getUsername())) { uriBuilder.setCredential(authenticationSettings.getUsername(), authenticationSettings.getPassword(), mongoExtraSettings.getAuthenticationDatabase()); } if (mongoExtraSettings.getAuthenticationMechanism() != null) { uriBuilder.setAuthenticationMecanism(mongoExtraSettings.getAuthenticationMechanism()); } if (mongoExtraSettings.isSsl()) { uriBuilder.sslEnabled(); } return new com.mongodb.MongoClient(new MongoClientURI(uriBuilder.build())); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/logic/MongoClientURIBuilder.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.logic; import com.mongodb.AuthenticationMechanism; import org.apache.commons.lang.StringUtils; import org.jetbrains.annotations.NotNull; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; public class MongoClientURIBuilder { private static final String DEFAULT_AUTH_DB = "admin"; private String serverUrls; private String username; private String password; private String authDatabase; private AuthenticationMechanism authenticationMecanism; private boolean sslEnabled = false; private MongoClientURIBuilder() { } public static MongoClientURIBuilder builder() { return new MongoClientURIBuilder(); } public MongoClientURIBuilder setServerAddresses(String serverUrls) { this.serverUrls = serverUrls; return this; } public MongoClientURIBuilder setCredential(String username, String password, String authDatabase) { this.username = username; this.password = password; this.authDatabase = StringUtils.isNotEmpty(authDatabase) ? authDatabase : DEFAULT_AUTH_DB; return this; } public String build() { StringBuilder strBuilder = new StringBuilder(); Map options = new HashMap(); if (StringUtils.isEmpty(username)) { strBuilder.append(String.format("mongodb://%s/", this.serverUrls)); } else { strBuilder.append(String.format("mongodb://%s:%s@%s/", username, password, serverUrls)); } if (authDatabase != null) { options.put("authSource", authDatabase); } if (authenticationMecanism != null) { options.put("authMechanism", authenticationMecanism.getMechanismName()); } if (sslEnabled) { options.put("ssl", Boolean.TRUE.toString()); } if (options.size() == 0) { return strBuilder.toString(); } return strBuilder.append(buildOptions(options)).toString(); } public MongoClientURIBuilder setAuthenticationMecanism(@NotNull AuthenticationMechanism authenticationMecanism) { this.authenticationMecanism = authenticationMecanism; return this; } public MongoClientURIBuilder sslEnabled() { sslEnabled = true; return this; } private static String buildOptions(Map options) { List optionList = new LinkedList(); for (Map.Entry keyValue : options.entrySet()) { optionList.add(String.format("%s=%s", keyValue.getKey(), keyValue.getValue())); } return "?" + StringUtils.join(optionList, "&"); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/logic/MongoConnectionException.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.logic; public class MongoConnectionException extends RuntimeException { public MongoConnectionException(String message) { super(message); } public MongoConnectionException(Exception ex) { super(ex); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/logic/MongoExtraSettings.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.logic; import com.mongodb.AuthenticationMechanism; import java.util.HashMap; import java.util.Map; public class MongoExtraSettings { private static final String DEFAULT_AUTH_DATABASE = "admin"; private static final String SSL = "ssl"; private static final String AUTH_DATABASE = "authDatabase"; private static final String AUTH_MECHANISM = "authMechanism"; private Map extras = new HashMap<>(); public MongoExtraSettings() { } public MongoExtraSettings(Map extras) { this.extras = extras; } public String getAuthenticationDatabase() { String authDatabase = extras.get(AUTH_DATABASE); return authDatabase == null ? DEFAULT_AUTH_DATABASE : authDatabase; } public AuthenticationMechanism getAuthenticationMechanism() { String authMecanism = extras.get(AUTH_MECHANISM); return authMecanism == null ? null : AuthenticationMechanism.valueOf(authMecanism); } public boolean isSsl() { String isSsl = extras.get(SSL); return isSsl == null ? false : Boolean.valueOf(isSsl); } public void setAuthenticationDatabase(String authenticationDatabase) { extras.put(AUTH_DATABASE, authenticationDatabase); } public void setAuthenticationMechanism(AuthenticationMechanism authenticationMechanism) { if (authenticationMechanism != null) { extras.put(AUTH_MECHANISM, authenticationMechanism.name()); } } public void setSsl(boolean isSsl) { extras.put(SSL, String.valueOf(isSsl)); } public Map get() { return extras; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/model/JsonDataType.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.model; public enum JsonDataType { STRING("String"), NUMBER("Number"), BOOLEAN("Boolean"), ARRAY("Array"), OBJECT("Object"), NULL("Null"), DATE("Date"); public final String type; private JsonDataType(String type) { this.type = type; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/model/MongoAggregateOperator.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.model; public enum MongoAggregateOperator { MATCH("$match"), PROJECT("$project"), GROUP("$group"), SORT("$sort"), LIMIT("$limit"), SKIP("$skip"), UNWIND("$unwind"); private final String operator; private MongoAggregateOperator(String operator) { this.operator = operator; } public String getLabel() { return operator; } @Override public String toString() { return name().toLowerCase(); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/model/MongoCollection.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.model; import org.jetbrains.annotations.NotNull; public class MongoCollection implements Comparable { private final String name; private final String databaseName; public MongoCollection(String name, String databaseName) { this.name = name; this.databaseName = databaseName; } public String getName() { return name; } public String getDatabaseName() { return databaseName; } @Override public int compareTo(@NotNull MongoCollection otherCollection) { return this.name.compareTo(otherCollection.getName()); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/model/MongoDatabase.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.model; import org.codinjutsu.tools.nosql.commons.model.Database; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; public class MongoDatabase extends Database { private final SortedSet collections = new TreeSet(); public MongoDatabase(String name) { super(name); } public String getName() { return name; } public Set getCollections() { return collections; } public void addCollection(MongoCollection mongoCollection) { collections.add(mongoCollection); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/model/MongoQueryOptions.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.model; import com.mongodb.BasicDBList; import com.mongodb.BasicDBObject; import com.mongodb.DBObject; import com.mongodb.util.JSON; import org.apache.commons.lang.StringUtils; import java.util.LinkedList; import java.util.List; public class MongoQueryOptions { private static final int DEFAULT_RESULT_LIMIT = 300; private static final BasicDBObject EMPTY_FILTER = new BasicDBObject(); private final List operations = new LinkedList(); private DBObject filter = EMPTY_FILTER; private DBObject projection = null; private DBObject sort; private int resultLimit = DEFAULT_RESULT_LIMIT; public boolean isAggregate() { return !operations.isEmpty(); } public List getOperations() { return operations; } public void setOperations(String aggregateQuery) { operations.clear(); BasicDBList operations = (BasicDBList) JSON.parse(aggregateQuery); this.operations.addAll(operations); } public void setFilter(String query) { if (!StringUtils.isBlank(query)) { filter = (DBObject) JSON.parse(query); } } public DBObject getFilter() { return filter; } public void setProjection(String query) { if (!StringUtils.isBlank(query)) { projection = (DBObject) JSON.parse(query); } } public DBObject getProjection() { return projection; } public void setSort(String query) { if (!StringUtils.isBlank(query)) { sort = (DBObject) JSON.parse(query); } } public DBObject getSort() { return sort; } public int getResultLimit() { return resultLimit; } public void setResultLimit(int resultLimit) { this.resultLimit = resultLimit; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/model/MongoResult.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.model; import com.mongodb.DBObject; import java.util.LinkedList; import java.util.List; public class MongoResult { private final String collectionName; private final List mongoObjects = new LinkedList(); public MongoResult(String collectionName) { this.collectionName = collectionName; } public void add(DBObject dbObject) { mongoObjects.add(dbObject); } public List getMongoObjects() { return mongoObjects; } public String getCollectionName() { return collectionName; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/model/OperatorValueConverter.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.model; import com.mongodb.DBObject; import com.mongodb.util.JSON; interface OperatorValueConverter { T convert(String operatorValue); public static OperatorValueConverter integerValueConverter = new OperatorValueConverter() { @Override public Integer convert(String operatorValue) { return Integer.valueOf(operatorValue); } }; public static OperatorValueConverter stringValueConverter = new OperatorValueConverter() { @Override public String convert(String operatorValue) { return operatorValue; } }; public static OperatorValueConverter jSONValueConverter = new OperatorValueConverter() { @Override public DBObject convert(String operatorValue) { return (DBObject) JSON.parse(operatorValue); } }; } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/runner/MongoCommandLineState.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.runner; import com.intellij.execution.ExecutionException; import com.intellij.execution.configurations.CommandLineState; import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.execution.process.ColoredProcessHandler; import com.intellij.execution.process.OSProcessHandler; import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.process.ProcessTerminatedListener; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.openapi.vfs.VirtualFile; import org.apache.commons.lang.StringUtils; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.codinjutsu.tools.nosql.mongo.MongoUtils; import org.codinjutsu.tools.nosql.mongo.model.MongoDatabase; import org.jetbrains.annotations.NotNull; class MongoCommandLineState extends CommandLineState { private final MongoRunConfiguration mongoRunConfiguration; public MongoCommandLineState(MongoRunConfiguration mongoRunConfiguration, ExecutionEnvironment environment) { super(environment); this.mongoRunConfiguration = mongoRunConfiguration; } @NotNull @Override protected ProcessHandler startProcess() throws ExecutionException { GeneralCommandLine commandLine = generateCommandLine(); final OSProcessHandler processHandler = new ColoredProcessHandler(commandLine); ProcessTerminatedListener.attach(processHandler); return processHandler; } private GeneralCommandLine generateCommandLine() { final GeneralCommandLine commandLine = new GeneralCommandLine(); String exePath = mongoRunConfiguration.getMongoShell(); commandLine.setExePath(exePath); ServerConfiguration serverConfiguration = mongoRunConfiguration.getServerConfiguration(); MongoDatabase database = mongoRunConfiguration.getDatabase(); commandLine.addParameter(MongoUtils.buildMongoUrl(serverConfiguration, database)); VirtualFile scriptPath = mongoRunConfiguration.getScriptPath(); commandLine.addParameter(scriptPath.getPath()); String shellWorkingDir = mongoRunConfiguration.getShellWorkingDir(); if (StringUtils.isNotEmpty(shellWorkingDir)) { commandLine.setWorkDirectory(shellWorkingDir); } return commandLine; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/runner/MongoRunConfiguration.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.runner; import com.intellij.execution.CantRunException; import com.intellij.execution.ExecutionException; import com.intellij.execution.Executor; import com.intellij.execution.configurations.*; import com.intellij.execution.filters.TextConsoleBuilderFactory; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.openapi.components.PathMacroManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.options.SettingsEditor; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.JDOMExternalizer; import com.intellij.openapi.util.WriteExternalException; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import org.codinjutsu.tools.nosql.DatabaseVendor; import org.codinjutsu.tools.nosql.NoSqlConfiguration; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.codinjutsu.tools.nosql.mongo.model.MongoDatabase; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Arrays; import java.util.Collection; class MongoRunConfiguration extends ModuleBasedConfiguration { private final String mongoShell; private String scriptPath; private String shellParameters; private ServerConfiguration serverConfiguration; private MongoDatabase database; private String shellWorkingDir; MongoRunConfiguration(RunConfigurationModule runConfigurationModule, ConfigurationFactory factory) { super("Mongo Script", runConfigurationModule, factory); mongoShell = NoSqlConfiguration.getInstance(getProject()).getShellPath(DatabaseVendor.MONGO); } @NotNull @Override public SettingsEditor getConfigurationEditor() { return new MongoRunConfigurationEditor(getProject()); } @Override public Collection getValidModules() { Module[] allModules = ModuleManager.getInstance(getProject()).getModules(); return Arrays.asList(allModules); } @Override public void readExternal(Element element) throws InvalidDataException { PathMacroManager.getInstance(getProject()).expandPaths(element); super.readExternal(element); scriptPath = JDOMExternalizer.readString(element, "path"); shellParameters = JDOMExternalizer.readString(element, "shellParams"); // serverConfiguration = JDOMExternalizer.readBoolean(element, "serverConfiguration"); } @Override public void writeExternal(Element element) throws WriteExternalException { super.writeExternal(element); JDOMExternalizer.write(element, "path", scriptPath); JDOMExternalizer.write(element, "shellParams", shellParameters); // JDOMExternalizer.write(element, "serverConfiguration", serverConfiguration); PathMacroManager.getInstance(getProject()).collapsePathsRecursively(element); } @Override protected MongoRunConfiguration createInstance() { return new MongoRunConfiguration(getConfigurationModule(), getFactory()); } @Nullable @Override public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment env) throws ExecutionException { final VirtualFile script = getScriptPath(); if (script == null) { throw new CantRunException("Cannot find script " + scriptPath); } final MongoCommandLineState state = new MongoCommandLineState(this, env); state.setConsoleBuilder(TextConsoleBuilderFactory.getInstance().createBuilder(getProject())); return state; } @Override public void checkConfiguration() throws RuntimeConfigurationException { if (mongoShell == null) { throw new RuntimeConfigurationError("Mongo shell path is not set."); } if (scriptPath == null) { throw new RuntimeConfigurationError("Script path is not set."); } if (serverConfiguration == null) { throw new RuntimeConfigurationError("Server is not set."); } if (database == null) { throw new RuntimeConfigurationError("Database is not set."); } } public VirtualFile getScriptPath() { if (scriptPath == null) return null; return LocalFileSystem.getInstance().findFileByPath(FileUtil.toSystemIndependentName(scriptPath)); } public void setScriptPath(String scriptPath) { this.scriptPath = scriptPath; } public ServerConfiguration getServerConfiguration() { return serverConfiguration; } public void setServerConfiguration(ServerConfiguration serverConfiguration) { this.serverConfiguration = serverConfiguration; } public String getShellParameters() { return shellParameters; } public void setShellParameters(String shellParameters) { this.shellParameters = shellParameters; } public String getMongoShell() { return mongoShell; } public MongoDatabase getDatabase() { return this.database; } public void setDatabase(MongoDatabase database) { this.database = database; } public String getShellWorkingDir() { return shellWorkingDir; } public void setShellWorkingDir(String shellWorkingDir) { this.shellWorkingDir = shellWorkingDir; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/runner/MongoRunConfigurationEditor.form ================================================
================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/runner/MongoRunConfigurationEditor.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.runner; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.options.SettingsEditor; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.ComboBox; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.ui.ColoredListCellRenderer; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.RawCommandLineEditor; import org.apache.commons.lang.StringUtils; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.codinjutsu.tools.nosql.commons.model.Database; import org.codinjutsu.tools.nosql.commons.model.DatabaseServer; import org.codinjutsu.tools.nosql.mongo.logic.MongoClient; import org.codinjutsu.tools.nosql.mongo.model.MongoDatabase; import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.LinkedList; import java.util.List; public class MongoRunConfigurationEditor extends SettingsEditor { private JPanel mainPanel; private JTextField scriptPathField; private ComboBox serverConfigurationCombobox; private ComboBox databaseCombobox; private JPanel mongoShellOptionsPanel; private RawCommandLineEditor shellParametersField; private TextFieldWithBrowseButton shellWorkingDirField; public MongoRunConfigurationEditor(Project project) { mongoShellOptionsPanel.setBorder(IdeBorderFactory.createTitledBorder("Mongo shell options", true)); shellParametersField.setDialogCaption("Mongo arguments"); DatabaseServer[] mongoServers = getAvailableMongoServers(project); if (mongoServers.length == 0) { serverConfigurationCombobox.setEnabled(false); databaseCombobox.setEnabled(false); return; } serverConfigurationCombobox.setModel(new DefaultComboBoxModel(mongoServers)); serverConfigurationCombobox.setRenderer(new ColoredListCellRenderer() { @Override protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) { DatabaseServer serverConfiguration = (DatabaseServer) value; append(serverConfiguration.getLabel()); } }); databaseCombobox.setRenderer(new ColoredListCellRenderer() { @Override protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) { MongoDatabase mongoDatabase = (MongoDatabase) value; if (value == null) { return; } append(mongoDatabase.getName()); } }); serverConfigurationCombobox.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent itemEvent) { DatabaseServer selectedServer = (DatabaseServer) serverConfigurationCombobox.getSelectedItem(); if (selectedServer == null) { return; } databaseCombobox.removeAllItems(); for (Database mongoDatabase : selectedServer.getDatabases()) { databaseCombobox.addItem(mongoDatabase); } } }); serverConfigurationCombobox.setSelectedIndex(-1); serverConfigurationCombobox.setSelectedIndex(0); } private DatabaseServer[] getAvailableMongoServers(Project project) { List mongoServers = MongoClient.getInstance(project).getServers(); List availableMongoServers = new LinkedList(); for (DatabaseServer mongoServer : mongoServers) { if (mongoServer.hasDatabases()) { availableMongoServers.add(mongoServer); } } return availableMongoServers.toArray(new DatabaseServer[availableMongoServers.size()]); } @Override protected void resetEditorFrom(MongoRunConfiguration configuration) { scriptPathField.setText(configuration.getScriptPath() != null ? configuration.getScriptPath().getPath() : null); shellParametersField.setText(configuration.getShellParameters()); shellWorkingDirField.setText(configuration.getShellWorkingDir()); } @Override protected void applyEditorTo(MongoRunConfiguration configuration) throws ConfigurationException { configuration.setScriptPath(getScriptPath()); configuration.setServerConfiguration(getSelectedConfiguration()); configuration.setDatabase(getSelectedDatabase()); configuration.setShellParameters(getShellParameters()); configuration.setShellWorkingDir(getShellWorkingDir()); } private String getScriptPath() { return scriptPathField.getText(); } private String getShellParameters() { return shellParametersField.getText(); } private ServerConfiguration getSelectedConfiguration() { DatabaseServer selectedServer = (DatabaseServer) serverConfigurationCombobox.getSelectedItem(); return selectedServer == null ? null : selectedServer.getConfiguration(); } public MongoDatabase getSelectedDatabase() { return (MongoDatabase) databaseCombobox.getSelectedItem(); } private String getShellWorkingDir() { String shellWorkingDir = shellWorkingDirField.getText(); if (StringUtils.isNotBlank(shellWorkingDir)) { return shellWorkingDir; } return null; } @NotNull @Override protected JComponent createEditor() { return mainPanel; } @Override protected void disposeEditor() { } private void createUIComponents() { shellWorkingDirField = new TextFieldWithBrowseButton(); shellWorkingDirField.addBrowseFolderListener("Mongo shell working directory", "", null, new FileChooserDescriptor(false, true, false, false, false, false)); shellWorkingDirField.setName("shellWorkingDirField"); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/runner/MongoRunConfigurationType.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.runner; import com.intellij.execution.configurations.*; import com.intellij.openapi.project.Project; import org.codinjutsu.tools.nosql.commons.utils.GuiUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import javax.swing.*; public class MongoRunConfigurationType implements ConfigurationType { private final MongoFactory myConfigurationFactory; public MongoRunConfigurationType() { myConfigurationFactory = new MongoFactory(this); } public String getDisplayName() { return "Mongo"; } public String getConfigurationTypeDescription() { return "Mongo configuration"; } public Icon getIcon() { return GuiUtils.loadIcon("mongo_logo.png"); } @NonNls @NotNull public String getId() { return "MongoRunConfiguration"; } public MongoFactory[] getConfigurationFactories() { return new MongoFactory[]{myConfigurationFactory}; } public static MongoRunConfigurationType getInstance() { return ConfigurationTypeUtil.findConfigurationType(MongoRunConfigurationType.class); } private static class MongoFactory extends ConfigurationFactory { public MongoFactory(ConfigurationType type) { super(type); } public RunConfiguration createTemplateConfiguration(Project project) { return new MongoRunConfiguration(new RunConfigurationModule(project), this); } } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/runner/MongoScriptRunConfigurationProducer.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.runner; import com.intellij.execution.Location; import com.intellij.execution.RunnerAndConfigurationSettings; import com.intellij.execution.actions.ConfigurationContext; import com.intellij.execution.junit.RuntimeConfigurationProducer; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class MongoScriptRunConfigurationProducer extends RuntimeConfigurationProducer implements Cloneable { private PsiFile sourceFile; public MongoScriptRunConfigurationProducer() { super(MongoRunConfigurationType.getInstance()); } @Override public PsiElement getSourceElement() { return sourceFile; } @Nullable @Override protected RunnerAndConfigurationSettings createConfigurationByElement(Location location, ConfigurationContext configurationContext) { sourceFile = location.getPsiElement().getContainingFile(); if (sourceFile != null && sourceFile.getFileType().getName().toLowerCase().contains("javascript")) { Project project = sourceFile.getProject(); VirtualFile file = sourceFile.getVirtualFile(); RunnerAndConfigurationSettings settings = cloneTemplateConfiguration(project, configurationContext); MongoRunConfiguration runConfiguration = (MongoRunConfiguration) settings.getConfiguration(); runConfiguration.setName(file.getName()); runConfiguration.setScriptPath(file.getPath()); Module module = ModuleUtil.findModuleForPsiElement(location.getPsiElement()); if (module != null) { runConfiguration.setModule(module); } return settings; } return null; } @Override public int compareTo(@NotNull Object o) { return 0; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/AbstractAddDialog.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view; import com.intellij.openapi.ui.ComboBox; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.ui.ColoredListCellRenderer; import com.intellij.ui.components.JBCheckBox; import com.mongodb.util.JSON; import org.apache.commons.lang.StringUtils; import org.codinjutsu.tools.nosql.commons.view.table.DateTimePicker; import org.codinjutsu.tools.nosql.mongo.model.JsonDataType; import javax.swing.*; import java.awt.*; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.Map; public abstract class AbstractAddDialog extends DialogWrapper { private static final Map UI_COMPONENT_BY_JSON_DATATYPE = new HashMap(); static { UI_COMPONENT_BY_JSON_DATATYPE.put(JsonDataType.STRING, new StringFieldWrapper()); UI_COMPONENT_BY_JSON_DATATYPE.put(JsonDataType.BOOLEAN, new BooleanFieldWrapper()); UI_COMPONENT_BY_JSON_DATATYPE.put(JsonDataType.NUMBER, new NumberFieldWrapper()); UI_COMPONENT_BY_JSON_DATATYPE.put(JsonDataType.NULL, new NullFieldWrapper()); UI_COMPONENT_BY_JSON_DATATYPE.put(JsonDataType.DATE, new DateTimeFieldWrapper()); UI_COMPONENT_BY_JSON_DATATYPE.put(JsonDataType.OBJECT, new JsonFieldWrapper()); UI_COMPONENT_BY_JSON_DATATYPE.put(JsonDataType.ARRAY, new JsonFieldWrapper()); } final MongoEditionPanel mongoEditionPanel; protected TextFieldWrapper currentEditor = null; AbstractAddDialog(MongoEditionPanel mongoEditionPanel) { super(mongoEditionPanel, true); this.mongoEditionPanel = mongoEditionPanel; } void initCombo(final ComboBox combobox, final JPanel parentPanel) { combobox.setModel(new DefaultComboBoxModel(JsonDataType.values())); combobox.setRenderer(new ColoredListCellRenderer() { @Override protected void customizeCellRenderer(JList jList, Object o, int i, boolean b, boolean b2) { append(((JsonDataType) o).type); } }); combobox.setSelectedItem(null); combobox.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent itemEvent) { JsonDataType selectedType = (JsonDataType) combobox.getSelectedItem(); currentEditor = UI_COMPONENT_BY_JSON_DATATYPE.get(selectedType); currentEditor.reset(); parentPanel.invalidate(); parentPanel.removeAll(); parentPanel.add(currentEditor.getComponent(), BorderLayout.CENTER); parentPanel.validate(); } }); combobox.setSelectedItem(JsonDataType.STRING); } public abstract Object getValue(); public static abstract class TextFieldWrapper { protected final T component; private TextFieldWrapper(T component) { this.component = component; } public abstract V getValue(); public abstract void reset(); public boolean isValueSet() { return true; } public T getComponent() { return component; } public void validate() { if (!isValueSet()) { throw new IllegalArgumentException("Value is not set"); } } } private static class StringFieldWrapper extends TextFieldWrapper { private StringFieldWrapper() { super(new JTextField()); } @Override public String getValue() { return component.getText(); } @Override public boolean isValueSet() { return StringUtils.isNotBlank(component.getText()); } @Override public void reset() { component.setText(""); } } private static class JsonFieldWrapper extends TextFieldWrapper { private JsonFieldWrapper() { super(new JTextField()); } @Override public Object getValue() { return JSON.parse(component.getText()); } @Override public boolean isValueSet() { return StringUtils.isNotBlank(component.getText()); } @Override public void reset() { component.setText(""); } } private static class NumberFieldWrapper extends TextFieldWrapper { private NumberFieldWrapper() { super(new JTextField()); } @Override public Number getValue() { return org.codinjutsu.tools.nosql.commons.utils.StringUtils.parseNumber(component.getText()); } @Override public void reset() { component.setText(""); } @Override public boolean isValueSet() { return StringUtils.isNotBlank(component.getText()); } @Override public void validate() { super.validate(); getValue(); } } private static class BooleanFieldWrapper extends TextFieldWrapper { private BooleanFieldWrapper() { super(new JBCheckBox()); } @Override public Boolean getValue() { return component.isSelected(); } @Override public void reset() { component.setSelected(false); } } private static class NullFieldWrapper extends TextFieldWrapper { private NullFieldWrapper() { super(new JLabel("null")); } @Override public Object getValue() { return null; } @Override public void reset() { } } private static class DateTimeFieldWrapper extends TextFieldWrapper { private DateTimeFieldWrapper() { super(DateTimePicker.create()); component.getEditor().setEditable(false); } @Override public Date getValue() { return component.getDate(); } @Override public boolean isValueSet() { return component.getDate() != null; } @Override public void reset() { component.setDate(GregorianCalendar.getInstance().getTime()); } } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/AddKeyDialog.form ================================================
================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/AddKeyDialog.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view; import com.intellij.openapi.ui.ComboBox; import com.intellij.openapi.ui.ValidationInfo; import org.apache.commons.lang.StringUtils; import org.codinjutsu.tools.nosql.commons.utils.GuiUtils; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; public class AddKeyDialog extends AbstractAddDialog { private JTextField nameTextfield; private ComboBox typeCombobox; private JPanel valuePanel; private JPanel mainPanel; private AddKeyDialog(MongoEditionPanel mongoEditionPanel) { super(mongoEditionPanel); mainPanel.setPreferredSize(GuiUtils.enlargeWidth(mainPanel.getPreferredSize(), 1.5d)); valuePanel.setLayout(new BorderLayout()); nameTextfield.setName("keyName"); typeCombobox.setName("valueType"); } @Nullable @Override protected JComponent createCenterPanel() { return mainPanel; } public static AddKeyDialog createDialog(MongoEditionPanel parentPanel) { AddKeyDialog dialog = new AddKeyDialog(parentPanel); dialog.init(); dialog.setTitle("Add A Key"); return dialog; } @Override protected void init() { super.init(); initCombo(typeCombobox, valuePanel); } @Nullable @Override protected ValidationInfo doValidate() { String keyName = getKey(); if (StringUtils.isBlank(keyName)) { return new ValidationInfo("Key name is not set"); } if (mongoEditionPanel.containsKey(keyName)) { return new ValidationInfo(String.format("Key '%s' is already used", keyName)); } try { currentEditor.validate(); } catch (Exception ex) { return new ValidationInfo(ex.getMessage()); } return null; } @Nullable @Override public JComponent getPreferredFocusedComponent() { return nameTextfield; } public String getKey() { return nameTextfield.getText(); } @Override public Object getValue() { return currentEditor.getValue(); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/AddValueDialog.form ================================================
================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/AddValueDialog.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view; import com.intellij.openapi.ui.ComboBox; import com.intellij.openapi.ui.ValidationInfo; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; public class AddValueDialog extends AbstractAddDialog { private ComboBox typeCombobox; private JPanel valuePanel; private JPanel mainPanel; private AddValueDialog(MongoEditionPanel mongoEditionPanel) { super(mongoEditionPanel); valuePanel.setLayout(new BorderLayout()); typeCombobox.setName("valueType"); typeCombobox.requestFocus(); } @Nullable @Override protected JComponent createCenterPanel() { return mainPanel; } public static AddValueDialog createDialog(MongoEditionPanel parentPanel) { AddValueDialog dialog = new AddValueDialog(parentPanel); dialog.init(); dialog.setTitle("Add A Value"); return dialog; } @Override protected void init() { super.init(); initCombo(typeCombobox, valuePanel); } @Nullable @Override protected ValidationInfo doValidate() { try { currentEditor.validate(); } catch (Exception ex) { return new ValidationInfo(ex.getMessage()); } return null; } @Override public Object getValue() { return currentEditor.getValue(); } @Nullable @Override public JComponent getPreferredFocusedComponent() { return typeCombobox; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/JsonTreeTableView.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view; import com.intellij.ui.TreeTableSpeedSearch; import com.intellij.ui.treeStructure.treetable.ListTreeTableModelOnColumns; import com.intellij.ui.treeStructure.treetable.TreeTable; import com.intellij.ui.treeStructure.treetable.TreeTableModel; import com.intellij.ui.treeStructure.treetable.TreeTableTree; import com.intellij.util.containers.Convertor; import com.intellij.util.ui.ColumnInfo; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.tree.TreeUtil; import com.mongodb.DBObject; import org.bson.types.ObjectId; import org.codinjutsu.tools.nosql.commons.view.NoSqlTreeNode; import org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor; import org.codinjutsu.tools.nosql.commons.view.renderer.KeyCellRenderer; import org.codinjutsu.tools.nosql.commons.view.renderer.ValueCellRenderer; import org.codinjutsu.tools.nosql.commons.view.table.CellEditor; import org.codinjutsu.tools.nosql.mongo.view.table.MongoDatePickerCellEditor; import org.jetbrains.annotations.Nullable; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Date; public class JsonTreeTableView extends TreeTable { private static final ColumnInfo KEY = new ColumnInfo("Key") { public Object valueOf(Object obj) { NoSqlTreeNode node = (NoSqlTreeNode) obj; return node.getDescriptor(); } @Override public Class getColumnClass() { return TreeTableModel.class; } @Override public boolean isCellEditable(Object o) { return false; } }; private static final ColumnInfo READONLY_VALUE = new ReadOnlyValueColumnInfo(); private static final ColumnInfo WRITABLE_VALUE = new WritableColumnInfo(); public static final ColumnInfo[] COLUMNS_FOR_READING = new ColumnInfo[]{KEY, READONLY_VALUE}; public static final ColumnInfo[] COLUMNS_FOR_WRITING = new ColumnInfo[]{KEY, WRITABLE_VALUE}; private final ColumnInfo[] columns; public JsonTreeTableView(TreeNode rootNode, ColumnInfo[] columnInfos) { super(new ListTreeTableModelOnColumns(rootNode, columnInfos)); this.columns = columnInfos; final TreeTableTree tree = getTree(); tree.setShowsRootHandles(true); tree.setRootVisible(false); UIUtil.setLineStyleAngled(tree); setTreeCellRenderer(new KeyCellRenderer()); TreeUtil.expand(tree, 2); new TreeTableSpeedSearch(this, new Convertor() { @Override public String convert(final TreePath path) { final NoSqlTreeNode node = (NoSqlTreeNode) path.getLastPathComponent(); NodeDescriptor descriptor = node.getDescriptor(); return descriptor.getFormattedKey(); } }); } @Override public TableCellRenderer getCellRenderer(int row, int column) { TreePath treePath = getTree().getPathForRow(row); if (treePath == null) return super.getCellRenderer(row, column); NoSqlTreeNode node = (NoSqlTreeNode) treePath.getLastPathComponent(); TableCellRenderer renderer = this.columns[column].getRenderer(node); return renderer == null ? super.getCellRenderer(row, column) : renderer; } @Override public TableCellEditor getCellEditor(int row, int column) { TreePath treePath = getTree().getPathForRow(row); if (treePath == null) return super.getCellEditor(row, column); NoSqlTreeNode node = (NoSqlTreeNode) treePath.getLastPathComponent(); TableCellEditor editor = columns[column].getEditor(node); return editor == null ? super.getCellEditor(row, column) : editor; } private static class ReadOnlyValueColumnInfo extends ColumnInfo { private final TableCellRenderer myRenderer = new ValueCellRenderer(); public ReadOnlyValueColumnInfo() { super("Value"); } public NodeDescriptor valueOf(NoSqlTreeNode treeNode) { return treeNode.getDescriptor(); } @Override public TableCellRenderer getRenderer(NoSqlTreeNode o) { return myRenderer; } @Override public boolean isCellEditable(NoSqlTreeNode o) { return false; } } private static class WritableColumnInfo extends ColumnInfo { private final TableCellRenderer myRenderer = new ValueCellRenderer(); private final TableCellEditor defaultEditor = new CellEditor(); public WritableColumnInfo() { super("Value"); } @Override public TableCellRenderer getRenderer(NoSqlTreeNode o) { return myRenderer; } @Override public boolean isCellEditable(NoSqlTreeNode treeNode) { Object value = treeNode.getDescriptor().getValue(); if (value instanceof DBObject) { return false; } if (value instanceof ObjectId) { return false; } return true; } @Nullable @Override public TableCellEditor getEditor(final NoSqlTreeNode treeNode) { Object value = treeNode.getDescriptor().getValue(); if (value instanceof Date) { return buildDateCellEditor(treeNode); } return defaultEditor; } private static MongoDatePickerCellEditor buildDateCellEditor(final NoSqlTreeNode treeNode) { final MongoDatePickerCellEditor dateEditor = new MongoDatePickerCellEditor(); // Note from dev: Quite ugly because when clicking on the button to open popup calendar, stopCellEdition is invoked. // From that point, impossible to set the selected data in the node description dateEditor.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { treeNode.getDescriptor().setValue(dateEditor.getCellEditorValue()); } }); return dateEditor; } public Object valueOf(NoSqlTreeNode treeNode) { return treeNode.getDescriptor().getValue(); } @Override public void setValue(NoSqlTreeNode treeNode, Object value) { treeNode.getDescriptor().setValue(value); } } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/MongoAuthenticationPanel.form ================================================
================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/MongoAuthenticationPanel.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view; import com.mongodb.AuthenticationMechanism; import org.apache.commons.lang.StringUtils; import org.codinjutsu.tools.nosql.commons.model.AuthenticationSettings; import org.codinjutsu.tools.nosql.commons.view.AuthenticationView; import org.codinjutsu.tools.nosql.mongo.logic.MongoExtraSettings; import javax.swing.*; public class MongoAuthenticationPanel implements AuthenticationView { private JPanel mainPanel; private JTextField usernameField; private JPasswordField passwordField; private JTextField authenticationDatabaseField; private JRadioButton scramSHA1AuthRadioButton; private JRadioButton mongoCRAuthRadioButton; private JRadioButton defaultAuthMethodRadioButton; private JCheckBox sslConnectionField; public MongoAuthenticationPanel() { usernameField.setName("usernameField"); passwordField.setName("passwordField"); authenticationDatabaseField.setName("authenticationDatabaseField"); mongoCRAuthRadioButton.setName("mongoCRAuthField"); scramSHA1AuthRadioButton.setName("scramSHA1AuthField"); defaultAuthMethodRadioButton.setName("defaultAuthMethod"); sslConnectionField.setName("sslConnectionField"); ButtonGroup authMethodGroup = new ButtonGroup(); authMethodGroup.add(mongoCRAuthRadioButton); authMethodGroup.add(scramSHA1AuthRadioButton); authMethodGroup.add(defaultAuthMethodRadioButton); defaultAuthMethodRadioButton.setSelected(true); defaultAuthMethodRadioButton.setToolTipText("Let the driver resolves the auth. mecanism"); } @Override public JPanel getComponent() { return mainPanel; } @Override public AuthenticationSettings create() { AuthenticationSettings authenticationSettings = new AuthenticationSettings(); authenticationSettings.setUsername(getUsername()); authenticationSettings.setPassword(getPassword()); MongoExtraSettings mongoExtraSettings = new MongoExtraSettings(); mongoExtraSettings.setSsl(isSslConnection()); mongoExtraSettings.setAuthenticationDatabase(getAuthenticationDatabase()); mongoExtraSettings.setAuthenticationMechanism(getAuthenticationMechanism()); authenticationSettings.setExtras(mongoExtraSettings.get()); return authenticationSettings; } @Override public void load(AuthenticationSettings settings) { usernameField.setText(settings.getUsername()); passwordField.setText(settings.getPassword()); MongoExtraSettings mongoExtraSettings = new MongoExtraSettings(settings.getExtras()); authenticationDatabaseField.setText(mongoExtraSettings.getAuthenticationDatabase()); sslConnectionField.setSelected(mongoExtraSettings.isSsl()); AuthenticationMechanism authentificationMethod = mongoExtraSettings.getAuthenticationMechanism(); if (AuthenticationMechanism.MONGODB_CR.equals(authentificationMethod)) { mongoCRAuthRadioButton.setSelected(true); } else if (AuthenticationMechanism.SCRAM_SHA_1.equals(authentificationMethod)) { scramSHA1AuthRadioButton.setSelected(true); } else { defaultAuthMethodRadioButton.setSelected(true); } } private boolean isSslConnection() { return sslConnectionField.isSelected(); } private String getUsername() { String username = usernameField.getText(); if (StringUtils.isNotBlank(username)) { return username; } return null; } private String getPassword() { char[] password = passwordField.getPassword(); if (password != null && password.length != 0) { return String.valueOf(password); } return null; } private String getAuthenticationDatabase() { String authenticationDatabase = authenticationDatabaseField.getText(); if (StringUtils.isNotBlank(authenticationDatabase)) { return authenticationDatabase; } return null; } private AuthenticationMechanism getAuthenticationMechanism() { if (mongoCRAuthRadioButton.isSelected()) { return AuthenticationMechanism.MONGODB_CR; } else if (scramSHA1AuthRadioButton.isSelected()) { return AuthenticationMechanism.SCRAM_SHA_1; } return null; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/MongoEditionPanel.form ================================================
================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/MongoEditionPanel.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.openapi.application.ApplicationManager; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.PopupHandler; import com.intellij.ui.components.JBScrollPane; import com.intellij.util.ui.tree.TreeUtil; import com.mongodb.DBObject; import org.apache.commons.lang.StringUtils; import org.codinjutsu.tools.nosql.commons.view.NoSqlTreeNode; import org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor; import org.codinjutsu.tools.nosql.mongo.view.action.edition.AddKeyAction; import org.codinjutsu.tools.nosql.mongo.view.action.edition.AddValueAction; import org.codinjutsu.tools.nosql.mongo.view.action.edition.DeleteKeyAction; import org.codinjutsu.tools.nosql.mongo.view.model.JsonTreeModel; import org.codinjutsu.tools.nosql.mongo.view.nodedescriptor.MongoKeyValueDescriptor; import org.codinjutsu.tools.nosql.mongo.view.nodedescriptor.MongoValueDescriptor; import javax.swing.*; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeNode; import java.awt.*; import java.awt.event.ActionEvent; import java.util.Enumeration; import java.util.LinkedList; import java.util.List; public class MongoEditionPanel extends JPanel implements Disposable { private JButton saveButton; private JButton cancelButton; private JPanel editionTreePanel; private JPanel mainPanel; private JButton deleteButton; private JsonTreeTableView editTableView; public MongoEditionPanel() { super(new BorderLayout()); add(mainPanel); editionTreePanel.setLayout(new BorderLayout()); saveButton.setName("saveButton"); cancelButton.setName("cancelButton"); deleteButton.setName("deleteButton"); } public MongoEditionPanel init(final MongoPanel.MongoDocumentOperations mongoDocumentOperations, final MongoResultPanel.ActionCallback actionCallback) { cancelButton.addActionListener(new AbstractAction() { @Override public void actionPerformed(ActionEvent actionEvent) { actionCallback.onOperationCancelled("Modification canceled..."); } }); saveButton.addActionListener(new AbstractAction() { @Override public void actionPerformed(ActionEvent actionEvent) { try { mongoDocumentOperations.updateMongoDocument(buildMongoDocument()); actionCallback.onOperationSuccess("Document saved..."); } catch (Exception exception) { actionCallback.onOperationFailure(exception); } } }); deleteButton.addActionListener(new AbstractAction() { @Override public void actionPerformed(ActionEvent actionEvent) { try { mongoDocumentOperations.deleteMongoDocument(getDocumentId()); actionCallback.onOperationSuccess("Document deleted..."); } catch (Exception exception) { actionCallback.onOperationFailure(exception); } } }); return this; } public void updateEditionTree(DBObject mongoDocument) { String panelTitle = "New document"; if (mongoDocument != null) { panelTitle = "Edition"; } mainPanel.setBorder(IdeBorderFactory.createTitledBorder(panelTitle, true)); editTableView = new JsonTreeTableView(JsonTreeModel.buildJsonTree(mongoDocument), JsonTreeTableView.COLUMNS_FOR_WRITING); editTableView.setName("editionTreeTable"); editionTreePanel.invalidate(); editionTreePanel.removeAll(); editionTreePanel.add(new JBScrollPane(editTableView)); editionTreePanel.validate(); buildPopupMenu(); } void buildPopupMenu() { DefaultActionGroup actionPopupGroup = new DefaultActionGroup("MongoEditorPopupGroup", true); if (ApplicationManager.getApplication() != null) { actionPopupGroup.add(new AddKeyAction(this)); actionPopupGroup.add(new AddValueAction(this)); actionPopupGroup.add(new DeleteKeyAction(this)); } PopupHandler.installPopupHandler(editTableView, actionPopupGroup, "POPUP", ActionManager.getInstance()); } public boolean containsKey(String key) { NoSqlTreeNode parentNode = getParentNode(); if (parentNode == null) { return false; } Enumeration children = parentNode.children(); while (children.hasMoreElements()) { NoSqlTreeNode childNode = (NoSqlTreeNode) children.nextElement(); NodeDescriptor descriptor = childNode.getDescriptor(); if (descriptor instanceof MongoKeyValueDescriptor) { MongoKeyValueDescriptor keyValueDescriptor = (MongoKeyValueDescriptor) descriptor; if (StringUtils.equals(key, keyValueDescriptor.getKey())) { return true; } } } return false; } public void addKey(String key, Object value) { List node = new LinkedList(); NoSqlTreeNode treeNode = new NoSqlTreeNode(MongoKeyValueDescriptor.createDescriptor(key, value)); if (value instanceof DBObject) { JsonTreeModel.processDbObject(treeNode, (DBObject) value); } node.add(treeNode); DefaultTreeModel treeModel = (DefaultTreeModel) editTableView.getTree().getModel(); NoSqlTreeNode parentNode = getParentNode(); if (parentNode == null) { parentNode = (NoSqlTreeNode) treeModel.getRoot(); } TreeUtil.addChildrenTo(parentNode, node); treeModel.reload(parentNode); } public void addValue(Object value) { List node = new LinkedList(); NoSqlTreeNode parentNode = getParentNode(); NoSqlTreeNode treeNode = new NoSqlTreeNode(MongoValueDescriptor.createDescriptor(parentNode.getChildCount(), value)); if (value instanceof DBObject) { JsonTreeModel.processDbObject(treeNode, (DBObject) value); } node.add(treeNode); DefaultTreeModel treeModel = (DefaultTreeModel) editTableView.getTree().getModel(); TreeUtil.addChildrenTo(parentNode, node); treeModel.reload(parentNode); } private NoSqlTreeNode getParentNode() { NoSqlTreeNode lastPathComponent = getSelectedNode(); if (lastPathComponent == null) { return null; } return (NoSqlTreeNode) lastPathComponent.getParent(); } public NoSqlTreeNode getSelectedNode() { return (NoSqlTreeNode) editTableView.getTree().getLastSelectedPathComponent(); } public boolean canAddKey() { NoSqlTreeNode selectedNode = getSelectedNode(); if (selectedNode == null) { return false; } return selectedNode.getDescriptor() instanceof MongoKeyValueDescriptor; } public boolean canAddValue() { NoSqlTreeNode selectedNode = getSelectedNode(); if (selectedNode == null) { return false; } return selectedNode.getDescriptor() instanceof MongoValueDescriptor; } public void removeSelectedKey() { NoSqlTreeNode selectedNode = getSelectedNode(); if (selectedNode == null) { return; } TreeUtil.removeSelected(editTableView.getTree()); } private DBObject buildMongoDocument() { NoSqlTreeNode rootNode = (NoSqlTreeNode) editTableView.getTree().getModel().getRoot(); return JsonTreeModel.buildDBObject(rootNode); } @Override public void dispose() { editTableView = null; } private Object getDocumentId() { NoSqlTreeNode rootNode = (NoSqlTreeNode) editTableView.getTree().getModel().getRoot(); return findObjectIdNodeDescriptor(rootNode).getDescriptor().getValue(); } private NoSqlTreeNode findObjectIdNodeDescriptor(NoSqlTreeNode rootNode) { return ((NoSqlTreeNode) rootNode.getChildAt(0));//TODO crappy } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/MongoPanel.form ================================================
================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/MongoPanel.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view; import com.intellij.ide.CommonActionsManager; import com.intellij.ide.TreeExpander; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.ActionToolbar; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.LoadingDecorator; import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.util.Disposer; import com.intellij.ui.NumberDocument; import com.intellij.ui.components.panels.NonOpaquePanel; import com.mongodb.DBObject; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.codinjutsu.tools.nosql.commons.utils.GuiUtils; import org.codinjutsu.tools.nosql.commons.view.ErrorPanel; import org.codinjutsu.tools.nosql.commons.view.NoSqlResultView; import org.codinjutsu.tools.nosql.commons.view.action.ExecuteQuery; import org.codinjutsu.tools.nosql.mongo.logic.MongoClient; import org.codinjutsu.tools.nosql.mongo.model.MongoCollection; import org.codinjutsu.tools.nosql.mongo.model.MongoResult; import org.codinjutsu.tools.nosql.mongo.view.action.*; import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; public class MongoPanel extends NoSqlResultView { private final LoadingDecorator loadingDecorator; private JPanel rootPanel; private Splitter splitter; private JPanel toolBar; private JPanel errorPanel; private final JTextField rowLimitField = new JTextField(""); private final MongoResultPanel resultPanel; private final QueryPanel queryPanel; private final Project project; private final MongoClient mongoClient; private final ServerConfiguration configuration; private final MongoCollection mongoCollection; public MongoPanel(Project project, final MongoClient mongoClient, final ServerConfiguration configuration, final MongoCollection mongoCollection) { this.project = project; this.mongoClient = mongoClient; this.mongoCollection = mongoCollection; this.configuration = configuration; errorPanel.setLayout(new BorderLayout()); queryPanel = new QueryPanel(project); queryPanel.setVisible(false); resultPanel = createResultPanel(project, new MongoDocumentOperations() { public DBObject getMongoDocument(Object _id) { return mongoClient.findMongoDocument(configuration, mongoCollection, _id); } public void updateMongoDocument(DBObject mongoDocument) { mongoClient.update(configuration, mongoCollection, mongoDocument); executeQuery(); } public void deleteMongoDocument(Object objectId) { mongoClient.delete(configuration, mongoCollection, objectId); executeQuery(); } }); loadingDecorator = new LoadingDecorator(resultPanel, this, 0); splitter.setOrientation(true); splitter.setProportion(0.2f); splitter.setSecondComponent(loadingDecorator.getComponent()); setLayout(new BorderLayout()); add(rootPanel); initToolBar(); } private void initToolBar() { toolBar.setLayout(new BorderLayout()); rowLimitField.setColumns(5); rowLimitField.setDocument(new NumberDocument()); JPanel rowLimitPanel = new NonOpaquePanel(); rowLimitPanel.add(new JLabel("Row limit:"), BorderLayout.WEST); rowLimitPanel.add(rowLimitField, BorderLayout.CENTER); rowLimitPanel.add(Box.createHorizontalStrut(5), BorderLayout.EAST); toolBar.add(rowLimitPanel, BorderLayout.WEST); installResultPanelActions(); } private MongoResultPanel createResultPanel(Project project, MongoDocumentOperations mongoDocumentOperations) { return new MongoResultPanel(project, mongoDocumentOperations); } void installResultPanelActions() { DefaultActionGroup actionResultGroup = new DefaultActionGroup("MongoResultGroup", true); if (ApplicationManager.getApplication() != null) { actionResultGroup.add(new ExecuteQuery(this)); actionResultGroup.add(new OpenFindAction(this)); actionResultGroup.add(new EnableAggregateAction(queryPanel)); actionResultGroup.addSeparator(); actionResultGroup.add(new AddMongoDocumentAction(resultPanel)); actionResultGroup.add(new EditMongoDocumentAction(resultPanel)); actionResultGroup.add(new CopyResultAction(resultPanel)); } final TreeExpander treeExpander = new TreeExpander() { @Override public void expandAll() { resultPanel.expandAll(); } @Override public boolean canExpand() { return true; } @Override public void collapseAll() { resultPanel.collapseAll(); } @Override public boolean canCollapse() { return true; } }; CommonActionsManager actionsManager = CommonActionsManager.getInstance(); final AnAction expandAllAction = actionsManager.createExpandAllAction(treeExpander, resultPanel); final AnAction collapseAllAction = actionsManager.createCollapseAllAction(treeExpander, resultPanel); Disposer.register(this, new Disposable() { @Override public void dispose() { collapseAllAction.unregisterCustomShortcutSet(resultPanel); expandAllAction.unregisterCustomShortcutSet(resultPanel); } }); actionResultGroup.addSeparator(); actionResultGroup.add(expandAllAction); actionResultGroup.add(collapseAllAction); actionResultGroup.add(new CloseFindEditorAction(this)); ActionToolbar actionToolBar = ActionManager.getInstance().createActionToolbar("MongoResultGroupActions", actionResultGroup, true); actionToolBar.setLayoutPolicy(ActionToolbar.AUTO_LAYOUT_POLICY); JComponent actionToolBarComponent = actionToolBar.getComponent(); actionToolBarComponent.setBorder(null); actionToolBarComponent.setOpaque(false); toolBar.add(actionToolBarComponent, BorderLayout.CENTER); } public MongoCollection getRecords() { return mongoCollection; } public void showResults() { executeQuery(); } public void executeQuery() { errorPanel.setVisible(false); validateQuery(); ProgressManager.getInstance().run(new Task.Backgroundable(project, "Executing query", true) { @Override public void run(@NotNull final ProgressIndicator indicator) { try { GuiUtils.runInSwingThread(new Runnable() { @Override public void run() { loadingDecorator.startLoading(false); } }); final MongoResult mongoResult = mongoClient.loadCollectionValues(configuration, mongoCollection, queryPanel.getQueryOptions(rowLimitField.getText())); GuiUtils.runInSwingThread(new Runnable() { @Override public void run() { resultPanel.updateResultTableTree(mongoResult); } }); } catch (final Exception ex) { GuiUtils.runInSwingThread(new Runnable() { @Override public void run() { errorPanel.invalidate(); errorPanel.removeAll(); errorPanel.add(new ErrorPanel(ex), BorderLayout.CENTER); errorPanel.validate(); errorPanel.setVisible(true); } }); } finally { GuiUtils.runInSwingThread(new Runnable() { @Override public void run() { loadingDecorator.stopLoading(); } }); } } }); } private void validateQuery() { queryPanel.validateQuery(); } @Override public void dispose() { resultPanel.dispose(); } public MongoResultPanel getResultPanel() { return resultPanel; } public void openFindEditor() { queryPanel.setVisible(true); splitter.setFirstComponent(queryPanel); GuiUtils.runInSwingThread(new Runnable() { @Override public void run() { focusOnEditor(); } }); } public void closeFindEditor() { splitter.setFirstComponent(null); queryPanel.setVisible(false); } public void focusOnEditor() { queryPanel.requestFocusOnEditor(); } public boolean isFindEditorOpened() { return splitter.getFirstComponent() == queryPanel; } interface MongoDocumentOperations { DBObject getMongoDocument(Object _id); void deleteMongoDocument(Object mongoDocument); void updateMongoDocument(DBObject mongoDocument); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/MongoResultPanel.form ================================================
================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/MongoResultPanel.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.ui.popup.Balloon; import com.intellij.openapi.util.Disposer; import com.intellij.ui.PopupHandler; import com.intellij.ui.components.JBScrollPane; import com.intellij.ui.treeStructure.treetable.TreeTableTree; import com.intellij.util.ui.tree.TreeUtil; import com.mongodb.DBObject; import org.apache.commons.lang.StringUtils; import org.codinjutsu.tools.nosql.commons.utils.GuiUtils; import org.codinjutsu.tools.nosql.commons.view.NoSqlTreeNode; import org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor; import org.codinjutsu.tools.nosql.mongo.model.MongoResult; import org.codinjutsu.tools.nosql.mongo.view.action.CopyResultAction; import org.codinjutsu.tools.nosql.mongo.view.action.EditMongoDocumentAction; import org.codinjutsu.tools.nosql.mongo.view.model.JsonTreeModel; import org.codinjutsu.tools.nosql.mongo.view.nodedescriptor.MongoKeyValueDescriptor; import org.codinjutsu.tools.nosql.mongo.view.nodedescriptor.MongoResultDescriptor; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.LinkedList; import java.util.List; public class MongoResultPanel extends JPanel implements Disposable { private final MongoPanel.MongoDocumentOperations mongoDocumentOperations; private JPanel mainPanel; private JPanel containerPanel; private final Splitter splitter; private final JPanel resultTreePanel; private final MongoEditionPanel mongoEditionPanel; JsonTreeTableView resultTableView; public MongoResultPanel(Project project, MongoPanel.MongoDocumentOperations mongoDocumentOperations) { this.mongoDocumentOperations = mongoDocumentOperations; setLayout(new BorderLayout()); add(mainPanel, BorderLayout.CENTER); splitter = new Splitter(true, 0.6f); resultTreePanel = new JPanel(new BorderLayout()); splitter.setFirstComponent(resultTreePanel); mongoEditionPanel = createMongoEditionPanel(); containerPanel.setLayout(new BorderLayout()); containerPanel.add(splitter); Disposer.register(project, this); } private MongoEditionPanel createMongoEditionPanel() { return new MongoEditionPanel().init(mongoDocumentOperations, new ActionCallback() { public void onOperationSuccess(String message) { hideEditionPanel(); GuiUtils.showNotification(MongoResultPanel.this.resultTreePanel, MessageType.INFO, message, Balloon.Position.above); } @Override public void onOperationFailure(Exception exception) { GuiUtils.showNotification(MongoResultPanel.this.resultTreePanel, MessageType.ERROR, exception.getMessage(), Balloon.Position.above); } @Override public void onOperationCancelled(String message) { hideEditionPanel(); } }); } public void updateResultTableTree(MongoResult mongoResult) { resultTableView = new JsonTreeTableView(JsonTreeModel.buildJsonTree(mongoResult), JsonTreeTableView.COLUMNS_FOR_READING); resultTableView.setName("resultTreeTable"); resultTableView.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent mouseEvent) { if (mouseEvent.getClickCount() == 2 && MongoResultPanel.this.isSelectedNodeId()) { MongoResultPanel.this.editSelectedMongoDocument(); } } }); buildPopupMenu(); resultTreePanel.invalidate(); resultTreePanel.removeAll(); resultTreePanel.add(new JBScrollPane(resultTableView)); resultTreePanel.validate(); } void buildPopupMenu() { DefaultActionGroup actionPopupGroup = new DefaultActionGroup("MongoResultPopupGroup", true); if (ApplicationManager.getApplication() != null) { actionPopupGroup.add(new EditMongoDocumentAction(this)); actionPopupGroup.add(new CopyResultAction(this)); } PopupHandler.installPopupHandler(resultTableView, actionPopupGroup, "POPUP", ActionManager.getInstance()); } public void editSelectedMongoDocument() { DBObject mongoDocument = getSelectedMongoDocument(); if (mongoDocument == null) { return; } mongoEditionPanel.updateEditionTree(mongoDocument); splitter.setSecondComponent(mongoEditionPanel); } public void addMongoDocument() { mongoEditionPanel.updateEditionTree(null); splitter.setSecondComponent(mongoEditionPanel); } private DBObject getSelectedMongoDocument() { TreeTableTree tree = resultTableView.getTree(); NoSqlTreeNode treeNode = (NoSqlTreeNode) tree.getLastSelectedPathComponent(); if (treeNode == null) { return null; } NodeDescriptor descriptor = treeNode.getDescriptor(); if (descriptor instanceof MongoKeyValueDescriptor) { MongoKeyValueDescriptor keyValueDescriptor = (MongoKeyValueDescriptor) descriptor; if (StringUtils.equals(keyValueDescriptor.getKey(), "_id")) { return mongoDocumentOperations.getMongoDocument(keyValueDescriptor.getValue()); } } return null; } public boolean isSelectedNodeId() { if (resultTableView == null) { return false; } TreeTableTree tree = resultTableView.getTree(); NoSqlTreeNode treeNode = (NoSqlTreeNode) tree.getLastSelectedPathComponent(); if (treeNode == null) { return false; } NodeDescriptor descriptor = treeNode.getDescriptor(); if (descriptor instanceof MongoKeyValueDescriptor) { MongoKeyValueDescriptor keyValueDescriptor = (MongoKeyValueDescriptor) descriptor; return StringUtils.equals(keyValueDescriptor.getKey(), "_id"); } return false; } void expandAll() { TreeUtil.expandAll(resultTableView.getTree()); } void collapseAll() { TreeTableTree tree = resultTableView.getTree(); TreeUtil.collapseAll(tree, 1); } public String getSelectedNodeStringifiedValue() { NoSqlTreeNode lastSelectedResultNode = (NoSqlTreeNode) resultTableView.getTree().getLastSelectedPathComponent(); if (lastSelectedResultNode == null) { lastSelectedResultNode = (NoSqlTreeNode) resultTableView.getTree().getModel().getRoot(); } NodeDescriptor userObject = lastSelectedResultNode.getDescriptor(); if (userObject instanceof MongoResultDescriptor) { return stringifyResult(lastSelectedResultNode); } return userObject.toString(); } private void hideEditionPanel() { splitter.setSecondComponent(null); } private String stringifyResult(DefaultMutableTreeNode selectedResultNode) { List stringifiedObjects = new LinkedList(); for (int i = 0; i < selectedResultNode.getChildCount(); i++) { DefaultMutableTreeNode childNode = (DefaultMutableTreeNode) selectedResultNode.getChildAt(i); stringifiedObjects.add(childNode.getUserObject()); } return String.format("[ %s ]", StringUtils.join(stringifiedObjects, " , ")); } @Override public void dispose() { resultTableView = null; mongoEditionPanel.dispose(); } public interface ActionCallback { void onOperationSuccess(String message); void onOperationFailure(Exception exception); void onOperationCancelled(String message); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/QueryPanel.form ================================================
================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/QueryPanel.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view; import com.intellij.lang.Language; import com.intellij.openapi.Disposable; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.EditorFactory; import com.intellij.openapi.editor.EditorSettings; import com.intellij.openapi.editor.colors.EditorColors; import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.editor.ex.util.LexerEditorHighlighter; import com.intellij.openapi.editor.highlighter.EditorHighlighter; import com.intellij.openapi.fileTypes.PlainTextSyntaxHighlighterFactory; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.popup.Balloon; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.ui.awt.RelativePoint; import com.intellij.ui.components.panels.NonOpaquePanel; import com.intellij.util.Alarm; import com.intellij.util.ui.UIUtil; import com.mongodb.util.JSON; import com.mongodb.util.JSONParseException; import org.apache.commons.lang.StringUtils; import org.codinjutsu.tools.nosql.mongo.model.MongoQueryOptions; import org.codinjutsu.tools.nosql.mongo.view.action.OperatorCompletionAction; import javax.swing.*; import java.awt.*; public class QueryPanel extends JPanel implements Disposable { private static final Font COURIER_FONT = new Font("Courier", Font.PLAIN, UIUtil.getLabelFont().getSize()); private static final String FILTER_PANEL = "FilterPanel"; private static final String AGGREGATION_PANEL = "AggregationPanel"; private final Alarm myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); private final Project project; private JPanel mainPanel; private final CardLayout queryCardLayout; private JPanel queryContainerPanel; private final OperatorPanel filterPanel; private final OperatorPanel aggregationPanel; public QueryPanel(Project project) { this.project = project; setLayout(new BorderLayout()); add(mainPanel); queryCardLayout = new CardLayout(); queryContainerPanel.setLayout(queryCardLayout); filterPanel = createFilterPanel(); queryContainerPanel.add(filterPanel, FILTER_PANEL); aggregationPanel = createAggregationPanel(); queryContainerPanel.add(aggregationPanel, AGGREGATION_PANEL); toggleToFind(); Disposer.register(project, this); } private OperatorPanel createAggregationPanel() { return new AggregatorPanel(); } private OperatorPanel createFilterPanel() { return new FilterPanel(); } public void requestFocusOnEditor() {// Code from requestFocus of EditorImpl final IdeFocusManager focusManager = IdeFocusManager.getInstance(this.project); JComponent editorContentComponent = getCurrentOperatorPanel().getRequestFocusComponent(); if (focusManager.getFocusOwner() != editorContentComponent) { focusManager.requestFocus(editorContentComponent, true); } } public OperatorPanel getCurrentOperatorPanel() { return filterPanel.isVisible() ? filterPanel : aggregationPanel; } private static void fillEditorSettings(final EditorSettings editorSettings) { editorSettings.setWhitespacesShown(true); editorSettings.setLineMarkerAreaShown(false); editorSettings.setIndentGuidesShown(false); editorSettings.setLineNumbersShown(false); editorSettings.setAllowSingleLogicalLineFolding(true); editorSettings.setAdditionalColumnsCount(0); editorSettings.setAdditionalLinesCount(1); editorSettings.setUseSoftWraps(true); editorSettings.setUseTabCharacter(false); editorSettings.setCaretInsideTabs(false); editorSettings.setVirtualSpace(false); } private void attachHighlighter(final EditorEx editor) { EditorColorsScheme scheme = editor.getColorsScheme(); scheme.setColor(EditorColors.CARET_ROW_COLOR, null); editor.setHighlighter(createHighlighter(scheme)); } private EditorHighlighter createHighlighter(EditorColorsScheme settings) { Language language = Language.findLanguageByID("JSON"); if (language == null) { language = Language.ANY; } return new LexerEditorHighlighter(PlainTextSyntaxHighlighterFactory.getSyntaxHighlighter(language, null, null), settings); } public MongoQueryOptions getQueryOptions(String rowLimit) { return getCurrentOperatorPanel().buildQueryOptions(rowLimit); } @Override public void dispose() { myUpdateAlarm.cancelAllRequests(); filterPanel.dispose(); aggregationPanel.dispose(); } public void toggleToAggregation() { queryCardLayout.show(queryContainerPanel, AGGREGATION_PANEL); } public void toggleToFind() { queryCardLayout.show(queryContainerPanel, FILTER_PANEL); } public void validateQuery() { getCurrentOperatorPanel().validateQuery(); } private class AggregatorPanel extends OperatorPanel { private final Editor editor; private final OperatorCompletionAction operatorCompletionAction; private AggregatorPanel() { this.editor = createEditor(); setLayout(new BorderLayout()); NonOpaquePanel headPanel = new NonOpaquePanel(); JLabel operatorLabel = new JLabel("Aggregation"); headPanel.add(operatorLabel, BorderLayout.WEST); add(headPanel, BorderLayout.NORTH); add(this.editor.getComponent(), BorderLayout.CENTER); this.operatorCompletionAction = new OperatorCompletionAction(project, editor); myUpdateAlarm.setActivationComponent(this.editor.getComponent()); } @Override public void validateQuery() { try { String query = getQuery(); if (StringUtils.isEmpty(query)) { return; } JSON.parse(query); } catch (JSONParseException ex) { notifyOnErrorForOperator(editor.getComponent(), ex); } catch (NumberFormatException ex) { notifyOnErrorForOperator(editor.getComponent(), ex); } } private String getQuery() { return String.format("[%s]", StringUtils.trim(this.editor.getDocument().getText())); } @Override public MongoQueryOptions buildQueryOptions(String rowLimit) { MongoQueryOptions mongoQueryOptions = new MongoQueryOptions(); try { mongoQueryOptions.setOperations(getQuery()); } catch (JSONParseException ex) { notifyOnErrorForOperator(editor.getComponent(), ex); } if (StringUtils.isNotBlank(rowLimit)) { mongoQueryOptions.setResultLimit(Integer.parseInt(rowLimit)); } return mongoQueryOptions; } @Override public JComponent getRequestFocusComponent() { return this.editor.getContentComponent(); } @Override public void dispose() { operatorCompletionAction.dispose(); EditorFactory.getInstance().releaseEditor(this.editor); } } private class FilterPanel extends OperatorPanel { private final Editor selectEditor; private final OperatorCompletionAction operatorCompletionAction; private final Editor projectionEditor; private final Editor sortEditor; private FilterPanel() { setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); this.selectEditor = createEditor(); this.operatorCompletionAction = new OperatorCompletionAction(project, selectEditor); add(createSubOperatorPanel("Filter", this.selectEditor)); this.projectionEditor = createEditor(); add(createSubOperatorPanel("Projection", this.projectionEditor)); this.sortEditor = createEditor(); add(createSubOperatorPanel("Sort", this.sortEditor)); } @Override public JComponent getRequestFocusComponent() { return this.selectEditor.getContentComponent(); } @Override public void validateQuery() { validateEditorQuery(selectEditor); validateEditorQuery(projectionEditor); validateEditorQuery(sortEditor); } @Override public MongoQueryOptions buildQueryOptions(String rowLimit) { MongoQueryOptions mongoQueryOptions = new MongoQueryOptions(); try { mongoQueryOptions.setFilter(getQueryFrom(selectEditor)); mongoQueryOptions.setProjection(getQueryFrom(projectionEditor)); mongoQueryOptions.setSort(getQueryFrom(sortEditor)); } catch (JSONParseException ex) { notifyOnErrorForOperator(selectEditor.getComponent(), ex); } if (StringUtils.isNotBlank(rowLimit)) { mongoQueryOptions.setResultLimit(Integer.parseInt(rowLimit)); } return mongoQueryOptions; } @Override public void dispose() { operatorCompletionAction.dispose(); EditorFactory.getInstance().releaseEditor(this.selectEditor); EditorFactory.getInstance().releaseEditor(this.projectionEditor); EditorFactory.getInstance().releaseEditor(this.sortEditor); } private void validateEditorQuery(Editor editor) { try { String query = getQueryFrom(editor); if (StringUtils.isEmpty(query)) { return; } JSON.parse(query); } catch (JSONParseException ex) { notifyOnErrorForOperator(editor.getComponent(), ex); } catch (NumberFormatException ex) { notifyOnErrorForOperator(editor.getComponent(), ex); } } private String getQueryFrom(Editor editor) { return StringUtils.trim(editor.getDocument().getText()); } private JPanel createSubOperatorPanel(String title, Editor subOperatorEditor) { JPanel selectPanel = new JPanel(); selectPanel.setLayout(new BorderLayout()); NonOpaquePanel headPanel = new NonOpaquePanel(); JLabel operatorLabel = new JLabel(title); headPanel.add(operatorLabel, BorderLayout.WEST); selectPanel.add(headPanel, BorderLayout.NORTH); selectPanel.add(subOperatorEditor.getComponent(), BorderLayout.CENTER); myUpdateAlarm.setActivationComponent(subOperatorEditor.getComponent()); return selectPanel; } } private abstract class OperatorPanel extends JPanel implements Disposable { public abstract JComponent getRequestFocusComponent(); public abstract void validateQuery(); public abstract MongoQueryOptions buildQueryOptions(String rowLimit); void notifyOnErrorForOperator(JComponent component, Exception ex) { String message; if (ex instanceof JSONParseException) { message = StringUtils.removeStart(ex.getMessage(), "\n"); } else { message = String.format("%s: %s", ex.getClass().getSimpleName(), ex.getMessage()); } NonOpaquePanel nonOpaquePanel = new NonOpaquePanel(); JTextPane textPane = Messages.configureMessagePaneUi(new JTextPane(), message); textPane.setFont(COURIER_FONT); textPane.setBackground(MessageType.ERROR.getPopupBackground()); nonOpaquePanel.add(textPane, BorderLayout.CENTER); nonOpaquePanel.add(new JLabel(MessageType.ERROR.getDefaultIcon()), BorderLayout.WEST); JBPopupFactory.getInstance().createBalloonBuilder(nonOpaquePanel) .setFillColor(MessageType.ERROR.getPopupBackground()) .createBalloon() .show(new RelativePoint(component, new Point(0, 0)), Balloon.Position.above); } protected Editor createEditor() { EditorFactory editorFactory = EditorFactory.getInstance(); Document editorDocument = editorFactory.createDocument(""); Editor editor = editorFactory.createEditor(editorDocument, project); fillEditorSettings(editor.getSettings()); EditorEx editorEx = (EditorEx) editor; attachHighlighter(editorEx); return editor; } } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/action/AddMongoDocumentAction.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view.action; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.project.DumbAware; import org.codinjutsu.tools.nosql.mongo.view.MongoResultPanel; import java.awt.event.KeyEvent; public class AddMongoDocumentAction extends AnAction implements DumbAware { private final MongoResultPanel resultPanel; public AddMongoDocumentAction(MongoResultPanel resultPanel) { super("Add", "Add mongo document", AllIcons.General.Add); registerCustomShortcutSet(KeyEvent.VK_INSERT, KeyEvent.ALT_MASK, resultPanel); this.resultPanel = resultPanel; } @Override public void actionPerformed(AnActionEvent anActionEvent) { resultPanel.addMongoDocument(); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/action/CloseFindEditorAction.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view.action; import com.intellij.icons.AllIcons; import com.intellij.ide.actions.CloseTabToolbarAction; import com.intellij.openapi.actionSystem.AnActionEvent; import org.codinjutsu.tools.nosql.mongo.view.MongoPanel; import java.awt.event.KeyEvent; public class CloseFindEditorAction extends CloseTabToolbarAction { private final MongoPanel mongoPanel; public CloseFindEditorAction(MongoPanel mongoPanel) { getTemplatePresentation().setIcon(AllIcons.Actions.Close); registerCustomShortcutSet(KeyEvent.VK_ESCAPE, 0, mongoPanel); this.mongoPanel = mongoPanel; } @Override public void actionPerformed(AnActionEvent e) { mongoPanel.closeFindEditor(); } @Override public void update(AnActionEvent event) { event.getPresentation().setVisible(false); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/action/CopyResultAction.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view.action; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.ide.CopyPasteManager; import com.intellij.openapi.project.DumbAware; import org.codinjutsu.tools.nosql.mongo.view.MongoResultPanel; import java.awt.*; import java.awt.datatransfer.StringSelection; import java.awt.event.KeyEvent; public class CopyResultAction extends AnAction implements DumbAware { private final MongoResultPanel mongoResultPanel; public CopyResultAction(MongoResultPanel mongoResultPanel) { super("Copy", "Copy results to clipboard", AllIcons.Actions.Copy); this.mongoResultPanel = mongoResultPanel; registerCustomShortcutSet(KeyEvent.VK_C, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), mongoResultPanel); } @Override public void actionPerformed(AnActionEvent anActionEvent) { CopyPasteManager.getInstance().setContents(new StringSelection(mongoResultPanel.getSelectedNodeStringifiedValue())); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/action/DropCollectionAction.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view.action; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.project.DumbAware; import org.codinjutsu.tools.nosql.NoSqlExplorerPanel; import javax.swing.*; public class DropCollectionAction extends AnAction implements DumbAware { private static final Icon REMOVE_ICON = AllIcons.Actions.GC; private final NoSqlExplorerPanel noSqlExplorerPanel; public DropCollectionAction(NoSqlExplorerPanel noSqlExplorerPanel) { super("Drop collection", "Drop the selected collection", REMOVE_ICON); this.noSqlExplorerPanel = noSqlExplorerPanel; } @Override public void actionPerformed(AnActionEvent anActionEvent) { int result = JOptionPane.showConfirmDialog(null, String.format("Do you REALLY want to drop the '%s' collection?", noSqlExplorerPanel.getSelectedCollection().getName()), "Warning", JOptionPane.YES_NO_OPTION); if (result == JOptionPane.YES_OPTION) { noSqlExplorerPanel.dropCollection(); } } @Override public void update(AnActionEvent event) { event.getPresentation().setVisible(noSqlExplorerPanel.getSelectedCollection() != null); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/action/DropDatabaseAction.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view.action; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.project.DumbAware; import org.codinjutsu.tools.nosql.NoSqlExplorerPanel; import javax.swing.*; /** * Created by piddubnyi on 06.11.14 . */ public class DropDatabaseAction extends AnAction implements DumbAware { private static final Icon REMOVE_ICON = AllIcons.Actions.GC; private final NoSqlExplorerPanel noSqlExplorerPanel; public DropDatabaseAction(NoSqlExplorerPanel noSqlExplorerPanel) { super("Drop Database", "Drop the selected database", REMOVE_ICON); this.noSqlExplorerPanel = noSqlExplorerPanel; } @Override public void actionPerformed(AnActionEvent anActionEvent) { int result = JOptionPane.showConfirmDialog(null, String.format("Do you REALLY want to drop the '%s' database?", noSqlExplorerPanel.getSelectedMongoDatabase().getName()), "Warning", JOptionPane.YES_NO_OPTION); if (result == JOptionPane.YES_OPTION) { noSqlExplorerPanel.dropDatabase(); } } @Override public void update(AnActionEvent event) { event.getPresentation().setVisible(noSqlExplorerPanel.getSelectedMongoDatabase() != null); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/action/EditMongoDocumentAction.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view.action; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.project.DumbAware; import org.codinjutsu.tools.nosql.mongo.view.MongoResultPanel; public class EditMongoDocumentAction extends AnAction implements DumbAware { private final MongoResultPanel resultPanel; public EditMongoDocumentAction(MongoResultPanel resultPanel) { super("Edit", "Edit mongo document", AllIcons.Actions.Edit); this.resultPanel = resultPanel; } @Override public void actionPerformed(AnActionEvent anActionEvent) { resultPanel.editSelectedMongoDocument(); } @Override public void update(AnActionEvent event) { super.update(event); event.getPresentation().setVisible(resultPanel.isSelectedNodeId()); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/action/EnableAggregateAction.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view.action; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.ToggleAction; import org.codinjutsu.tools.nosql.commons.utils.GuiUtils; import org.codinjutsu.tools.nosql.mongo.view.QueryPanel; import javax.swing.*; public class EnableAggregateAction extends ToggleAction { private static final String ENABLE_FIND_MODE = "Toggle to Find Mode"; private static final String ENABLE_AGGREGATION_MODE = "Toggle to Aggregation Mode"; private static final Icon AGGREGATION_ICON = GuiUtils.loadIcon("sqlGroupByType.png"); private static final String QUERY_FIND_SAMPLE = "ex: {'name': 'foo'}"; private static final String QUERY_AGGREGATION_SAMPLE = "ex: [{'$match': {'name': 'foo'}, {'$project': {'address': 1}}]"; private final QueryPanel queryPanel; private boolean enableAggregation = false; public EnableAggregateAction(final QueryPanel queryPanel) { super(ENABLE_AGGREGATION_MODE, QUERY_FIND_SAMPLE, AGGREGATION_ICON); this.queryPanel = queryPanel; } @Override public boolean isSelected(AnActionEvent anActionEvent) { return enableAggregation; } @Override public void setSelected(AnActionEvent event, boolean enableAggregation) { this.enableAggregation = enableAggregation; if (enableAggregation) { queryPanel.toggleToAggregation(); } else { queryPanel.toggleToFind(); } } @Override public void update(AnActionEvent event) { event.getPresentation().setText(isSelected(event) ? ENABLE_FIND_MODE : ENABLE_AGGREGATION_MODE); event.getPresentation().setDescription(isSelected(event) ? QUERY_AGGREGATION_SAMPLE : QUERY_FIND_SAMPLE); event.getPresentation().setVisible(queryPanel.isVisible()); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/action/OpenFindAction.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view.action; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.project.DumbAware; import org.codinjutsu.tools.nosql.mongo.view.MongoPanel; import java.awt.event.KeyEvent; public class OpenFindAction extends AnAction implements DumbAware { private final MongoPanel mongoPanel; public OpenFindAction(MongoPanel mongoPanel) { super("Find", "Open Find editor", AllIcons.Actions.Find); this.mongoPanel = mongoPanel; registerCustomShortcutSet(KeyEvent.VK_F, KeyEvent.CTRL_MASK, mongoPanel); } @Override public void actionPerformed(AnActionEvent e) { if (!mongoPanel.isFindEditorOpened()) { mongoPanel.openFindEditor(); } else { mongoPanel.focusOnEditor(); } } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/action/OperatorCompletionAction.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view.action; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.application.Result; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.editor.CaretModel; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.PopupChooserBuilder; import com.intellij.ui.components.JBList; import com.mongodb.QueryOperators; import org.codinjutsu.tools.nosql.mongo.model.MongoAggregateOperator; import org.jetbrains.annotations.NotNull; import java.awt.event.KeyEvent; import java.lang.reflect.Field; import java.util.LinkedList; import java.util.List; public class OperatorCompletionAction extends AnAction implements Disposable { private static final String MONGO_OPERATOR_COMPLETION = "MONGO_OPERATOR_COMPLETION"; private static final JBList QUERY_OPERATOR_LIST; static { List operator = new LinkedList(); for (MongoAggregateOperator aggregateOperator : MongoAggregateOperator.values()) { operator.add(aggregateOperator.getLabel()); } for (Field field : QueryOperators.class.getFields()) { try { operator.add((String) QueryOperators.class.getDeclaredField(field.getName()).get(String.class)); } catch (IllegalAccessException e) { } catch (NoSuchFieldException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } } QUERY_OPERATOR_LIST = new JBList(operator); } private final Project project; private final Editor editor; public OperatorCompletionAction(Project project, Editor editor) { this.project = project; this.editor = editor; registerCustomShortcutSet(KeyEvent.VK_SPACE, KeyEvent.CTRL_MASK, editor.getContentComponent()); } @Override public void actionPerformed(AnActionEvent anActionEvent) { final Document document = editor.getDocument(); CaretModel caretModel = editor.getCaretModel(); final int offset = caretModel.getOffset(); new PopupChooserBuilder(QUERY_OPERATOR_LIST) .setMovable(false) .setCancelKeyEnabled(true) .setItemChoosenCallback(new Runnable() { public void run() { final String selectedQueryOperator = (String) QUERY_OPERATOR_LIST.getSelectedValue(); if (selectedQueryOperator == null) return; new WriteCommandAction(project, MONGO_OPERATOR_COMPLETION) { @Override protected void run(@NotNull Result result) throws Throwable { document.insertString(offset, selectedQueryOperator); } }.execute(); } }) .createPopup() .showInBestPositionFor(editor); } @Override public void dispose() { unregisterCustomShortcutSet(editor.getContentComponent()); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/action/edition/AddKeyAction.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view.action.edition; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import org.codinjutsu.tools.nosql.mongo.view.AddKeyDialog; import org.codinjutsu.tools.nosql.mongo.view.MongoEditionPanel; import java.awt.event.KeyEvent; public class AddKeyAction extends AnAction { private final MongoEditionPanel mongoEditionPanel; public AddKeyAction(MongoEditionPanel mongoEditionPanel) { super("Add a key", "Add a key", AllIcons.General.Add); registerCustomShortcutSet(KeyEvent.VK_INSERT, KeyEvent.ALT_MASK, mongoEditionPanel); this.mongoEditionPanel = mongoEditionPanel; } @Override public void actionPerformed(AnActionEvent anActionEvent) { AddKeyDialog dialog = AddKeyDialog.createDialog(mongoEditionPanel); dialog.show(); if (!dialog.isOK()) { return; } mongoEditionPanel.addKey(dialog.getKey(), dialog.getValue()); } @Override public void update(AnActionEvent event) { // event.getPresentation().setVisible(mongoEditionPanel.canAddKey()); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/action/edition/AddValueAction.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view.action.edition; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import org.codinjutsu.tools.nosql.mongo.view.AddValueDialog; import org.codinjutsu.tools.nosql.mongo.view.MongoEditionPanel; public class AddValueAction extends AnAction { private final MongoEditionPanel mongoEditionPanel; public AddValueAction(MongoEditionPanel mongoEditionPanel) { super("Add a value", "Add a value", AllIcons.General.Add); this.mongoEditionPanel = mongoEditionPanel; } @Override public void actionPerformed(AnActionEvent anActionEvent) { AddValueDialog dialog = AddValueDialog.createDialog(mongoEditionPanel); dialog.show(); if (!dialog.isOK()) { return; } mongoEditionPanel.addValue(dialog.getValue()); } @Override public void update(AnActionEvent event) { event.getPresentation().setVisible(mongoEditionPanel.canAddValue()); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/action/edition/DeleteKeyAction.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view.action.edition; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import org.codinjutsu.tools.nosql.mongo.view.MongoEditionPanel; import java.awt.event.KeyEvent; public class DeleteKeyAction extends AnAction { private final MongoEditionPanel mongoEditionPanel; public DeleteKeyAction(MongoEditionPanel mongoEditionPanel) { super("Delete this", "Delete the selected node", AllIcons.Actions.Delete); registerCustomShortcutSet(KeyEvent.VK_DELETE, KeyEvent.ALT_MASK, mongoEditionPanel); this.mongoEditionPanel = mongoEditionPanel; } @Override public void actionPerformed(AnActionEvent anActionEvent) { mongoEditionPanel.removeSelectedKey(); } @Override public void update(AnActionEvent event) { event.getPresentation().setVisible(mongoEditionPanel.getSelectedNode() != null); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/console/MongoConsoleRunner.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view.console; import com.intellij.execution.ExecutionException; import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.execution.console.ConsoleHistoryController; import com.intellij.execution.console.ConsoleRootType; import com.intellij.execution.console.ProcessBackedConsoleExecuteActionHandler; import com.intellij.execution.process.OSProcessHandler; import com.intellij.execution.runners.AbstractConsoleRunnerWithHistory; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.psi.PsiFile; import com.mongodb.AuthenticationMechanism; import org.apache.commons.lang.StringUtils; import org.codinjutsu.tools.nosql.DatabaseVendor; import org.codinjutsu.tools.nosql.NoSqlConfiguration; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.codinjutsu.tools.nosql.commons.model.AuthenticationSettings; import org.codinjutsu.tools.nosql.commons.view.console.NoSqlConsoleView; import org.codinjutsu.tools.nosql.mongo.MongoUtils; import org.codinjutsu.tools.nosql.mongo.logic.MongoExtraSettings; import org.codinjutsu.tools.nosql.mongo.model.MongoDatabase; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class MongoConsoleRunner extends AbstractConsoleRunnerWithHistory { private static final Key MONGO_SHELL_FILE = Key.create("MONGO_SHELL_FILE"); private final ServerConfiguration serverConfiguration; private final MongoDatabase database; public MongoConsoleRunner(@NotNull Project project, ServerConfiguration serverConfiguration, MongoDatabase database) { super(project, "Mongo Shell", "/tmp"); this.serverConfiguration = serverConfiguration; this.database = database; } @Override protected NoSqlConsoleView createConsoleView() { NoSqlConsoleView res = new NoSqlConsoleView(getProject(), "Mongo Console", serverConfiguration); PsiFile file = res.getFile(); assert file.getContext() == null; file.putUserData(MONGO_SHELL_FILE, Boolean.TRUE); return res; } @Nullable @Override protected Process createProcess() throws ExecutionException { NoSqlConfiguration noSqlConfiguration = NoSqlConfiguration.getInstance(getProject()); String shellPath = noSqlConfiguration.getShellPath(DatabaseVendor.MONGO); final GeneralCommandLine commandLine = new GeneralCommandLine(); commandLine.setExePath(shellPath); commandLine.addParameter(MongoUtils.buildMongoUrl(serverConfiguration, database)); String shellWorkingDir = serverConfiguration.getShellWorkingDir(); if (StringUtils.isNotBlank(shellWorkingDir)) { commandLine.withWorkDirectory(shellWorkingDir); } AuthenticationSettings authenticationSettings = serverConfiguration.getAuthenticationSettings(); String username = authenticationSettings.getUsername(); if (StringUtils.isNotBlank(username)) { commandLine.addParameter("--username"); commandLine.addParameter(username); } String password = authenticationSettings.getPassword(); if (StringUtils.isNotBlank(password)) { commandLine.addParameter("--password"); commandLine.addParameter(password); } MongoExtraSettings mongoExtraSettings = new MongoExtraSettings(authenticationSettings.getExtras()); String authenticationDatabase = mongoExtraSettings.getAuthenticationDatabase(); if (StringUtils.isNotBlank(authenticationDatabase)) { commandLine.addParameter("--authenticationDatabase"); commandLine.addParameter(authenticationDatabase); } AuthenticationMechanism authenticationMecanism = mongoExtraSettings.getAuthenticationMechanism(); if (authenticationMecanism != null) { commandLine.addParameter("--authenticationMecanism"); commandLine.addParameter(authenticationMecanism.getMechanismName()); } String shellArgumentsLine = serverConfiguration.getShellArgumentsLine(); if (StringUtils.isNotBlank(shellArgumentsLine)) { commandLine.addParameters(shellArgumentsLine.split(" ")); } return commandLine.createProcess(); } @Override protected OSProcessHandler createProcessHandler(Process process) { return new OSProcessHandler(process, null); } @NotNull @Override protected ProcessBackedConsoleExecuteActionHandler createExecuteActionHandler() { ProcessBackedConsoleExecuteActionHandler handler = new ProcessBackedConsoleExecuteActionHandler(getProcessHandler(), false) { @Override public String getEmptyExecuteAction() { return "NoSql.Shell.Execute"; } }; new ConsoleHistoryController(new ConsoleRootType("Mongo Shell", null) { }, null, getConsoleView()).install(); return handler; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/editor/MongoFakeFileType.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view.editor; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.ex.FakeFileType; import com.intellij.openapi.vfs.VirtualFile; import org.codinjutsu.tools.nosql.commons.utils.GuiUtils; import org.jetbrains.annotations.NotNull; import javax.swing.*; public class MongoFakeFileType extends FakeFileType { public static final Icon MONGO_ICON = GuiUtils.loadIcon("mongodb.png"); public static final FileType INSTANCE = new MongoFakeFileType(); @Override public Icon getIcon() { return MONGO_ICON; } @Override public boolean isMyFileType(VirtualFile file) { return false; } @NotNull @Override public String getDefaultExtension() { return "json"; } @NotNull @Override public String getName() { return "MONGO"; } @NotNull @Override public String getDescription() { return "MONGO"; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/editor/MongoObjectFile.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view.editor; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.project.Project; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.codinjutsu.tools.nosql.commons.view.editor.NoSqlDatabaseObjectFile; import org.codinjutsu.tools.nosql.mongo.model.MongoCollection; import org.jetbrains.annotations.NotNull; public class MongoObjectFile extends NoSqlDatabaseObjectFile { private MongoCollection collection; public MongoObjectFile(Project project, ServerConfiguration configuration, MongoCollection collection) { super(project, configuration, String.format("%s/%s/%s", configuration.getLabel(), collection.getDatabaseName(), collection.getName())); this.collection = collection; } @NotNull public FileType getFileType() { return MongoFakeFileType.INSTANCE; } public MongoCollection getCollection() { return collection; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/model/JsonTreeModel.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view.model; import com.mongodb.BasicDBList; import com.mongodb.BasicDBObject; import com.mongodb.DBObject; import org.apache.commons.lang.StringUtils; import org.codinjutsu.tools.nosql.commons.view.NoSqlTreeNode; import org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor; import org.codinjutsu.tools.nosql.mongo.model.MongoResult; import org.codinjutsu.tools.nosql.mongo.view.nodedescriptor.MongoKeyValueDescriptor; import org.codinjutsu.tools.nosql.mongo.view.nodedescriptor.MongoResultDescriptor; import org.codinjutsu.tools.nosql.mongo.view.nodedescriptor.MongoValueDescriptor; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeNode; import java.util.Enumeration; import java.util.List; public class JsonTreeModel extends DefaultTreeModel { public JsonTreeModel(MongoResult mongoResult) { super(buildJsonTree(mongoResult)); } public static TreeNode buildJsonTree(MongoResult mongoResult) { NoSqlTreeNode rootNode = new NoSqlTreeNode(new MongoResultDescriptor(mongoResult.getCollectionName())); List mongoObjects = mongoResult.getMongoObjects(); int i = 0; for (DBObject mongoObject : mongoObjects) { if (mongoObject instanceof BasicDBList) { processDbObject(rootNode, mongoObject); } else if (mongoObject instanceof BasicDBObject) {//dead code? NoSqlTreeNode currentNode = new NoSqlTreeNode(MongoValueDescriptor.createDescriptor(i++, mongoObject)); processDbObject(currentNode, mongoObject); rootNode.add(currentNode); } } return rootNode; } public static TreeNode buildJsonTree(DBObject mongoObject) { NoSqlTreeNode rootNode = new NoSqlTreeNode(new MongoResultDescriptor());//TODO crappy processDbObject(rootNode, mongoObject); return rootNode; } public static void processDbObject(NoSqlTreeNode parentNode, DBObject mongoObject) { if (mongoObject instanceof BasicDBList) { BasicDBList mongoObjectList = (BasicDBList) mongoObject; for (int i = 0; i < mongoObjectList.size(); i++) { Object mongoObjectOfList = mongoObjectList.get(i); NoSqlTreeNode currentNode = new NoSqlTreeNode(MongoValueDescriptor.createDescriptor(i, mongoObjectOfList)); if (mongoObjectOfList instanceof DBObject) { processDbObject(currentNode, (DBObject) mongoObjectOfList); } parentNode.add(currentNode); } } else if (mongoObject instanceof BasicDBObject) { BasicDBObject basicDBObject = (BasicDBObject) mongoObject; for (String key : basicDBObject.keySet()) { Object value = basicDBObject.get(key); NoSqlTreeNode currentNode = new NoSqlTreeNode(MongoKeyValueDescriptor.createDescriptor(key, value)); if (value instanceof DBObject) { processDbObject(currentNode, (DBObject) value); } parentNode.add(currentNode); } } } public static DBObject buildDBObject(NoSqlTreeNode rootNode) { BasicDBObject basicDBObject = new BasicDBObject(); Enumeration children = rootNode.children(); while (children.hasMoreElements()) { NoSqlTreeNode node = (NoSqlTreeNode) children.nextElement(); MongoKeyValueDescriptor descriptor = (MongoKeyValueDescriptor) node.getDescriptor(); Object value = descriptor.getValue(); if (value instanceof DBObject) { if (value instanceof BasicDBList) { basicDBObject.put(descriptor.getKey(), buildDBList(node)); } else { basicDBObject.put(descriptor.getKey(), buildDBObject(node)); } } else { basicDBObject.put(descriptor.getKey(), value); } } return basicDBObject; } private static DBObject buildDBList(NoSqlTreeNode parentNode) { BasicDBList basicDBList = new BasicDBList(); Enumeration children = parentNode.children(); while (children.hasMoreElements()) { NoSqlTreeNode node = (NoSqlTreeNode) children.nextElement(); MongoValueDescriptor descriptor = (MongoValueDescriptor) node.getDescriptor(); Object value = descriptor.getValue(); if (value instanceof DBObject) { if (value instanceof BasicDBList) { basicDBList.add(buildDBList(node)); } else { basicDBList.add(buildDBObject(node)); } } else { basicDBList.add(value); } } return basicDBList; } public static NoSqlTreeNode findObjectIdNode(NoSqlTreeNode treeNode) { NodeDescriptor descriptor = treeNode.getDescriptor(); if (descriptor instanceof MongoResultDescriptor) { //defensive prog? return null; } if (descriptor instanceof MongoKeyValueDescriptor) { MongoKeyValueDescriptor keyValueDescriptor = (MongoKeyValueDescriptor) descriptor; if (StringUtils.equals(keyValueDescriptor.getKey(), "_id")) { return treeNode; } } NoSqlTreeNode parentTreeNode = (NoSqlTreeNode) treeNode.getParent(); if (parentTreeNode.getDescriptor() instanceof MongoValueDescriptor) { if (((NoSqlTreeNode) parentTreeNode.getParent()).getDescriptor() instanceof MongoResultDescriptor) { //find } } return null; } public static Object findDocument(NoSqlTreeNode startingNode) { if (startingNode.getDescriptor() instanceof MongoValueDescriptor) { if (((NoSqlTreeNode) startingNode.getParent()).getDescriptor() instanceof MongoResultDescriptor) { return startingNode.getDescriptor().getValue(); } } return null; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/nodedescriptor/MongoKeyValueDescriptor.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view.nodedescriptor; import com.intellij.ui.ColoredTableCellRenderer; import com.intellij.ui.ColoredTreeCellRenderer; import com.intellij.ui.SimpleTextAttributes; import com.mongodb.DBObject; import org.bson.types.ObjectId; import org.codinjutsu.tools.nosql.commons.style.StyleAttributesProvider; import org.codinjutsu.tools.nosql.commons.utils.DateUtils; import org.codinjutsu.tools.nosql.commons.utils.StringUtils; import org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor; import java.text.DateFormat; import java.util.Date; import java.util.Locale; public class MongoKeyValueDescriptor implements NodeDescriptor { protected static final String TO_STRING_TEMPLATE = "\"%s\" : %s"; protected final String key; protected Object value; private final SimpleTextAttributes valueTextAttributes; public static MongoKeyValueDescriptor createDescriptor(String key, Object value) { if (value == null) { return new MongoKeyNullValueDescriptor(key); } if (value instanceof Boolean) { return new MongoKeyValueDescriptor(key, value, StyleAttributesProvider.getBooleanAttribute()) { @Override public void setValue(Object value) { this.value = Boolean.valueOf((String) value); } }; } else if (value instanceof Integer) { return new MongoKeyValueDescriptor(key, value, StyleAttributesProvider.getNumberAttribute()) { @Override public void setValue(Object value) { this.value = Integer.valueOf((String) value); } }; } else if (value instanceof Double) { return new MongoKeyValueDescriptor(key, value, StyleAttributesProvider.getNumberAttribute()) { @Override public void setValue(Object value) { this.value = Double.valueOf((String) value); } }; } else if (value instanceof Long) { return new MongoKeyValueDescriptor(key, value, StyleAttributesProvider.getNumberAttribute()) { @Override public void setValue(Object value) { this.value = Long.valueOf((String) value); } }; } else if (value instanceof String) { return new MongoKeyStringValueDescriptor(key, (String) value); } else if (value instanceof Date) { return new MongoKeyDateValueDescriptor(key, (Date) value); } else if (value instanceof ObjectId) { return new MongoKeyValueDescriptor(key, value, StyleAttributesProvider.getObjectIdAttribute()); } else if (value instanceof DBObject) { return new MongoKeyValueDescriptor(key, value, StyleAttributesProvider.getObjectAttribute()); } else { return new MongoKeyValueDescriptor(key, value, StyleAttributesProvider.getStringAttribute()); } } private MongoKeyValueDescriptor(String key, Object value, SimpleTextAttributes valueTextAttributes) { this.key = key; this.value = value; this.valueTextAttributes = valueTextAttributes; } public void renderValue(ColoredTableCellRenderer cellRenderer, boolean isNodeExpanded) { if (!isNodeExpanded) { cellRenderer.append(getValueAndAbbreviateIfNecessary(), valueTextAttributes); } } public void renderNode(ColoredTreeCellRenderer cellRenderer) { cellRenderer.append(getFormattedKey(), StyleAttributesProvider.getKeyValueAttribute()); } public String getFormattedKey() { return key; } public String getFormattedValue() { return getValueAndAbbreviateIfNecessary(); } public String getKey() { return key; } public Object getValue() { return value; } public void setValue(Object value) { this.value = value; } @Override public String toString() { return String.format(TO_STRING_TEMPLATE, key, value); } protected String getValueAndAbbreviateIfNecessary() { String stringifiedValue = value.toString(); if (stringifiedValue.length() > MAX_LENGTH) { return StringUtils.abbreviateInCenter(stringifiedValue, MAX_LENGTH); } return stringifiedValue; } private static class MongoKeyNullValueDescriptor extends MongoKeyValueDescriptor { private MongoKeyNullValueDescriptor(String key) { super(key, null, StyleAttributesProvider.getNullAttribute()); } protected String getValueAndAbbreviateIfNecessary() { return "null"; } } private static class MongoKeyStringValueDescriptor extends MongoKeyValueDescriptor { private static final String STRING_SURROUNDED = "\"%s\""; private static final String TO_STRING_FOR_STRING_VALUE_TEMPLATE = "\"%s\" : \"%s\""; private MongoKeyStringValueDescriptor(String key, String value) { super(key, value, StyleAttributesProvider.getStringAttribute()); } @Override protected String getValueAndAbbreviateIfNecessary() { return String.format(STRING_SURROUNDED, value); } @Override public String toString() { return String.format(TO_STRING_FOR_STRING_VALUE_TEMPLATE, key, value); } } private static class MongoKeyDateValueDescriptor extends MongoKeyValueDescriptor { private static final DateFormat DATE_FORMAT = DateUtils.utcDateTime(Locale.getDefault()); private static final String TO_STRING_FOR_DATE_VALUE_TEMPLATE = "\"%s\" : \"%s\""; private MongoKeyDateValueDescriptor(String key, Date value) { super(key, value, StyleAttributesProvider.getStringAttribute()); } @Override protected String getValueAndAbbreviateIfNecessary() { return getFormattedDate(); } @Override public String toString() { return String.format(TO_STRING_FOR_DATE_VALUE_TEMPLATE, key, getFormattedDate()); } private String getFormattedDate() { return DATE_FORMAT.format(value); } } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/nodedescriptor/MongoResultDescriptor.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view.nodedescriptor; import com.intellij.ui.ColoredTableCellRenderer; import com.intellij.ui.ColoredTreeCellRenderer; import org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor; public class MongoResultDescriptor implements NodeDescriptor { private final String formattedText; public MongoResultDescriptor(String collectionName) { formattedText = String.format("results of '%s'", collectionName); } public MongoResultDescriptor() { this(""); } public void renderValue(ColoredTableCellRenderer cellRenderer, boolean isNodeExpanded) { } public void renderNode(ColoredTreeCellRenderer cellRenderer) { } public String getFormattedKey() { return formattedText; } @Override public String getFormattedValue() { return ""; } @Override public String getValue() { return null; } @Override public void setValue(Object value) { } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/nodedescriptor/MongoValueDescriptor.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view.nodedescriptor; import com.intellij.ui.ColoredTableCellRenderer; import com.intellij.ui.ColoredTreeCellRenderer; import com.intellij.ui.SimpleTextAttributes; import com.mongodb.DBObject; import org.codinjutsu.tools.nosql.commons.style.StyleAttributesProvider; import org.codinjutsu.tools.nosql.commons.utils.DateUtils; import org.codinjutsu.tools.nosql.commons.utils.StringUtils; import org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor; import java.text.DateFormat; import java.util.Date; import java.util.Locale; public class MongoValueDescriptor implements NodeDescriptor { private final int index; protected Object value; private final SimpleTextAttributes valueTextAttributes; public static MongoValueDescriptor createDescriptor(int index, Object value) { if (value == null) { return new MongoNullValueDescriptor(index); } if (value instanceof String) { return new MongoStringValueDescriptor(index, (String) value); } else if (value instanceof Boolean) { return new MongoValueDescriptor(index, value, StyleAttributesProvider.getBooleanAttribute()) { @Override public void setValue(Object value) { this.value = Boolean.parseBoolean((String) value); } }; } else if (value instanceof Number) { return new MongoValueDescriptor(index, value, StyleAttributesProvider.getNumberAttribute()) { @Override public void setValue(Object value) { this.value = Integer.parseInt((String) value); } }; } else if (value instanceof Date) { return new MongoDateValueDescriptor(index, (Date) value); } else if (value instanceof DBObject) { return new MongoValueDescriptor(index, value, StyleAttributesProvider.getObjectAttribute()); } else { return new MongoValueDescriptor(index, value, StyleAttributesProvider.getStringAttribute()); } } private MongoValueDescriptor(int index, Object value, SimpleTextAttributes valueTextAttributes) { this.index = index; this.value = value; this.valueTextAttributes = valueTextAttributes; } public void renderValue(ColoredTableCellRenderer cellRenderer, boolean isNodeExpanded) { if (!isNodeExpanded) { cellRenderer.append(getFormattedValue(), valueTextAttributes); } } public void renderNode(ColoredTreeCellRenderer cellRenderer) { cellRenderer.append(getFormattedKey(), StyleAttributesProvider.getIndexAttribute()); } public String getFormattedKey() { return String.format("[%s]", index); } public String getFormattedValue() { return String.format("%s", getValueAndAbbreviateIfNecessary()); } protected String getValueAndAbbreviateIfNecessary() { String stringifiedValue = value.toString(); if (stringifiedValue.length() > MAX_LENGTH) { return StringUtils.abbreviateInCenter(stringifiedValue, MAX_LENGTH); } return stringifiedValue; } public Object getValue() { return value; } public void setValue(Object value) { this.value = value; } @Override public String toString() { return value.toString(); } private static class MongoStringValueDescriptor extends MongoValueDescriptor { private MongoStringValueDescriptor(int index, String value) { super(index, value, StyleAttributesProvider.getStringAttribute()); } @Override public String getFormattedValue() { return String.format("\"%s\"", getValueAndAbbreviateIfNecessary()); } } private static class MongoNullValueDescriptor extends MongoValueDescriptor { private MongoNullValueDescriptor(int index) { super(index, null, StyleAttributesProvider.getNullAttribute()); } @Override public String getFormattedValue() { return "null"; } @Override public String toString() { return "null"; } } private static class MongoDateValueDescriptor extends MongoValueDescriptor { private static final DateFormat DATE_FORMAT = DateUtils.utcDateTime(Locale.getDefault()); private static final String TO_STRING_FOR_DATE_VALUE_TEMPLATE = "\"%s\""; private MongoDateValueDescriptor(int index, Date value) { super(index, value, StyleAttributesProvider.getStringAttribute()); } @Override protected String getValueAndAbbreviateIfNecessary() { return getFormattedDate(); } @Override public String toString() { return String.format(TO_STRING_FOR_DATE_VALUE_TEMPLATE, getFormattedDate()); } private String getFormattedDate() { return DATE_FORMAT.format(value); } } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/mongo/view/table/MongoDatePickerCellEditor.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view.table; import org.codinjutsu.tools.nosql.commons.utils.DateUtils; import org.codinjutsu.tools.nosql.commons.view.table.DateTimePicker; import org.jdesktop.swingx.table.DatePickerCellEditor; import javax.swing.*; import java.awt.event.ActionListener; import java.util.Locale; public class MongoDatePickerCellEditor extends DatePickerCellEditor { public MongoDatePickerCellEditor() { this.dateFormat = DateUtils.utcDateTime(Locale.getDefault()); datePicker = DateTimePicker.create(); datePicker.getEditor().setBorder(BorderFactory.createEmptyBorder(0, 1, 0, 1)); datePicker.getEditor().setEditable(false); } public void addActionListener(ActionListener actionListener) { datePicker.addActionListener(actionListener); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/redis/RedisUI.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.redis; import com.intellij.openapi.project.Project; import org.codinjutsu.tools.nosql.commons.DatabaseUI; import org.codinjutsu.tools.nosql.commons.view.AuthenticationView; import org.codinjutsu.tools.nosql.commons.view.NoSqlResultView; import org.codinjutsu.tools.nosql.commons.view.editor.NoSqlDatabaseObjectFile; import org.codinjutsu.tools.nosql.redis.logic.RedisClient; import org.codinjutsu.tools.nosql.redis.view.RedisAuthenticationPanel; import org.codinjutsu.tools.nosql.redis.view.RedisPanel; import org.codinjutsu.tools.nosql.redis.view.editor.RedisObjectFile; public class RedisUI implements DatabaseUI { @Override public AuthenticationView createAythenticationView() { return new RedisAuthenticationPanel(); } @Override public NoSqlResultView createResultPanel(Project project, NoSqlDatabaseObjectFile objectFile) { RedisObjectFile redisObjectFile = (RedisObjectFile) objectFile; return new RedisPanel(project, RedisClient.getInstance(project), redisObjectFile.getConfiguration(), redisObjectFile.getDatabase()); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/redis/RedisUtils.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.redis; import org.apache.commons.lang.StringUtils; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.codinjutsu.tools.nosql.redis.model.RedisDatabase; import redis.clients.jedis.Tuple; import java.util.LinkedList; import java.util.List; import java.util.Set; public class RedisUtils { public static String stringifySortedSet(Set sortedSet) { List stringifiedTuples = new LinkedList(); for (Tuple tuple : sortedSet) { stringifiedTuples.add(stringifyTuple(tuple)); } return String.format("{%s}", StringUtils.join(stringifiedTuples, ", ")); } public static String stringifySet(Set set) { return String.format("{%s}", StringUtils.join(set, ", ")); } public static String stringifyTuple(Tuple tuple) { return String.format("(%s, %s)", tuple.getElement(), tuple.getScore()); } public static String buildUrl(ServerConfiguration serverConfiguration, RedisDatabase database) { return String.format("-n %s", database.getName()); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/redis/logic/RedisClient.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.redis.logic; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import org.apache.commons.lang.StringUtils; import org.codinjutsu.tools.nosql.DatabaseVendor; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.codinjutsu.tools.nosql.commons.logic.DatabaseClient; import org.codinjutsu.tools.nosql.commons.model.AuthenticationSettings; import org.codinjutsu.tools.nosql.commons.model.Database; import org.codinjutsu.tools.nosql.commons.model.DatabaseServer; import org.codinjutsu.tools.nosql.redis.model.RedisDatabase; import org.codinjutsu.tools.nosql.redis.model.RedisKeyType; import org.codinjutsu.tools.nosql.redis.model.RedisQuery; import org.codinjutsu.tools.nosql.redis.model.RedisResult; import redis.clients.jedis.Jedis; import redis.clients.jedis.Tuple; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; public class RedisClient implements DatabaseClient { public static RedisClient getInstance(Project project) { return ServiceManager.getService(project, RedisClient.class); } @Override public void connect(ServerConfiguration serverConfiguration) { Jedis jedis = createJedis(serverConfiguration); jedis.connect(); String userDatabase = serverConfiguration.getUserDatabase(); int index = 0; if (StringUtils.isNotEmpty(userDatabase)) { index = Integer.parseInt(userDatabase); } jedis.select(index); } @Override public void loadServer(DatabaseServer databaseServer) { Jedis jedis = createJedis(databaseServer.getConfiguration()); List databaseNumberTuple = jedis.configGet("databases"); List databases = new LinkedList<>(); String userDatabase = databaseServer.getConfiguration().getUserDatabase(); if (StringUtils.isNotEmpty(userDatabase)) { databases.add(new RedisDatabase(userDatabase)); } else { int totalNumberOfDatabase = Integer.parseInt(databaseNumberTuple.get(1)); for (int databaseNumber = 0; databaseNumber < totalNumberOfDatabase; databaseNumber++) { databases.add(new RedisDatabase(String.valueOf(databaseNumber))); } } databaseServer.setDatabases(databases); } @Override public void cleanUpServers() { } @Override public void registerServer(DatabaseServer databaseServer) { } @Override public ServerConfiguration defaultConfiguration() { ServerConfiguration configuration = new ServerConfiguration(); configuration.setDatabaseVendor(DatabaseVendor.REDIS); configuration.setServerUrl(DatabaseVendor.REDIS.defaultUrl); configuration.setAuthenticationSettings(new AuthenticationSettings()); return configuration; } public RedisResult loadRecords(ServerConfiguration serverConfiguration, RedisDatabase database, RedisQuery query) { Jedis jedis = createJedis(serverConfiguration); jedis.connect(); RedisResult redisResult = new RedisResult(); int index = Integer.parseInt(database.getName()); jedis.select(index); Set keys = jedis.keys(query.getFilter()); for (String key : keys) { RedisKeyType keyType = RedisKeyType.getKeyType(jedis.type(key)); if (RedisKeyType.LIST.equals(keyType)) { List values = jedis.lrange(key, 0, -1); redisResult.addList(key, values); } else if (RedisKeyType.SET.equals(keyType)) { Set values = jedis.smembers(key); redisResult.addSet(key, values); } else if (RedisKeyType.HASH.equals(keyType)) { Map values = jedis.hgetAll(key); redisResult.addHash(key, values); } else if (RedisKeyType.ZSET.equals(keyType)) { Set valuesWithScores = jedis.zrangeByScoreWithScores(key, "-inf", "+inf"); redisResult.addSortedSet(key, valuesWithScores); } else if (RedisKeyType.STRING.equals(keyType)) { String value = jedis.get(key); redisResult.addString(key, value); } } return redisResult; } private Jedis createJedis(ServerConfiguration serverConfiguration) { String redisUri = "redis://"; String password = serverConfiguration.getAuthenticationSettings().getPassword(); if (StringUtils.isNotEmpty(password)) { redisUri += ":" + password + "@"; } redisUri += serverConfiguration.getServerUrl(); return new Jedis(redisUri); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/redis/model/RedisDatabase.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.redis.model; import org.codinjutsu.tools.nosql.commons.model.Database; public class RedisDatabase extends Database { public RedisDatabase(String name) { super(name); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/redis/model/RedisKeyType.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.redis.model; import org.apache.commons.lang.StringUtils; public enum RedisKeyType { LIST("list"), SET("set"), ZSET("zset"), HASH("hash"), STRING("string"); public final String label; RedisKeyType(String label) { this.label = label; } public static RedisKeyType getKeyType(String type) { for (RedisKeyType keyType : RedisKeyType.values()) { if (StringUtils.equals(type, keyType.label)) { return keyType; } } return null; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/redis/model/RedisQuery.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.redis.model; public class RedisQuery { private String filter; public RedisQuery(String filter) { this.filter = filter; } public String getFilter() { return filter; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/redis/model/RedisRecord.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.redis.model; public class RedisRecord { private final RedisKeyType keyType; private final String keyName; private final T keyValue; public RedisRecord(RedisKeyType keyType, String keyName, T keyValue) { this.keyType = keyType; this.keyName = keyName; this.keyValue = keyValue; } public RedisKeyType getKeyType() { return keyType; } public String getKey() { return keyName; } public T getValue() { return keyValue; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/redis/model/RedisResult.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.redis.model; import redis.clients.jedis.Tuple; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; public class RedisResult { private final List redisRecords = new LinkedList(); public void addString(String key, String value) { redisRecords.add(new RedisRecord(RedisKeyType.STRING, key, value)); } public void addList(String key, List values) { redisRecords.add(new RedisRecord(RedisKeyType.LIST, key, values)); } public void addSet(String key, Set values) { redisRecords.add(new RedisRecord(RedisKeyType.SET, key, values)); } public void addHash(String key, Map values) { redisRecords.add(new RedisRecord(RedisKeyType.HASH, key, values)); } public void addSortedSet(String key, Set values) { redisRecords.add(new RedisRecord>(RedisKeyType.ZSET, key, values)); } public List getResults() { return redisRecords; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/redis/view/RedisAuthenticationPanel.form ================================================
================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/redis/view/RedisAuthenticationPanel.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.redis.view; import org.codinjutsu.tools.nosql.commons.model.AuthenticationSettings; import org.codinjutsu.tools.nosql.commons.view.AuthenticationView; import javax.swing.*; public class RedisAuthenticationPanel implements AuthenticationView { private JPasswordField passwordField; private JPanel mainPanel; public RedisAuthenticationPanel() { passwordField.setName("passwordField"); } @Override public JPanel getComponent() { return mainPanel; } @Override public AuthenticationSettings create() { AuthenticationSettings authenticationSettings = new AuthenticationSettings(); authenticationSettings.setPassword(getPassword()); return authenticationSettings; } @Override public void load(AuthenticationSettings settings) { passwordField.setText(settings.getPassword()); } private String getPassword() { char[] password = passwordField.getPassword(); if (password != null && password.length != 0) { return String.valueOf(password); } return null; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/redis/view/RedisFragmentedKeyTreeModel.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.redis.view; import org.codinjutsu.tools.nosql.commons.utils.StringUtils; import org.codinjutsu.tools.nosql.commons.view.NoSqlTreeNode; import org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor; import org.codinjutsu.tools.nosql.redis.view.nodedescriptor.FragmentedKeyNodeDescriptor; import org.codinjutsu.tools.nosql.redis.view.nodedescriptor.RedisKeyValueDescriptor; import javax.swing.event.TreeModelListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.MutableTreeNode; import java.util.Arrays; import java.util.Enumeration; import static org.apache.commons.lang.StringUtils.isEmpty; public class RedisFragmentedKeyTreeModel extends DefaultTreeModel { private String separator; private DefaultTreeModel fragmentedKeyModel; private boolean needsUpdate = true; public RedisFragmentedKeyTreeModel(NoSqlTreeNode root) { super(root); this.separator = ""; } public void setSeparator(String separator) { this.separator = separator; needsUpdate = true; fireSeparatorChanged(); } public void resetSeparator() { this.separator = ""; needsUpdate = true; fireSeparatorChanged(); } @Override public DefaultMutableTreeNode getRoot() { return (DefaultMutableTreeNode) getFragmentedKeyModel().getRoot(); } @Override public void reload() { super.reload(); getFragmentedKeyModel().reload(); needsUpdate = true; fireSeparatorChanged(); } @Override public int getChildCount(Object parent) { return getFragmentedKeyModel().getChildCount(parent); } @Override public Object getChild(Object parent, int index) { return getFragmentedKeyModel().getChild(parent, index); } @Override public int getIndexOfChild(Object parent, Object child) { return getFragmentedKeyModel().getIndexOfChild(parent, child); } @Override public void addTreeModelListener(TreeModelListener listener) { super.addTreeModelListener(listener); getFragmentedKeyModel().addTreeModelListener(listener); } @Override public void removeTreeModelListener(TreeModelListener listener) { super.removeTreeModelListener(listener); getFragmentedKeyModel().removeTreeModelListener(listener); } @Override public boolean isLeaf(Object node) { return getFragmentedKeyModel().isLeaf(node); } private DefaultTreeModel getFragmentedKeyModel() { if (needsUpdate) { needsUpdate = false; updateFilteredModel(); } return fragmentedKeyModel; } private void updateFilteredModel() { DefaultMutableTreeNode sourceRoot = (DefaultMutableTreeNode) super.getRoot(); DefaultMutableTreeNode targetRoot = (DefaultMutableTreeNode) sourceRoot.clone(); wrapNodes(sourceRoot, separator); fragmentedKeyModel = new DefaultTreeModel(targetRoot); Object[] listeners = listenerList.getListenerList(); for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == TreeModelListener.class) { fragmentedKeyModel.addTreeModelListener((TreeModelListener) listeners[i + 1]); } } fireSeparatorChanged(); } private void fireSeparatorChanged() { getFragmentedKeyModel().reload(); } public static DefaultMutableTreeNode wrapNodes(DefaultMutableTreeNode source, String separator) { if (isEmpty(separator)) { return source; } DefaultMutableTreeNode targetRootNode = (DefaultMutableTreeNode) source.clone(); for (int i = 0; i < source.getChildCount(); i++) { DefaultMutableTreeNode originalChildNode = (DefaultMutableTreeNode) source.getChildAt(i); NoSqlTreeNode clonedChildNode = (NoSqlTreeNode) originalChildNode.clone(); RedisKeyValueDescriptor descriptor = (RedisKeyValueDescriptor) clonedChildNode.getDescriptor(); String[] explodedKey = StringUtils.explode(descriptor.getKey(), separator); if (explodedKey.length == 1) { addChildren(clonedChildNode, originalChildNode); targetRootNode.add(clonedChildNode); } else { updateTree(targetRootNode, originalChildNode, explodedKey, descriptor); } } return targetRootNode; } private static void updateTree(DefaultMutableTreeNode parentTargetNode, DefaultMutableTreeNode originalChildNode, String[] explodedKey, RedisKeyValueDescriptor sourceDescriptor) { if (explodedKey.length == 0) { addChildren(parentTargetNode, originalChildNode); return; } String keyFragment = explodedKey[0]; NoSqlTreeNode node = findNodeByKey(parentTargetNode, keyFragment); if (node == null) { if (explodedKey.length == 1) { node = new NoSqlTreeNode(RedisKeyValueDescriptor.createDescriptor(sourceDescriptor.getKeyType(), keyFragment, sourceDescriptor.getValue())); } else { node = new NoSqlTreeNode(FragmentedKeyNodeDescriptor.createDescriptor(keyFragment)); } } updateTree(node, originalChildNode, Arrays.copyOfRange(explodedKey, 1, explodedKey.length), sourceDescriptor); parentTargetNode.add(node); } private static NoSqlTreeNode findNodeByKey(DefaultMutableTreeNode parentTargetNode, String keyFragment) { for (int i = 0; i < parentTargetNode.getChildCount(); i++) { NoSqlTreeNode currentChild = (NoSqlTreeNode) parentTargetNode.getChildAt(i); NodeDescriptor descriptor = currentChild.getDescriptor(); String nodeKey; if (descriptor instanceof FragmentedKeyNodeDescriptor) { nodeKey = ((FragmentedKeyNodeDescriptor) descriptor).getKeyFragment(); } else if (descriptor instanceof RedisKeyValueDescriptor) { nodeKey = ((RedisKeyValueDescriptor) descriptor).getKey(); } else { return null; } if (keyFragment.equals(nodeKey)) { return currentChild; } } return null; } private static void addChildren(DefaultMutableTreeNode parentNode, DefaultMutableTreeNode originalChildNode) { Enumeration children = originalChildNode.children(); while (children.hasMoreElements()) { DefaultMutableTreeNode childNode = (DefaultMutableTreeNode) children.nextElement(); parentNode.add((MutableTreeNode) childNode.clone()); } } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/redis/view/RedisPanel.form ================================================
================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/redis/view/RedisPanel.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.redis.view; import com.intellij.ide.CommonActionsManager; import com.intellij.ide.TreeExpander; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.ActionToolbar; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.LoadingDecorator; import com.intellij.openapi.util.Disposer; import com.intellij.ui.components.JBScrollPane; import com.intellij.ui.components.JBTextField; import com.intellij.ui.components.panels.NonOpaquePanel; import com.intellij.ui.treeStructure.treetable.TreeTableTree; import com.intellij.util.ui.tree.TreeUtil; import org.apache.commons.lang.StringUtils; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.codinjutsu.tools.nosql.commons.utils.GuiUtils; import org.codinjutsu.tools.nosql.commons.view.ErrorPanel; import org.codinjutsu.tools.nosql.commons.view.NoSqlResultView; import org.codinjutsu.tools.nosql.commons.view.action.ExecuteQuery; import org.codinjutsu.tools.nosql.mongo.view.JsonTreeTableView; import org.codinjutsu.tools.nosql.redis.logic.RedisClient; import org.codinjutsu.tools.nosql.redis.model.RedisDatabase; import org.codinjutsu.tools.nosql.redis.model.RedisQuery; import org.codinjutsu.tools.nosql.redis.model.RedisResult; import org.codinjutsu.tools.nosql.redis.view.action.EnableGroupingAction; import org.codinjutsu.tools.nosql.redis.view.action.SetSeparatorAction; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; import java.awt.*; public class RedisPanel extends NoSqlResultView { private JPanel toolBarPanel; private JPanel containerPanel; private JPanel errorPanel; private JPanel resultPanel; private JPanel mainPanel; private final LoadingDecorator loadingDecorator; private JsonTreeTableView resultTableView; private final Project project; private final RedisClient redisClient; private final ServerConfiguration configuration; private final RedisDatabase database; private JBTextField filterField; private RedisResult redisResult; private boolean groupData; private String groupSeparator; public RedisPanel(Project project, RedisClient redisClient, ServerConfiguration configuration, RedisDatabase database) { this.project = project; this.redisClient = redisClient; this.configuration = configuration; this.database = database; this.resultPanel = new JPanel(new BorderLayout()); buildQueryToolBar(); loadingDecorator = new LoadingDecorator(resultPanel, this, 0); containerPanel.add(loadingDecorator.getComponent()); loadAndDisplayResults(getFilter(), this.groupData, this.groupSeparator); setLayout(new BorderLayout()); add(mainPanel); } private void loadAndDisplayResults(final String filter, final boolean groupByPrefix, final String separator) { redisResult = redisClient.loadRecords(configuration, database, new RedisQuery(filter)); updateResultTableTree(redisResult, groupByPrefix, separator); } protected void buildQueryToolBar() { toolBarPanel.setLayout(new BorderLayout()); filterField = new JBTextField("*"); filterField.setColumns(10); NonOpaquePanel westPanel = new NonOpaquePanel(); NonOpaquePanel filterPanel = new NonOpaquePanel(); filterPanel.add(new JLabel("Filter: "), BorderLayout.WEST); filterPanel.add(filterField, BorderLayout.CENTER); filterPanel.add(Box.createHorizontalStrut(5), BorderLayout.EAST); westPanel.add(filterPanel, BorderLayout.WEST); toolBarPanel.add(westPanel, BorderLayout.WEST); addCommonsActions(); } protected void addCommonsActions() { final TreeExpander treeExpander = new TreeExpander() { @Override public void expandAll() { RedisPanel.this.expandAll(); } @Override public boolean canExpand() { return true; } @Override public void collapseAll() { RedisPanel.this.collapseAll(); } @Override public boolean canCollapse() { return true; } }; CommonActionsManager actionsManager = CommonActionsManager.getInstance(); final AnAction expandAllAction = actionsManager.createExpandAllAction(treeExpander, resultPanel); final AnAction collapseAllAction = actionsManager.createCollapseAllAction(treeExpander, resultPanel); Disposer.register(this, new Disposable() { @Override public void dispose() { collapseAllAction.unregisterCustomShortcutSet(resultPanel); expandAllAction.unregisterCustomShortcutSet(resultPanel); } }); DefaultActionGroup actionResultGroup = new DefaultActionGroup("RedisResultGroup", true); actionResultGroup.add(new ExecuteQuery<>(this)); actionResultGroup.addSeparator(); actionResultGroup.add(new EnableGroupingAction(this)); actionResultGroup.add(new SetSeparatorAction(this)); actionResultGroup.addSeparator(); actionResultGroup.add(expandAllAction); actionResultGroup.add(collapseAllAction); ActionToolbar actionToolBar = ActionManager.getInstance().createActionToolbar("MongoResultGroupActions", actionResultGroup, true); actionToolBar.setLayoutPolicy(ActionToolbar.AUTO_LAYOUT_POLICY); JComponent actionToolBarComponent = actionToolBar.getComponent(); actionToolBarComponent.setBorder(null); actionToolBarComponent.setOpaque(false); toolBarPanel.add(actionToolBarComponent, BorderLayout.CENTER); } private String getFilter() { String filter = filterField.getText(); if (StringUtils.isNotBlank(filter)) { return filter; } return "*"; } void expandAll() { TreeUtil.expandAll(resultTableView.getTree()); } void collapseAll() { TreeTableTree tree = resultTableView.getTree(); TreeUtil.collapseAll(tree, 1); } public void updateResultTableTree(RedisResult redisResult, boolean groupByPrefix, String separator) { DefaultMutableTreeNode rootNode = RedisTreeModel.buildTree(redisResult); DefaultMutableTreeNode renderedNode = rootNode; if (groupByPrefix && StringUtils.isNotBlank(separator)) { renderedNode = RedisFragmentedKeyTreeModel.wrapNodes(rootNode, separator); } resultTableView = new JsonTreeTableView(renderedNode, JsonTreeTableView.COLUMNS_FOR_READING); resultTableView.setName("resultTreeTable"); resultPanel.invalidate(); resultPanel.removeAll(); resultPanel.add(new JBScrollPane(resultTableView)); resultPanel.validate(); } @Override public void showResults() { executeQuery(); } @Override public JPanel getResultPanel() { return resultPanel; } @Override public RedisResult getRecords() { return redisResult; } @Override public void executeQuery() { errorPanel.setVisible(false); ProgressManager.getInstance().run(new Task.Backgroundable(project, "Executing query", true) { @Override public void run(ProgressIndicator indicator) { try { GuiUtils.runInSwingThread(new Runnable() { @Override public void run() { loadingDecorator.startLoading(false); } }); loadAndDisplayResults(getFilter(), isGroupDataEnabled(), getGroupSeparator()); } catch (final Exception ex) { GuiUtils.runInSwingThread(new Runnable() { @Override public void run() { errorPanel.invalidate(); errorPanel.removeAll(); errorPanel.add(new ErrorPanel(ex), BorderLayout.CENTER); errorPanel.validate(); errorPanel.setVisible(true); } }); } finally { GuiUtils.runInSwingThread(new Runnable() { @Override public void run() { loadingDecorator.stopLoading(); } }); } } }); } @Override public void dispose() { } public boolean isGroupDataEnabled() { return this.groupData; } public void toggleGroupData(boolean enabled) { this.groupData = enabled; updateResultTableTree(redisResult, this.groupData, this.groupSeparator); } public String getGroupSeparator() { return groupSeparator; } public void setGroupSeparator(String groupSeparator) { this.groupSeparator = groupSeparator; updateResultTableTree(redisResult, this.groupData, this.groupSeparator); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/redis/view/RedisTreeModel.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.redis.view; import org.codinjutsu.tools.nosql.commons.view.NoSqlTreeNode; import org.codinjutsu.tools.nosql.redis.model.RedisKeyType; import org.codinjutsu.tools.nosql.redis.model.RedisRecord; import org.codinjutsu.tools.nosql.redis.model.RedisResult; import org.codinjutsu.tools.nosql.redis.view.nodedescriptor.RedisKeyValueDescriptor; import org.codinjutsu.tools.nosql.redis.view.nodedescriptor.RedisResultDescriptor; import org.codinjutsu.tools.nosql.redis.view.nodedescriptor.RedisValueDescriptor; import java.util.List; import java.util.Map; import java.util.Set; public class RedisTreeModel { public static NoSqlTreeNode buildTree(RedisResult redisResult) { NoSqlTreeNode rootNode = new NoSqlTreeNode(new RedisResultDescriptor()); List redisRecords = redisResult.getResults(); for (RedisRecord redisRecord : redisRecords) { processRecord(rootNode, redisRecord); } return rootNode; } private static void processRecord(NoSqlTreeNode rootNode, RedisRecord redisRecord) { RedisKeyType keyType = redisRecord.getKeyType(); NoSqlTreeNode treeNode = new NoSqlTreeNode(RedisKeyValueDescriptor.createDescriptor(keyType, redisRecord.getKey(), redisRecord.getValue())); if (RedisKeyType.LIST.equals(keyType)) { List valuesFromList = (List) redisRecord.getValue(); for (int index = 0; index < valuesFromList.size(); index++) { String value = valuesFromList.get(index); treeNode.add(new NoSqlTreeNode(RedisValueDescriptor.createDescriptor(index, value))); } } else if (RedisKeyType.SET.equals(keyType) || RedisKeyType.ZSET.equals(keyType)) { Set valuesFromSet = (Set) redisRecord.getValue(); for (Object value : valuesFromSet) { treeNode.add(new NoSqlTreeNode(RedisValueDescriptor.createUnindexedDescriptor(value))); } } else if (RedisKeyType.HASH.equals(keyType)) { Map valuesFromMap = (Map) redisRecord.getValue(); for (Map.Entry entry : valuesFromMap.entrySet()) { treeNode.add(new NoSqlTreeNode(RedisKeyValueDescriptor.createDescriptor(entry.getKey(), entry.getValue()))); } } rootNode.add(treeNode); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/redis/view/action/EnableGroupingAction.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.redis.view.action; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.ToggleAction; import org.codinjutsu.tools.nosql.redis.view.RedisPanel; public class EnableGroupingAction extends ToggleAction { private final RedisPanel redisPanel; private boolean isGroupData = false; public EnableGroupingAction(RedisPanel redisPanel) { super("Group by prefix", "Group by prefix", AllIcons.Actions.GroupByPrefix); this.redisPanel = redisPanel; } @Override public boolean isSelected(AnActionEvent event) { return isGroupData; } @Override public void setSelected(AnActionEvent event, boolean state) { redisPanel.toggleGroupData(state); isGroupData = state; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/redis/view/action/SetSeparatorAction.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.redis.view.action; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.ui.Messages; import com.intellij.util.ArrayUtil; import org.apache.commons.lang.StringUtils; import org.codinjutsu.tools.nosql.redis.view.RedisPanel; import java.util.LinkedHashSet; import java.util.Set; public class SetSeparatorAction extends AnAction { private final RedisPanel redisPanel; private static final Set myPredefinedSeparators = new LinkedHashSet<>(); public SetSeparatorAction(RedisPanel redisPanel) { super(AllIcons.General.Ellipsis); this.redisPanel = redisPanel; myPredefinedSeparators.add("."); myPredefinedSeparators.add(":"); } @Override public void actionPerformed(AnActionEvent event) { String[] strings = ArrayUtil.toStringArray(myPredefinedSeparators); String current = redisPanel.getGroupSeparator(); String separator = Messages.showEditableChooseDialog("Redis Keys Separator", "Select Separator", Messages.getQuestionIcon(), strings, current, null); if (separator == null) { return; } if (StringUtils.equals(redisPanel.getGroupSeparator(), separator)) { return; } redisPanel.setGroupSeparator(separator); myPredefinedSeparators.add(separator); update(event); } @Override public void update(AnActionEvent event) { String currentSeparator = redisPanel.getGroupSeparator(); String textToDisplay = String.format("Group by '%s'", (currentSeparator == null ? "Nothing" : currentSeparator)); event.getPresentation().setText(textToDisplay); event.getPresentation().setDescription(textToDisplay); event.getPresentation().setEnabled(redisPanel.isGroupDataEnabled()); } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/redis/view/console/RedisConsoleRunner.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.redis.view.console; import com.intellij.execution.ExecutionException; import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.execution.console.ConsoleHistoryController; import com.intellij.execution.console.ConsoleRootType; import com.intellij.execution.console.ProcessBackedConsoleExecuteActionHandler; import com.intellij.execution.process.OSProcessHandler; import com.intellij.execution.runners.AbstractConsoleRunnerWithHistory; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.psi.PsiFile; import org.apache.commons.lang.StringUtils; import org.codinjutsu.tools.nosql.DatabaseVendor; import org.codinjutsu.tools.nosql.NoSqlConfiguration; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.codinjutsu.tools.nosql.commons.view.console.NoSqlConsoleView; import org.codinjutsu.tools.nosql.redis.model.RedisDatabase; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class RedisConsoleRunner extends AbstractConsoleRunnerWithHistory { private static final Key SHELL_FILE = Key.create("REDIS_SHELL_FILE"); private final ServerConfiguration serverConfiguration; private final RedisDatabase database; public RedisConsoleRunner(@NotNull Project project, ServerConfiguration serverConfiguration, RedisDatabase database) { super(project, "Redis Shell", "/tmp"); this.serverConfiguration = serverConfiguration; this.database = database; } @Override protected NoSqlConsoleView createConsoleView() { NoSqlConsoleView res = new NoSqlConsoleView(getProject(), "Redis Console", serverConfiguration); PsiFile file = res.getFile(); assert file.getContext() == null; file.putUserData(SHELL_FILE, Boolean.TRUE); return res; } @Nullable @Override protected Process createProcess() throws ExecutionException { NoSqlConfiguration noSqlConfiguration = NoSqlConfiguration.getInstance(getProject()); String shellPath = noSqlConfiguration.getShellPath(DatabaseVendor.REDIS); final GeneralCommandLine commandLine = new GeneralCommandLine(); commandLine.setExePath(shellPath); commandLine.addParameter("-n"); commandLine.addParameter(database.getName()); String shellWorkingDir = serverConfiguration.getShellWorkingDir(); if (StringUtils.isNotBlank(shellWorkingDir)) { commandLine.setWorkDirectory(shellWorkingDir); } String shellArgumentsLine = serverConfiguration.getShellArgumentsLine(); if (StringUtils.isNotBlank(shellArgumentsLine)) { commandLine.addParameters(shellArgumentsLine.split(" ")); } return commandLine.createProcess(); } @Override protected OSProcessHandler createProcessHandler(Process process) { return new OSProcessHandler(process, null); } @NotNull @Override protected ProcessBackedConsoleExecuteActionHandler createExecuteActionHandler() { ProcessBackedConsoleExecuteActionHandler handler = new ProcessBackedConsoleExecuteActionHandler(getProcessHandler(), false) { @Override public String getEmptyExecuteAction() { return "NoSql.Shell.Execute"; } }; new ConsoleHistoryController(new ConsoleRootType("Redis Shell", null) { }, null, getConsoleView()).install(); return handler; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/redis/view/editor/RedisFakeFileType.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.redis.view.editor; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.ex.FakeFileType; import com.intellij.openapi.vfs.VirtualFile; import org.codinjutsu.tools.nosql.commons.utils.GuiUtils; import org.jetbrains.annotations.NotNull; import javax.swing.*; public class RedisFakeFileType extends FakeFileType { public static final Icon REDIS_ICON = GuiUtils.loadIcon("redis.png"); public static final FileType INSTANCE = new RedisFakeFileType(); @Override public Icon getIcon() { return REDIS_ICON; } @Override public boolean isMyFileType(VirtualFile file) { return false; } @NotNull @Override public String getDefaultExtension() { return "json"; } @NotNull @Override public String getName() { return "REDIS"; } @NotNull @Override public String getDescription() { return "REDIS"; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/redis/view/editor/RedisObjectFile.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.redis.view.editor; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.project.Project; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.codinjutsu.tools.nosql.commons.view.editor.NoSqlDatabaseObjectFile; import org.codinjutsu.tools.nosql.redis.model.RedisDatabase; import org.jetbrains.annotations.NotNull; public class RedisObjectFile extends NoSqlDatabaseObjectFile { private RedisDatabase database; public RedisObjectFile(Project project, ServerConfiguration configuration, RedisDatabase redisDatabase) { super(project, configuration, String.format("%s/%s", configuration.getLabel(), redisDatabase.getName())); this.database = redisDatabase; } @NotNull public FileType getFileType() { return RedisFakeFileType.INSTANCE; } public RedisDatabase getDatabase() { return database; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/redis/view/nodedescriptor/FragmentedKeyNodeDescriptor.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.redis.view.nodedescriptor; import com.intellij.icons.AllIcons; import com.intellij.ui.ColoredTableCellRenderer; import com.intellij.ui.ColoredTreeCellRenderer; import com.intellij.ui.SimpleTextAttributes; import org.codinjutsu.tools.nosql.commons.style.StyleAttributesProvider; import org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor; public class FragmentedKeyNodeDescriptor implements NodeDescriptor { private final String keyFragment; private final SimpleTextAttributes keyAttribute; public FragmentedKeyNodeDescriptor(String keyFragment, SimpleTextAttributes keyAttribute) { this.keyFragment = keyFragment; this.keyAttribute = keyAttribute; } public static FragmentedKeyNodeDescriptor createDescriptor(String key) { return new FragmentedKeyNodeDescriptor(key, StyleAttributesProvider.getKeyValueAttribute()); } public String getKeyFragment() { return keyFragment; } @Override public void renderValue(ColoredTableCellRenderer cellRenderer, boolean isNodeExpanded) { } @Override public void renderNode(ColoredTreeCellRenderer cellRenderer) { cellRenderer.append(keyFragment, keyAttribute); cellRenderer.setIcon(AllIcons.Nodes.Advice); } @Override public String getFormattedKey() { return keyFragment; } @Override public String getFormattedValue() { return ""; } @Override public Object getValue() { return null; } @Override public void setValue(Object value) { } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/redis/view/nodedescriptor/RedisKeyValueDescriptor.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.redis.view.nodedescriptor; import com.intellij.icons.AllIcons; import com.intellij.ui.ColoredTableCellRenderer; import com.intellij.ui.ColoredTreeCellRenderer; import com.intellij.ui.SimpleTextAttributes; import org.codinjutsu.tools.nosql.commons.style.StyleAttributesProvider; import org.codinjutsu.tools.nosql.commons.utils.StringUtils; import org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor; import org.codinjutsu.tools.nosql.redis.RedisUtils; import org.codinjutsu.tools.nosql.redis.model.RedisKeyType; import redis.clients.jedis.Tuple; import javax.swing.*; import java.util.List; import java.util.Map; import java.util.Set; public class RedisKeyValueDescriptor implements NodeDescriptor { private final RedisKeyType keyType; private final String key; private final Object value; private final SimpleTextAttributes valueTextAttributes; private final Icon icon; public static RedisKeyValueDescriptor createDescriptor(RedisKeyType keyType, String key, Object value) { return new RedisKeyValueDescriptor(keyType, key, value, StyleAttributesProvider.getStringAttribute()); } public static NodeDescriptor createDescriptor(String key, String value) { return createDescriptor(null, key, value); } public RedisKeyValueDescriptor(RedisKeyType keyType, String key, Object value, SimpleTextAttributes valueTextAttributes) { this.keyType = keyType; this.key = key; this.value = value; this.icon = findIcon(value); this.valueTextAttributes = valueTextAttributes; } private Icon findIcon(Object object) { if (object instanceof List) { return AllIcons.Json.Property_brackets; } else if (object instanceof Set || object instanceof Map) { return AllIcons.Json.Property_braces; } return null; } @Override public void renderValue(ColoredTableCellRenderer cellRenderer, boolean isNodeExpanded) { if (!isNodeExpanded) { cellRenderer.append(getFormattedValue(), valueTextAttributes); } } public void renderNode(ColoredTreeCellRenderer cellRenderer) { cellRenderer.setIcon(this.icon); if (this.keyType != null) { cellRenderer.append(this.keyType.name(), StyleAttributesProvider.getIndexAttribute()); cellRenderer.append(" "); } cellRenderer.append(getFormattedKey(), StyleAttributesProvider.getKeyValueAttribute()); } @Override public String getFormattedKey() { return key; } @Override public String getFormattedValue() { if (RedisKeyType.ZSET.equals(keyType)) { return getValueAndAbbreviateIfNecessary(RedisUtils.stringifySortedSet((Set) getValue())); } else if (RedisKeyType.SET.equals(keyType)) { return getValueAndAbbreviateIfNecessary(RedisUtils.stringifySet((Set) getValue())); } return getValueAndAbbreviateIfNecessary(getValue().toString()); } @Override public Object getValue() { return value; } @Override public void setValue(Object value) { } public String getKey() { return key; } public RedisKeyType getKeyType() { return keyType; } protected String getValueAndAbbreviateIfNecessary(String stringifiedValue) { if (stringifiedValue.length() > MAX_LENGTH) { return StringUtils.abbreviateInCenter(stringifiedValue, MAX_LENGTH); } return stringifiedValue; } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/redis/view/nodedescriptor/RedisResultDescriptor.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.redis.view.nodedescriptor; import com.intellij.ui.ColoredTableCellRenderer; import com.intellij.ui.ColoredTreeCellRenderer; import org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor; public class RedisResultDescriptor implements NodeDescriptor { @Override public void renderValue(ColoredTableCellRenderer cellRenderer, boolean isNodeExpanded) { } @Override public void renderNode(ColoredTreeCellRenderer cellRenderer) { } @Override public String getFormattedKey() { return null; } @Override public String getFormattedValue() { return null; } @Override public Object getValue() { return null; } @Override public void setValue(Object value) { } } ================================================ FILE: src/main/java/org/codinjutsu/tools/nosql/redis/view/nodedescriptor/RedisValueDescriptor.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.redis.view.nodedescriptor; import com.intellij.ui.ColoredTableCellRenderer; import com.intellij.ui.ColoredTreeCellRenderer; import com.intellij.ui.SimpleTextAttributes; import org.codinjutsu.tools.nosql.commons.style.StyleAttributesProvider; import org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor; import redis.clients.jedis.Tuple; public class RedisValueDescriptor implements NodeDescriptor { private final int index; protected Object value; private final SimpleTextAttributes valueTextAttributes; public static RedisValueDescriptor createDescriptor(int index, Object value) { return new RedisValueDescriptor(index, value, StyleAttributesProvider.getStringAttribute()); } public static RedisValueDescriptor createUnindexedDescriptor(Object value) { return new RedisUnindexedValueDescriptor(value, StyleAttributesProvider.getStringAttribute()); } private RedisValueDescriptor(int index, Object value, SimpleTextAttributes valueTextAttributes) { this.index = index; this.value = value; this.valueTextAttributes = valueTextAttributes; } @Override public void renderValue(ColoredTableCellRenderer cellRenderer, boolean isNodeExpanded) { if (!isNodeExpanded) { cellRenderer.append(getFormattedValue(), valueTextAttributes); } } @Override public void renderNode(ColoredTreeCellRenderer cellRenderer) { cellRenderer.append(getFormattedKey(), StyleAttributesProvider.getIndexAttribute()); } @Override public String getFormattedKey() { return String.format("[%s]", index); } @Override public String getFormattedValue() { if (getValue() instanceof Tuple) { Tuple tupleValue = (Tuple) getValue(); return String.format("(%s, %s)", tupleValue.getElement(), tupleValue.getScore()); } return String.valueOf(getValue()); } @Override public Object getValue() { return value; } @Override public void setValue(Object value) { } private static class RedisUnindexedValueDescriptor extends RedisValueDescriptor { private RedisUnindexedValueDescriptor(Object value, SimpleTextAttributes valueTextAttributes) { super(0, value, valueTextAttributes); } @Override public String getFormattedKey() { return "-"; } } } ================================================ FILE: src/main/resources/META-INF/plugin.xml ================================================ NoSql Plugin NoSql database integration for Intellij 0.1.0 David Boissier com.intellij.modules.lang org.codinjutsu.tools.nosql.NoSqlComponent org.codinjutsu.tools.nosql.commons.view.editor.NoSqlDatabaseDataEditorProvider org.codinjutsu.tools.nosql.commons.view.editor.NoSqlDatabaseFileSystem This tool allows accessing to NoSql databases and provides CRUD operations.
Documentation is available on the GitHub project



This tool is free for personal and commercial usage.
Donations are welcomed.

]]>
Changelog ]]>
================================================ FILE: src/main/resources/assemblies/plugin-assembly.xml ================================================ distribution zip /lib com.intellij:forms_rt com.intellij:openapi com.intellij:util commons-lang:commons-lang log4j:log4j README.md / CHANGELOG.txt / LICENSE.txt / ================================================ FILE: src/test/java/org/codinjutsu/tools/nosql/commons/utils/DateUtilsTest.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.utils; import org.junit.Test; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.Locale; import static org.junit.Assert.*; public class DateUtilsTest { @Test public void testUtcDateTime() throws Exception { Calendar calendar = GregorianCalendar.getInstance(); calendar.set(Calendar.YEAR, 2015); calendar.set(Calendar.MONTH, 1); calendar.set(Calendar.DAY_OF_YEAR, 1); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); Date time = calendar.getTime(); assertEquals("Thu Jan 01 00:00:00 CET 2015", time.toString()); assertEquals("31/12/14 23:00:00 UTC", DateUtils.utcDateTime(Locale.FRANCE).format(time)); } @Test public void testUtcTime() throws Exception { Calendar calendar = GregorianCalendar.getInstance(); calendar.set(Calendar.YEAR, 2015); calendar.set(Calendar.MONTH, 1); calendar.set(Calendar.DAY_OF_YEAR, 1); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); Date time = calendar.getTime(); assertEquals("Thu Jan 01 00:00:00 CET 2015", time.toString()); assertEquals("23:00:00", DateUtils.utcTime(Locale.FRANCE).format(time)); } } ================================================ FILE: src/test/java/org/codinjutsu/tools/nosql/commons/utils/StringUtilsTest.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.utils; import org.junit.Test; import static org.junit.Assert.assertEquals; public class StringUtilsTest { @Test public void abbreviateInCenter() throws Exception { String value = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"; assertEquals("abcdefghijklmnopq...ghijklmnopqrstuvwxyz", StringUtils.abbreviateInCenter(value, 40)); } @Test public void parseNumber() throws Exception { assertEquals(1, StringUtils.parseNumber("1")); assertEquals(1.000000000001d, StringUtils.parseNumber("1.000000000001")); assertEquals(1000000000000000L, StringUtils.parseNumber("1000000000000000")); } } ================================================ FILE: src/test/java/org/codinjutsu/tools/nosql/commons/view/TableCellReader.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.commons.view; import org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor; import org.fest.swing.driver.BasicJTableCellReader; import javax.swing.*; public class TableCellReader extends BasicJTableCellReader { @Override public String valueAt(JTable table, int row, int column) { NodeDescriptor nodeDescriptor = (NodeDescriptor) table.getValueAt(row, column); if (column == 0) { return nodeDescriptor.getFormattedKey(); } return nodeDescriptor.getFormattedValue(); } } ================================================ FILE: src/test/java/org/codinjutsu/tools/nosql/couchbase/CouchbaseClientTest.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.couchbase; import com.couchbase.client.java.Bucket; import com.couchbase.client.java.Cluster; import com.couchbase.client.java.CouchbaseCluster; import com.couchbase.client.java.document.JsonDocument; import com.couchbase.client.java.document.json.JsonArray; import com.couchbase.client.java.document.json.JsonObject; import com.couchbase.client.java.env.DefaultCouchbaseEnvironment; import com.couchbase.client.java.query.N1qlQuery; import com.couchbase.client.java.query.N1qlQueryResult; import com.couchbase.client.java.query.N1qlQueryRow; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.codinjutsu.tools.nosql.commons.model.AuthenticationSettings; import org.codinjutsu.tools.nosql.commons.model.DatabaseServer; import org.codinjutsu.tools.nosql.couchbase.logic.CouchbaseClient; import org.junit.Test; import static com.couchbase.client.java.query.Select.select; import static com.couchbase.client.java.query.dsl.Expression.i; public class CouchbaseClientTest { @Test public void loadServers() throws Exception { CouchbaseClient couchbaseClient = new CouchbaseClient(); ServerConfiguration configuration = new ServerConfiguration(); configuration.setServerUrl("localhost"); AuthenticationSettings authenticationSettings = new AuthenticationSettings(); authenticationSettings.setUsername("Administrator"); authenticationSettings.setPassword("helloworld2015"); configuration.setAuthenticationSettings(authenticationSettings); couchbaseClient.loadServer(new DatabaseServer(configuration)); } public static void main(String[] args) { Cluster cluster = CouchbaseCluster.create(DefaultCouchbaseEnvironment .builder() .queryEnabled(true) .build()); Bucket defaultBucket = cluster.openBucket("default"); defaultBucket.remove("user:walter"); JsonArray friends = JsonArray.empty() .add(JsonObject.empty().put("name", "Mike Ehrmantraut")) .add(JsonObject.empty().put("name", "Jesse Pinkman")); JsonObject content = JsonObject.empty() .put("firstname", "Walter") .put("lastname", "White") .put("age", 52) .put("aliases", JsonArray.from("Walt Jackson", "Mr. Mayhew", "David Lynn")) .put("friends", friends); JsonDocument walter = JsonDocument.create("user:walter", content); JsonDocument inserted = defaultBucket.insert(walter); JsonDocument foundGuy = defaultBucket.get("user:walter"); System.out.println(foundGuy.content().toMap()); Bucket beerBucket = cluster.openBucket("beer-sample"); N1qlQueryResult result = beerBucket.query(N1qlQuery.simple(select("*").from(i("beer-sample")).limit(10))); System.out.println("Errors found: " + result.errors()); for (N1qlQueryRow row : result.allRows()) { JsonObject jsonObject = row.value(); System.out.println(jsonObject.toMap()); } cluster.disconnect(); } } ================================================ FILE: src/test/java/org/codinjutsu/tools/nosql/couchbase/view/CouchbasePanelTest.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.couchbase.view; import com.couchbase.client.java.document.json.JsonObject; import com.intellij.openapi.command.impl.DummyProject; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.codinjutsu.tools.nosql.commons.view.TableCellReader; import org.codinjutsu.tools.nosql.couchbase.logic.CouchbaseClient; import org.codinjutsu.tools.nosql.couchbase.model.CouchbaseDatabase; import org.codinjutsu.tools.nosql.couchbase.model.CouchbaseQuery; import org.codinjutsu.tools.nosql.couchbase.model.CouchbaseResult; import org.fest.swing.edt.GuiActionRunner; import org.fest.swing.edt.GuiQuery; import org.fest.swing.fixture.Containers; import org.fest.swing.fixture.FrameFixture; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import java.util.Arrays; import static org.mockito.Matchers.any; import static org.mockito.Mockito.when; public class CouchbasePanelTest { private FrameFixture frameFixture; private CouchbaseClient couchbaseClientMock = Mockito.mock(CouchbaseClient.class); private CouchbasePanel couchbasePanelWrapper; @Before public void setUp() throws Exception { when(couchbaseClientMock.loadRecords(any(ServerConfiguration.class), any(CouchbaseDatabase.class), any(CouchbaseQuery.class))).thenReturn(new CouchbaseResult("dummy")); couchbasePanelWrapper = GuiActionRunner.execute(new GuiQuery() { protected CouchbasePanel executeInEDT() { return new CouchbasePanel(DummyProject.getInstance(), couchbaseClientMock, new ServerConfiguration(), new CouchbaseDatabase("default")) { @Override protected void addCommonsActions() { } }; } }); frameFixture = Containers.showInFrame(couchbasePanelWrapper); } @After public void tearDown() { frameFixture.cleanUp(); } @Test public void displayJsonObjects() throws Exception { couchbasePanelWrapper.updateResultTableTree(createResults()); couchbasePanelWrapper.expandAll(); frameFixture.table("resultTreeTable").cellReader(new TableCellReader()) .requireColumnCount(2) .requireContents(new String[][]{ {"amount", "123456764"}, {"mad", "true"}, {"address", "{\"City\":\"Paris\",\"ZIP Code\":75016,\"Street\":\"Av. Champs Elysées\"}"}, {"Street", "\"Av. Champs Elysées\""}, {"ZIP Code", "75016"}, {"City", "\"Paris\""}, {"interests", "[\"programming\",\"XP\",\"TDD\"]"}, {"[0]", "\"programming\""}, {"[1]", "\"XP\""}, {"[2]", "\"TDD\""}, {"movies", "[{\"title\":\"Fight Club\",\"critic\":8.2},{\"title\":\"Blade Runner\",\"critic\":9.3},{\"title\":\"Toys Story\",\"critic\":8.7}]"}, {"[0]", "{\"title\":\"Fight Club\",\"critic\":8.2}"}, {"title", "\"Fight Club\""}, {"critic", "8.2"}, {"[1]", "{\"title\":\"Blade Runner\",\"critic\":9.3}"}, {"title", "\"Blade Runner\""}, {"critic", "9.3"}, {"[2]", "{\"title\":\"Toys Story\",\"critic\":8.7}"}, {"title", "\"Toys Story\""}, {"critic", "8.7"}, {"age", "25"}, {"score", "12345.12121"}, {"firstname", "\"Jojo\""}, }); } private CouchbaseResult createResults() { CouchbaseResult result = new CouchbaseResult("test"); result.add(JsonObject.create().put("firstname", "Jojo") .put("age", 25) .put("mad", true) .put("interests", Arrays.asList("programming", "XP", "TDD")) .put("amount", 123456764L) .put("score", 12345.12121d) .put("address", JsonObject.create() .put("Street", "Av. Champs Elysées") .put("City", "Paris") .put("ZIP Code", 75016)) .put("movies", Arrays.asList( JsonObject.create() .put("title", "Fight Club") .put("critic", 8.2), JsonObject.create() .put("title", "Blade Runner") .put("critic", 9.3), JsonObject.create() .put("title", "Toys Story") .put("critic", 8.7) ))); return result; } } ================================================ FILE: src/test/java/org/codinjutsu/tools/nosql/couchbase/view/ServerConfigurationPanelTest.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.couchbase.view; import com.intellij.openapi.command.impl.DummyProject; import org.codinjutsu.tools.nosql.DatabaseVendor; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.codinjutsu.tools.nosql.commons.logic.DatabaseClient; import org.codinjutsu.tools.nosql.commons.model.AuthenticationSettings; import org.codinjutsu.tools.nosql.commons.view.ServerConfigurationPanel; import org.fest.swing.edt.GuiActionRunner; import org.fest.swing.edt.GuiQuery; import org.fest.swing.fixture.Containers; import org.fest.swing.fixture.FrameFixture; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.mockito.Mockito; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; public class ServerConfigurationPanelTest { @Rule public ExpectedException thrown = ExpectedException.none(); private ServerConfigurationPanel configurationPanel; private DatabaseClient databaseClientMock; private FrameFixture frameFixture; @Before public void setUp() throws Exception { databaseClientMock = Mockito.mock(DatabaseClient.class); configurationPanel = GuiActionRunner.execute(new GuiQuery() { protected ServerConfigurationPanel executeInEDT() { return new ServerConfigurationPanel(DummyProject.getInstance(), DatabaseVendor.COUCHBASE, databaseClientMock, new CouchbaseAuthenticationPanel() ); } }); frameFixture = Containers.showInFrame(configurationPanel); } @After public void tearDown() { frameFixture.cleanUp(); } @Test public void createCouchbaseConfiguration() throws Exception { frameFixture.textBox("labelField").setText("Localhost"); frameFixture.label("databaseVendorLabel").requireText("Couchbase"); frameFixture.label("databaseTipsLabel").requireText("format: host:port. If cluster: host:port1,host:port2,..."); frameFixture.textBox("serverUrlField").setText("localhost:25"); frameFixture.textBox("usernameField").setText("john"); frameFixture.textBox("passwordField").setText("johnpassword"); frameFixture.textBox("userDatabaseField").setText("mybucket"); frameFixture.checkBox("autoConnectField").check(); ServerConfiguration configuration = new ServerConfiguration(); configurationPanel.applyConfigurationData(configuration); assertEquals("Localhost", configuration.getLabel()); assertEquals(DatabaseVendor.COUCHBASE, configuration.getDatabaseVendor()); assertEquals("localhost:25", configuration.getServerUrl()); AuthenticationSettings authenticationSettings = configuration.getAuthenticationSettings(); assertEquals("john", authenticationSettings.getUsername()); assertEquals("johnpassword", authenticationSettings.getPassword()); assertEquals("mybucket", configuration.getUserDatabase()); assertTrue(configuration.isConnectOnIdeStartup()); } @Test public void loadCouchbaseConfiguration() throws Exception { ServerConfiguration configuration = new ServerConfiguration(); configuration.setLabel("Localhost"); configuration.setDatabaseVendor(DatabaseVendor.COUCHBASE); configuration.setServerUrl("localhost:25"); AuthenticationSettings authenticationSettings = new AuthenticationSettings(); authenticationSettings.setUsername("john"); authenticationSettings.setPassword("johnpassword"); configuration.setAuthenticationSettings(authenticationSettings); configurationPanel.loadConfigurationData(configuration); frameFixture.textBox("labelField").requireText("Localhost"); frameFixture.label("databaseVendorLabel").requireText("Couchbase"); frameFixture.label("databaseTipsLabel").requireText("format: host:port. If cluster: host:port1,host:port2,..."); frameFixture.textBox("serverUrlField").requireText("localhost:25"); frameFixture.textBox("usernameField").requireText("john"); frameFixture.textBox("passwordField").requireText("johnpassword"); } } ================================================ FILE: src/test/java/org/codinjutsu/tools/nosql/mongo/logic/MongoClientTest.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.logic; import com.mongodb.BasicDBList; import com.mongodb.BasicDBObject; import com.mongodb.DBObject; import com.mongodb.client.MongoDatabase; import com.mongodb.util.JSON; import org.apache.commons.io.IOUtils; import org.bson.Document; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.codinjutsu.tools.nosql.mongo.model.MongoCollection; import org.codinjutsu.tools.nosql.mongo.model.MongoResult; import org.codinjutsu.tools.nosql.mongo.model.MongoQueryOptions; import org.junit.Before; import org.junit.Test; import java.io.IOException; import java.util.List; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNotNull; public class MongoClientTest { private MongoClient mongoClient; private ServerConfiguration serverConfiguration; @Test public void loadCollectionsWithEmptyFilter() throws Exception { MongoQueryOptions mongoQueryOptions = new MongoQueryOptions(); mongoQueryOptions.setResultLimit(3); MongoResult mongoResult = mongoClient.loadCollectionValues(serverConfiguration, new MongoCollection("dummyCollection", "test"), mongoQueryOptions); assertNotNull(mongoResult); assertEquals(3, mongoResult.getMongoObjects().size()); } @Test public void loadCollectionsWithFilterAndProjection() throws Exception { MongoQueryOptions mongoQueryOptions = new MongoQueryOptions(); mongoQueryOptions.setFilter("{\"label\":\"tata\"}"); mongoQueryOptions.setProjection("{\"label\":1, \"_id\": 0}"); mongoQueryOptions.setResultLimit(3); MongoResult mongoResult = mongoClient.loadCollectionValues(serverConfiguration, new MongoCollection("dummyCollection", "test"), mongoQueryOptions); assertNotNull(mongoResult); assertEquals(2, mongoResult.getMongoObjects().size()); assertEquals("[{ \"label\" : \"tata\"}, { \"label\" : \"tata\"}]", mongoResult.getMongoObjects().toString()); } @Test public void loadCollectionsWithFilterAndProjectionAndSortByPrice() throws Exception { MongoQueryOptions mongoQueryOptions = new MongoQueryOptions(); mongoQueryOptions.setFilter("{\"label\":\"tata\"}"); mongoQueryOptions.setProjection("{\"label\": 1, \"_id\": 0, \"price\": 1}"); mongoQueryOptions.setSort("{\"price\": 1}"); mongoQueryOptions.setResultLimit(3); MongoResult mongoResult = mongoClient.loadCollectionValues(serverConfiguration, new MongoCollection("dummyCollection", "test"), mongoQueryOptions); assertNotNull(mongoResult); assertEquals(2, mongoResult.getMongoObjects().size()); assertEquals("[{ \"label\" : \"tata\" , \"price\" : 10}, { \"label\" : \"tata\" , \"price\" : 15}]", mongoResult.getMongoObjects().toString()); } @Test public void updateMongoDocument() throws Exception { MongoQueryOptions mongoQueryOptions = new MongoQueryOptions(); mongoQueryOptions.setFilter("{'label': 'tete'}"); MongoCollection mongoCollection = new MongoCollection("dummyCollection", "test"); MongoResult initialData = mongoClient.loadCollectionValues(serverConfiguration, mongoCollection, mongoQueryOptions); assertEquals(1, initialData.getMongoObjects().size()); DBObject initialMongoDocument = initialData.getMongoObjects().get(0); initialMongoDocument.put("price", 25); mongoClient.update(serverConfiguration, mongoCollection, initialMongoDocument); MongoResult updatedResult = mongoClient.loadCollectionValues(serverConfiguration, mongoCollection, mongoQueryOptions); List updatedMongoDocuments = updatedResult.getMongoObjects(); assertEquals(1, updatedMongoDocuments.size()); DBObject updatedMongoDocument = updatedMongoDocuments.get(0); assertEquals(25, updatedMongoDocument.get("price")); } @Test public void deleteMongoDocument() throws Exception { MongoQueryOptions mongoQueryOptions = new MongoQueryOptions(); mongoQueryOptions.setFilter("{'label': 'tete'}"); MongoCollection mongoCollection = new MongoCollection("dummyCollection", "test"); MongoResult initialData = mongoClient.loadCollectionValues(serverConfiguration, mongoCollection, mongoQueryOptions); assertEquals(1, initialData.getMongoObjects().size()); DBObject initialMongoDocument = initialData.getMongoObjects().get(0); mongoClient.delete(serverConfiguration, mongoCollection, initialMongoDocument.get("_id")); MongoResult deleteResult = mongoClient.loadCollectionValues(serverConfiguration, mongoCollection, mongoQueryOptions); List updatedMongoDocuments = deleteResult.getMongoObjects(); assertEquals(0, updatedMongoDocuments.size()); } @Test public void loadCollectionsWithAggregateOperators() throws Exception { MongoQueryOptions mongoQueryOptions = new MongoQueryOptions(); mongoQueryOptions.setOperations("[{'$match': {'price': 15}}, {'$project': {'label': 1, 'price': 1}}, {'$group': {'_id': '$label', 'total': {'$sum': '$price'}}}]"); MongoResult mongoResult = mongoClient.loadCollectionValues(serverConfiguration, new MongoCollection("dummyCollection", "test"), mongoQueryOptions); assertNotNull(mongoResult); List mongoObjects = mongoResult.getMongoObjects(); assertEquals(2, mongoObjects.size()); assertEquals("{ \"_id\" : \"tutu\" , \"total\" : 15}", mongoObjects.get(0).toString()); assertEquals("{ \"_id\" : \"tata\" , \"total\" : 15}", mongoObjects.get(1).toString()); } @Before public void setUp() throws Exception { com.mongodb.MongoClient mongo = new com.mongodb.MongoClient("localhost:27017"); MongoDatabase db = mongo.getDatabase("test"); com.mongodb.client.MongoCollection dummyCollection = db.getCollection("dummyCollection"); dummyCollection.deleteMany(new BasicDBObject()); fillCollectionWithJsonData(dummyCollection, IOUtils.toString(getClass().getResourceAsStream("dummyCollection.json"))); mongoClient = new MongoClient(); serverConfiguration = mongoClient.defaultConfiguration(); serverConfiguration.setServerUrl("localhost:27017"); } private static void fillCollectionWithJsonData(com.mongodb.client.MongoCollection collection, String jsonResource) throws IOException { Object jsonParsed = JSON.parse(jsonResource); if (jsonParsed instanceof BasicDBList) { BasicDBList jsonObject = (BasicDBList) jsonParsed; for (Object o : jsonObject) { DBObject dbObject = (DBObject) o; Document document = new Document(); for (String key : dbObject.keySet()) { document.append(key, dbObject.get(key)); } collection.insertOne(document); } } else { DBObject dbObject = (DBObject) jsonParsed; Document document = new Document(); for (String key : dbObject.keySet()) { document.append(key, dbObject.get(key)); } collection.insertOne(document); } } } ================================================ FILE: src/test/java/org/codinjutsu/tools/nosql/mongo/logic/MongoClientURIBuilderTest.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.logic; import com.mongodb.AuthenticationMechanism; import org.codinjutsu.tools.nosql.mongo.logic.MongoClientURIBuilder; import org.junit.Test; import static org.junit.Assert.assertEquals; public class MongoClientURIBuilderTest { @Test public void withoutAuthentication() throws Exception { assertEquals( "mongodb://localhost:27017,localhost:27018/", MongoClientURIBuilder.builder() .setServerAddresses("localhost:27017,localhost:27018") .build()); } @Test public void withSimpleAuthentication() throws Exception { assertEquals( "mongodb://toto:pass@localhost:27018/?authSource=userdb", MongoClientURIBuilder.builder() .setServerAddresses("localhost:27018") .setCredential("toto", "pass", "userdb") .build()); } @Test public void withSpecificAuthentication() throws Exception { assertEquals( "mongodb://toto:pass@localhost:27018/?authMechanism=MONGODB-CR&authSource=userdb", MongoClientURIBuilder.builder() .setServerAddresses("localhost:27018") .setCredential("toto", "pass", "userdb") .setAuthenticationMecanism(AuthenticationMechanism.MONGODB_CR) .build()); } @Test public void addSslOption() throws Exception { assertEquals( "mongodb://localhost:27018/?ssl=true", MongoClientURIBuilder.builder() .setServerAddresses("localhost:27018") .sslEnabled() .build()); } } ================================================ FILE: src/test/java/org/codinjutsu/tools/nosql/mongo/view/MongoEditionPanelTest.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view; import com.mongodb.DBObject; import com.mongodb.util.JSON; import org.apache.commons.io.IOUtils; import org.bson.types.ObjectId; import org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor; import org.fest.swing.data.TableCell; import org.fest.swing.driver.BasicJTableCellReader; import org.fest.swing.edt.GuiActionRunner; import org.fest.swing.edt.GuiQuery; import org.fest.swing.fixture.Containers; import org.fest.swing.fixture.FrameFixture; import org.fest.swing.fixture.JTableFixture; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import javax.swing.*; import java.io.IOException; import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; public class MongoEditionPanelTest { private MongoEditionPanel mongoEditionPanel; private FrameFixture frameFixture; private MongoPanel.MongoDocumentOperations mockMongoOperations = mock(MongoPanel.MongoDocumentOperations.class); private MongoResultPanel.ActionCallback mockActionCallback = mock(MongoResultPanel.ActionCallback.class); @After public void tearDown() { frameFixture.cleanUp(); } @Before public void setUp() throws Exception { mongoEditionPanel = GuiActionRunner.execute(new GuiQuery() { protected MongoEditionPanel executeInEDT() { MongoEditionPanel panel = new MongoEditionPanel() { @Override void buildPopupMenu() { } }; return panel.init(mockMongoOperations, mockActionCallback); } }); mongoEditionPanel.updateEditionTree(buildDocument("simpleDocument.json")); frameFixture = Containers.showInFrame(mongoEditionPanel); } @Test public void displayMongoDocumentInTheTreeTable() throws Exception { frameFixture.table("editionTreeTable").cellReader(new JsonTableCellReader()) .requireColumnCount(2) .requireContents(new String[][]{ {"_id", "50b8d63414f85401b9268b99"}, {"label", "toto"}, {"visible", "false"}, {"image", "null"} }); } @Test public void editKeyWithStringValue() throws Exception { JTableFixture editionTreeTable = frameFixture.table("editionTreeTable").cellReader(new JsonTableCellReader()); // edit 'label' key editionTreeTable.enterValue(TableCell.row(1).column(1), "Hello"); frameFixture.button("saveButton").click(); ArgumentCaptor argument = ArgumentCaptor.forClass(DBObject.class); verify(mockMongoOperations).updateMongoDocument(argument.capture()); Assert.assertEquals("{ \"_id\" : { \"$oid\" : \"50b8d63414f85401b9268b99\"} , \"label\" : \"Hello\" , \"visible\" : false , \"image\" : null }", argument.getValue().toString()); verify(mockActionCallback, times(1)).onOperationSuccess(any(String.class)); } @Test public void cancelEdition() throws Exception { JTableFixture editionTreeTable = frameFixture.table("editionTreeTable").cellReader(new JsonTableCellReader()); // edit 'label' key editionTreeTable.enterValue(TableCell.row(1).column(1), "Hello"); frameFixture.button("cancelButton").click(); verify(mockMongoOperations, times(0)).updateMongoDocument(any(DBObject.class)); verify(mockActionCallback, times(1)).onOperationCancelled(any(String.class)); } @Test public void addKeyWithSomeValue() throws Exception { JTableFixture editionTreeTable = frameFixture.table("editionTreeTable").cellReader(new JsonTableCellReader()); editionTreeTable.selectCell(TableCell.row(1).column(1)); mongoEditionPanel.addKey("stringKey", "pouet"); editionTreeTable.selectCell(TableCell.row(1).column(1)); mongoEditionPanel.addKey("numberKey", "1.1"); editionTreeTable.requireContents(new String[][]{ {"_id", "50b8d63414f85401b9268b99"}, {"label", "toto"}, {"visible", "false"}, {"image", "null"}, {"stringKey", "pouet"}, {"numberKey", "1.1"}, }); } @Test public void addValueInAList() throws Exception { mongoEditionPanel.updateEditionTree(buildDocument("simpleDocumentWithSubList.json")); JTableFixture editionTreeTable = frameFixture.table("editionTreeTable").cellReader(new JsonTableCellReader()); editionTreeTable.requireContents(new String[][]{ {"_id", "50b8d63414f85401b9268b99"}, {"title", "XP by example"}, {"tags", "[ \"pair programming\" , \"tdd\" , \"agile\"]"}, {"[0]", "pair programming"}, {"[1]", "tdd"}, {"[2]", "agile"}, {"innerList", "[ [ 1 , 2 , 3 , 4] , [ false , true] , [ { \"tagName\" : \"pouet\"} , { \"tagName\" : \"paf\"}]]"}, {"[0]", "[ 1 , 2 , 3 , 4]"}, {"[1]", "[ false , true]"}, {"[2]", "[ { \"tagName\" : \"pouet\"} , { \"tagName\" : \"paf\"}]"}}); editionTreeTable.selectCell(TableCell.row(3).column(1)); mongoEditionPanel.addValue("refactor"); editionTreeTable.requireContents(new String[][]{ {"_id", "50b8d63414f85401b9268b99"}, {"title", "XP by example"}, {"tags", "[ \"pair programming\" , \"tdd\" , \"agile\"]"}, {"[0]", "pair programming"}, {"[1]", "tdd"}, {"[2]", "agile"}, {"[3]", "refactor"}, {"innerList", "[ [ 1 , 2 , 3 , 4] , [ false , true] , [ { \"tagName\" : \"pouet\"} , { \"tagName\" : \"paf\"}]]"}, {"[0]", "[ 1 , 2 , 3 , 4]"}, {"[1]", "[ false , true]"}, {"[2]", "[ { \"tagName\" : \"pouet\"} , { \"tagName\" : \"paf\"}]"}}); } private static class JsonTableCellReader extends BasicJTableCellReader { @Override public String valueAt(JTable table, int row, int column) { Object value = table.getValueAt(row, column); if (value instanceof NodeDescriptor) { NodeDescriptor nodeDescriptor = (NodeDescriptor) value; return nodeDescriptor.getFormattedKey(); } else { return value == null ? "null" : value.toString(); } } } private DBObject buildDocument(String jsonFile) throws IOException { DBObject mongoDocument = (DBObject) JSON.parse(IOUtils.toString(getClass().getResourceAsStream(jsonFile))); mongoDocument.put("_id", new ObjectId(String.valueOf(mongoDocument.get("_id")))); return mongoDocument; } } ================================================ FILE: src/test/java/org/codinjutsu/tools/nosql/mongo/view/MongoResultPanelTest.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view; import com.intellij.openapi.command.impl.DummyProject; import com.intellij.util.ui.tree.TreeUtil; import com.mongodb.DBObject; import com.mongodb.util.JSON; import org.apache.commons.io.IOUtils; import org.codinjutsu.tools.nosql.commons.view.TableCellReader; import org.codinjutsu.tools.nosql.mongo.model.MongoResult; import org.fest.swing.edt.GuiActionRunner; import org.fest.swing.edt.GuiQuery; import org.fest.swing.fixture.Containers; import org.fest.swing.fixture.FrameFixture; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.io.IOException; import static org.junit.Assert.assertEquals; public class MongoResultPanelTest { private MongoResultPanel mongoResultPanel; private FrameFixture frameFixture; @Mock private MongoPanel.MongoDocumentOperations mongoDocumentOperations; @After public void tearDown() { frameFixture.cleanUp(); } @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(MongoResultPanelTest.class); mongoResultPanel = GuiActionRunner.execute(new GuiQuery() { protected MongoResultPanel executeInEDT() { return new MongoResultPanel(DummyProject.getInstance(), mongoDocumentOperations) { @Override void buildPopupMenu() { } }; } }); frameFixture = Containers.showInFrame(mongoResultPanel); } @Test public void displayTreeWithASimpleArray() throws Exception { mongoResultPanel.updateResultTableTree(createCollectionResults("simpleArray.json", "mycollec")); frameFixture.table("resultTreeTable").cellReader(new TableCellReader()) .requireColumnCount(2) .requireContents(new String[][]{ {"[0]", "\"toto\""}, {"[1]", "true"}, {"[2]", "10"}, {"[3]", "null"}, }); } @Test public void testDisplayTreeWithASimpleDocument() throws Exception { mongoResultPanel.updateResultTableTree(createCollectionResults("simpleDocument.json", "mycollec")); frameFixture.table("resultTreeTable").cellReader(new TableCellReader()) .requireColumnCount(2) .requireContents(new String[][]{ {"[0]", "{ \"_id\" : \"50b8d63414f85401b9268b99\" , \"label\" : \"toto\" , \"visible\" : false , \"image\" : null }"}, {"_id", "\"50b8d63414f85401b9268b99\""}, {"label", "\"toto\""}, {"visible", "false"}, {"image", "null"} }); } @Test public void testDisplayTreeWithAStructuredDocument() throws Exception { mongoResultPanel.updateResultTableTree(createCollectionResults("structuredDocument.json", "mycollec")); TreeUtil.expandAll(mongoResultPanel.resultTableView.getTree()); frameFixture.table("resultTreeTable").cellReader(new TableCellReader()) .requireColumnCount(2) .requireContents(new String[][]{ {"[0]", "{ \"id\" : 0 , \"label\" : \"toto\" , \"visible\" : false , \"doc\" : { \"title\" : \"hello\" , \"nbPages\" : 10 , \"keyWord\" : [ \"toto\" , true , 10]}}"}, {"id", "0"}, {"label", "\"toto\""}, {"visible", "false"}, {"doc", "{ \"title\" : \"hello\" , \"nbPages\" : 10 , \"keyWord\" : [ \"toto\" , true , 10]}"}, {"title", "\"hello\""}, {"nbPages", "10"}, {"keyWord", "[ \"toto\" , true , 10]"}, {"[0]", "\"toto\""}, {"[1]", "true"}, {"[2]", "10"}, }); } @Test public void testDisplayTreeWithAnArrayOfStructuredDocument() throws Exception { mongoResultPanel.updateResultTableTree(createCollectionResults("arrayOfDocuments.json", "mycollec")); TreeUtil.expandAll(mongoResultPanel.resultTableView.getTree()); frameFixture.table("resultTreeTable").cellReader(new TableCellReader()) .requireContents(new String[][]{ {"[0]", "{ \"id\" : 0 , \"label\" : \"toto\" , \"visible\" : false , \"doc\" : { \"title\" : \"hello\" , \"nbPages\" : 10 , \"keyWord\" : [ \"toto\" , true , 10]}}"}, {"id", "0"}, {"label", "\"toto\""}, {"visible", "false"}, {"doc", "{ \"title\" : \"hello\" , \"nbPages\" : 10 , \"keyWord\" : [ \"toto\" , true , 10]}"}, {"title", "\"hello\""}, {"nbPages", "10"}, {"keyWord", "[ \"toto\" , true , 10]"}, {"[0]", "\"toto\""}, {"[1]", "true"}, {"[2]", "10"}, {"[1]", "{ \"id\" : 1 , \"label\" : \"tata\" , \"visible\" : true , \"doc\" : { \"title\" : \"ola\" , \"nbPages\" : 1 , \"keyWord\" : [ \"tutu\" , false , 10]}}"}, {"id", "1"}, {"label", "\"tata\""}, {"visible", "true"}, {"doc", "{ \"title\" : \"ola\" , \"nbPages\" : 1 , \"keyWord\" : [ \"tutu\" , false , 10]}"}, {"title", "\"ola\""}, {"nbPages", "1"}, {"keyWord", "[ \"tutu\" , false , 10]"}, {"[0]", "\"tutu\""}, {"[1]", "false"}, {"[2]", "10"}, }); } @Test public void testCopyMongoObjectNodeValue() throws Exception { mongoResultPanel.updateResultTableTree(createCollectionResults("structuredDocument.json", "mycollec")); TreeUtil.expandAll(mongoResultPanel.resultTableView.getTree()); mongoResultPanel.resultTableView.setRowSelectionInterval(0, 0); assertEquals("{ \"id\" : 0 , \"label\" : \"toto\" , \"visible\" : false , \"doc\" : { \"title\" : \"hello\" , \"nbPages\" : 10 , \"keyWord\" : [ \"toto\" , true , 10]}}", mongoResultPanel.getSelectedNodeStringifiedValue()); mongoResultPanel.resultTableView.setRowSelectionInterval(2, 2); assertEquals("\"label\" : \"toto\"", mongoResultPanel.getSelectedNodeStringifiedValue()); mongoResultPanel.resultTableView.setRowSelectionInterval(4, 4); assertEquals("\"doc\" : { \"title\" : \"hello\" , \"nbPages\" : 10 , \"keyWord\" : [ \"toto\" , true , 10]}", mongoResultPanel.getSelectedNodeStringifiedValue()); } @Test public void copyMongoResults() throws Exception { mongoResultPanel.updateResultTableTree(createCollectionResults("arrayOfDocuments.json", "mycollec")); TreeUtil.expandAll(mongoResultPanel.resultTableView.getTree()); frameFixture.table("resultTreeTable").cellReader(new TableCellReader()) .requireContents(new String[][]{ {"[0]", "{ \"id\" : 0 , \"label\" : \"toto\" , \"visible\" : false , \"doc\" : { \"title\" : \"hello\" , \"nbPages\" : 10 , \"keyWord\" : [ \"toto\" , true , 10]}}"}, {"id", "0"}, {"label", "\"toto\""}, {"visible", "false"}, {"doc", "{ \"title\" : \"hello\" , \"nbPages\" : 10 , \"keyWord\" : [ \"toto\" , true , 10]}"}, {"title", "\"hello\""}, {"nbPages", "10"}, {"keyWord", "[ \"toto\" , true , 10]"}, {"[0]", "\"toto\""}, {"[1]", "true"}, {"[2]", "10"}, {"[1]", "{ \"id\" : 1 , \"label\" : \"tata\" , \"visible\" : true , \"doc\" : { \"title\" : \"ola\" , \"nbPages\" : 1 , \"keyWord\" : [ \"tutu\" , false , 10]}}"}, {"id", "1"}, {"label", "\"tata\""}, {"visible", "true"}, {"doc", "{ \"title\" : \"ola\" , \"nbPages\" : 1 , \"keyWord\" : [ \"tutu\" , false , 10]}"}, {"title", "\"ola\""}, {"nbPages", "1"}, {"keyWord", "[ \"tutu\" , false , 10]"}, {"[0]", "\"tutu\""}, {"[1]", "false"}, {"[2]", "10"}, }); assertEquals("[ " + "{ \"id\" : 0 , \"label\" : \"toto\" , \"visible\" : false , \"doc\" : { \"title\" : \"hello\" , \"nbPages\" : 10 , \"keyWord\" : [ \"toto\" , true , 10]}} , " + "{ \"id\" : 1 , \"label\" : \"tata\" , \"visible\" : true , \"doc\" : { \"title\" : \"ola\" , \"nbPages\" : 1 , \"keyWord\" : [ \"tutu\" , false , 10]}}" + " ]", mongoResultPanel.getSelectedNodeStringifiedValue()); } private MongoResult createCollectionResults(String data, String collectionName) throws IOException { DBObject jsonObject = (DBObject) JSON.parse(IOUtils.toString(getClass().getResourceAsStream(data))); MongoResult mongoResult = new MongoResult(collectionName); mongoResult.add(jsonObject); return mongoResult; } } ================================================ FILE: src/test/java/org/codinjutsu/tools/nosql/mongo/view/ServerConfigurationPanelTest.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view; import com.intellij.openapi.command.impl.DummyProject; import com.mongodb.AuthenticationMechanism; import org.codinjutsu.tools.nosql.DatabaseVendor; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.codinjutsu.tools.nosql.commons.logic.ConfigurationException; import org.codinjutsu.tools.nosql.commons.logic.DatabaseClient; import org.codinjutsu.tools.nosql.commons.model.AuthenticationSettings; import org.codinjutsu.tools.nosql.commons.view.ServerConfigurationPanel; import org.codinjutsu.tools.nosql.mongo.logic.MongoExtraSettings; import org.fest.swing.edt.GuiActionRunner; import org.fest.swing.edt.GuiQuery; import org.fest.swing.fixture.Containers; import org.fest.swing.fixture.FrameFixture; import org.junit.*; import org.junit.rules.ExpectedException; import org.mockito.Mockito; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; public class ServerConfigurationPanelTest { @Rule public ExpectedException thrown = ExpectedException.none(); private ServerConfigurationPanel configurationPanel; private DatabaseClient databaseClientMock; private FrameFixture frameFixture; @Before public void setUp() throws Exception { databaseClientMock = Mockito.mock(DatabaseClient.class); configurationPanel = GuiActionRunner.execute(new GuiQuery() { protected ServerConfigurationPanel executeInEDT() { return new ServerConfigurationPanel(DummyProject.getInstance(), DatabaseVendor.MONGO, databaseClientMock, new MongoAuthenticationPanel() ); } }); frameFixture = Containers.showInFrame(configurationPanel); } @After public void tearDown() { frameFixture.cleanUp(); } @Test public void createMongoConfiguration() throws Exception { frameFixture.textBox("labelField").setText("Localhost"); frameFixture.label("databaseVendorLabel").requireText("MongoDB"); frameFixture.label("databaseTipsLabel").requireText("format: host:port. If replicat set: host:port1,host:port2,..."); frameFixture.textBox("serverUrlField").setText("localhost:25"); frameFixture.textBox("usernameField").setText("john"); frameFixture.textBox("passwordField").setText("johnpassword"); frameFixture.textBox("userDatabaseField").setText("mydatabase"); frameFixture.textBox("authenticationDatabaseField").setText("admin"); frameFixture.radioButton("defaultAuthMethod").requireSelected(); frameFixture.radioButton("mongoCRAuthField").click(); frameFixture.checkBox("sslConnectionField").check(); frameFixture.checkBox("autoConnectField").check(); ServerConfiguration configuration = new ServerConfiguration(); configurationPanel.applyConfigurationData(configuration); assertEquals("Localhost", configuration.getLabel()); assertEquals(DatabaseVendor.MONGO, configuration.getDatabaseVendor()); assertEquals("localhost:25", configuration.getServerUrl()); AuthenticationSettings authenticationSettings = configuration.getAuthenticationSettings(); assertEquals("john", authenticationSettings.getUsername()); assertEquals("johnpassword", authenticationSettings.getPassword()); MongoExtraSettings mongoExtraSettings = new MongoExtraSettings(authenticationSettings.getExtras()); assertEquals("admin", mongoExtraSettings.getAuthenticationDatabase()); assertEquals(AuthenticationMechanism.MONGODB_CR, mongoExtraSettings.getAuthenticationMechanism()); assertEquals("mydatabase", configuration.getUserDatabase()); assertTrue(configuration.isConnectOnIdeStartup()); } @Test public void loadMongoConfiguration() throws Exception { ServerConfiguration configuration = new ServerConfiguration(); configuration.setLabel("Localhost"); configuration.setDatabaseVendor(DatabaseVendor.MONGO); configuration.setServerUrl("localhost:25"); AuthenticationSettings authenticationSettings = new AuthenticationSettings(); authenticationSettings.setUsername("john"); authenticationSettings.setPassword("johnpassword"); MongoExtraSettings mongoExtraSettings = new MongoExtraSettings(); mongoExtraSettings.setAuthenticationDatabase("admin"); mongoExtraSettings.setAuthenticationMechanism(AuthenticationMechanism.SCRAM_SHA_1); mongoExtraSettings.setSsl(true); authenticationSettings.setExtras(mongoExtraSettings.get()); configuration.setAuthenticationSettings(authenticationSettings); configuration.setUserDatabase("mydatabase"); configurationPanel.loadConfigurationData(configuration); frameFixture.textBox("labelField").requireText("Localhost"); frameFixture.textBox("serverUrlField").requireText("localhost:25"); frameFixture.textBox("usernameField").requireText("john"); frameFixture.textBox("passwordField").requireText("johnpassword"); frameFixture.textBox("authenticationDatabaseField").requireText("admin"); frameFixture.checkBox("sslConnectionField").requireSelected(); frameFixture.radioButton("scramSHA1AuthField").requireSelected(); } @Test public void validateFormWithEmptyLabelShouldReturnAValidationInfo() { assertEquals("Label should be set", configurationPanel.validateInputs().message); } @Test public void validateFormWithMissingMongoUrlShouldThrowAConfigurationException() { frameFixture.textBox("labelField").setText("Localhost"); frameFixture.textBox("serverUrlField").setText(null); assertEquals("URL(s) should be set", configurationPanel.validateInputs().message); } @Test public void validateFormWithEmptyMongoUrlShouldReturnAValidationInfo() { frameFixture.textBox("labelField").setText("Localhost"); frameFixture.textBox("serverUrlField").setText(""); assertEquals("URL(s) should be set", configurationPanel.validateInputs().message); } @Test @Ignore public void validateFormWithBadMongoUrlShouldReturnAValidationInfo() { frameFixture.textBox("labelField").setText("Localhost"); frameFixture.textBox("serverUrlField").setText("host"); configurationPanel.applyConfigurationData(new ServerConfiguration()); } @Test @Ignore public void validateFormWithBadMongoPortShouldThrowAConfigurationException() { thrown.expect(ConfigurationException.class); thrown.expectMessage("Port in the URL 'host:port' is incorrect. It should be a number"); frameFixture.textBox("labelField").setText("Localhost"); frameFixture.textBox("serverUrlField").setText("host:port"); configurationPanel.applyConfigurationData(new ServerConfiguration()); } @Test public void validateFormWithReplicatSet() throws Exception { frameFixture.textBox("labelField").setText("Localhost"); frameFixture.textBox("serverUrlField").setText("localhost:25, localhost:26"); ServerConfiguration configuration = new ServerConfiguration(); configurationPanel.applyConfigurationData(configuration); assertEquals("localhost:25, localhost:26", configuration.getServerUrl()); } @Test public void loadFormWithReplicatSet() throws Exception { ServerConfiguration configuration = new ServerConfiguration(); configuration.setAuthenticationSettings(new AuthenticationSettings()); configuration.setServerUrl("localhost:25, localhost:26"); configurationPanel.loadConfigurationData(configuration); frameFixture.textBox("serverUrlField").requireText("localhost:25, localhost:26"); } } ================================================ FILE: src/test/java/org/codinjutsu/tools/nosql/mongo/view/model/JsonTreeModelTest.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.mongo.view.model; import com.mongodb.BasicDBList; import com.mongodb.DBObject; import com.mongodb.util.JSON; import org.apache.commons.io.IOUtils; import org.bson.types.ObjectId; import org.codinjutsu.tools.nosql.commons.view.NoSqlTreeNode; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; public class JsonTreeModelTest { @Test public void buildDBObjectFromSimpleTree() throws Exception { DBObject jsonObject = (DBObject) JSON.parse(IOUtils.toString(getClass().getResourceAsStream("simpleDocument.json"))); // Hack to convert _id fron string to ObjectId jsonObject.put("_id", new ObjectId(String.valueOf(jsonObject.get("_id")))); NoSqlTreeNode treeNode = (NoSqlTreeNode) JsonTreeModel.buildJsonTree(jsonObject); NoSqlTreeNode labelNode = (NoSqlTreeNode) treeNode.getChildAt(1); labelNode.getDescriptor().setValue("tata"); DBObject dbObject = JsonTreeModel.buildDBObject(treeNode); assertEquals("{ \"_id\" : { \"$oid\" : \"50b8d63414f85401b9268b99\"} , \"label\" : \"tata\" , \"visible\" : false , \"image\" : null }", dbObject.toString()); } @Test public void buildDBObjectFromTreeWithSubNodes() throws Exception { DBObject jsonObject = (DBObject) JSON.parse(IOUtils.toString(getClass().getResourceAsStream("simpleDocumentWithInnerNodes.json"))); // Hack to convert _id fron string to ObjectId jsonObject.put("_id", new ObjectId(String.valueOf(jsonObject.get("_id")))); NoSqlTreeNode treeNode = (NoSqlTreeNode) JsonTreeModel.buildJsonTree(jsonObject); // Simulate updating from the treeNode NoSqlTreeNode innerDocNode = (NoSqlTreeNode) treeNode.getChildAt(4); NoSqlTreeNode soldOutNode = (NoSqlTreeNode) innerDocNode.getChildAt(2); soldOutNode.getDescriptor().setValue("false"); DBObject dbObject = JsonTreeModel.buildDBObject(treeNode); assertEquals("{ \"_id\" : { \"$oid\" : \"50b8d63414f85401b9268b99\"} , \"label\" : \"toto\" , \"visible\" : false , \"image\" : null , \"innerdoc\" : { \"title\" : \"What?\" , \"numberOfPages\" : 52 , \"soldOut\" : false}}", dbObject.toString()); } @Test public void buildDBObjectFromTreeWithSubList() throws Exception { DBObject jsonObject = (DBObject) JSON.parse(IOUtils.toString(getClass().getResourceAsStream("simpleDocumentWithSubList.json"))); // Hack to convert _id fron string to ObjectId jsonObject.put("_id", new ObjectId(String.valueOf(jsonObject.get("_id")))); NoSqlTreeNode treeNode = (NoSqlTreeNode) JsonTreeModel.buildJsonTree(jsonObject); NoSqlTreeNode tagsNode = (NoSqlTreeNode) treeNode.getChildAt(2); NoSqlTreeNode agileTagNode = (NoSqlTreeNode) tagsNode.getChildAt(2); agileTagNode.getDescriptor().setValue("a gilles"); DBObject dbObject = JsonTreeModel.buildDBObject(treeNode); assertEquals("{ \"_id\" : { \"$oid\" : \"50b8d63414f85401b9268b99\"} , \"title\" : \"XP by example\" , \"tags\" : [ \"pair programming\" , \"tdd\" , \"a gilles\"] , \"innerList\" : [ [ 1 , 2 , 3 , 4] , [ false , true] , [ { \"tagName\" : \"pouet\"} , { \"tagName\" : \"paf\"}]]}", dbObject.toString()); } @Test public void getObjectIdFromANode() throws Exception { DBObject jsonObject = (DBObject) JSON.parse(IOUtils.toString(getClass().getResourceAsStream("simpleDocumentWithInnerNodes.json"))); jsonObject.put("_id", new ObjectId(String.valueOf(jsonObject.get("_id")))); NoSqlTreeNode treeNode = (NoSqlTreeNode) JsonTreeModel.buildJsonTree(jsonObject); NoSqlTreeNode objectIdNode = (NoSqlTreeNode) treeNode.getChildAt(0); assertEquals("_id", objectIdNode.getDescriptor().getFormattedKey()); assertNull(JsonTreeModel.findObjectIdNode(treeNode)); assertEquals(objectIdNode, JsonTreeModel.findObjectIdNode((NoSqlTreeNode) treeNode.getChildAt(0))); } @Test public void findDocumentFromANode() throws Exception { BasicDBList dbList = (BasicDBList) JSON.parse(IOUtils.toString(getClass().getResourceAsStream("arrayOfDocuments.json"))); DBObject first = (DBObject) dbList.get(0); first.put("_id", new ObjectId(String.valueOf(first.get("_id")))); DBObject second = (DBObject) dbList.get(1); second.put("_id", new ObjectId(String.valueOf(second.get("_id")))); NoSqlTreeNode treeNode = (NoSqlTreeNode) JsonTreeModel.buildJsonTree(dbList); assertEquals(first, JsonTreeModel.findDocument((NoSqlTreeNode) treeNode.getChildAt(0))); } } ================================================ FILE: src/test/java/org/codinjutsu/tools/nosql/redis/logic/RedisClientTest.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.redis.logic; import org.codinjutsu.tools.nosql.DatabaseVendor; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.codinjutsu.tools.nosql.redis.model.*; import org.junit.Before; import org.junit.Test; import redis.clients.jedis.Jedis; import java.util.List; import static org.junit.Assert.assertEquals; public class RedisClientTest { private Jedis jedis; @Test public void loadWithEmptyFilter() throws Exception { jedis.sadd("books", "eXtreme Programming", "Haskell for Dummies"); jedis.set("status", "online"); jedis.lpush("todos", "coffee", "code", "drink", "sleep"); jedis.zadd("reviews", 12.0d, "writing"); jedis.zadd("reviews", 14.0d, "reading"); jedis.zadd("reviews", 15.0d, "maths"); RedisClient redisClient = new RedisClient(); ServerConfiguration serverConfiguration = new ServerConfiguration(); serverConfiguration.setDatabaseVendor(DatabaseVendor.REDIS); serverConfiguration.setServerUrl("localhost:6379"); RedisQuery query = new RedisQuery("*"); RedisResult result = redisClient.loadRecords(serverConfiguration, new RedisDatabase("1"), query); List redisRecords = result.getResults(); assertEquals(4, redisRecords.size()); RedisRecord redisRecord = redisRecords.get(0); assertEquals(RedisKeyType.SET, redisRecord.getKeyType()); assertEquals("books", redisRecord.getKey()); redisRecord = redisRecords.get(1); assertEquals(RedisKeyType.ZSET, redisRecord.getKeyType()); assertEquals("reviews", redisRecord.getKey()); redisRecord = redisRecords.get(2); assertEquals(RedisKeyType.LIST, redisRecord.getKeyType()); assertEquals("todos", redisRecord.getKey()); redisRecord = redisRecords.get(3); assertEquals(RedisKeyType.STRING, redisRecord.getKeyType()); assertEquals("status", redisRecord.getKey()); } @Test public void loadWithFilter() throws Exception { jedis.sadd("books", "eXtreme Programming", "Haskell for Dummies"); jedis.set("status", "online"); jedis.lpush("todos", "coffee", "code", "drink", "sleep"); jedis.zadd("reviews", 12.0d, "writing"); jedis.zadd("reviews", 14.0d, "reading"); jedis.zadd("reviews", 15.0d, "maths"); RedisClient redisClient = new RedisClient(); ServerConfiguration serverConfiguration = new ServerConfiguration(); serverConfiguration.setDatabaseVendor(DatabaseVendor.REDIS); serverConfiguration.setServerUrl("localhost:6379"); RedisQuery query = new RedisQuery("reviews"); RedisResult result = redisClient.loadRecords(serverConfiguration, new RedisDatabase("1"), query); List redisRecords = result.getResults(); assertEquals(1, redisRecords.size()); RedisRecord redisRecord = redisRecords.get(0); assertEquals(RedisKeyType.ZSET, redisRecord.getKeyType()); assertEquals("reviews", redisRecord.getKey()); } @Before public void setUp() throws Exception { jedis = new Jedis("localhost", 6379); jedis.select(1); jedis.flushDB(); } public void tearDown() throws Exception { jedis.close(); } } ================================================ FILE: src/test/java/org/codinjutsu/tools/nosql/redis/view/RedisPanelTest.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.redis.view; import com.intellij.openapi.command.impl.DummyProject; import com.intellij.openapi.project.Project; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.codinjutsu.tools.nosql.commons.view.TableCellReader; import org.codinjutsu.tools.nosql.redis.model.RedisQuery; import org.codinjutsu.tools.nosql.redis.logic.RedisClient; import org.codinjutsu.tools.nosql.redis.model.RedisDatabase; import org.codinjutsu.tools.nosql.redis.model.RedisResult; import org.fest.swing.edt.GuiActionRunner; import org.fest.swing.edt.GuiQuery; import org.fest.swing.fixture.Containers; import org.fest.swing.fixture.FrameFixture; import org.fest.swing.fixture.JTableFixture; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import redis.clients.jedis.Tuple; import java.util.*; import static org.mockito.Matchers.any; import static org.mockito.Mockito.when; public class RedisPanelTest { private RedisPanel redisPanelWrapper; private FrameFixture frameFixture; private Project dummyProject = DummyProject.getInstance(); private RedisClient redisClientMock = Mockito.mock(RedisClient.class); @After public void tearDown() { frameFixture.cleanUp(); } @Before public void setUp() throws Exception { when(redisClientMock.loadRecords(any(ServerConfiguration.class), any(RedisDatabase.class), any(RedisQuery.class))).thenReturn(new RedisResult()); redisPanelWrapper = GuiActionRunner.execute(new GuiQuery() { protected RedisPanel executeInEDT() { return new RedisPanel(dummyProject, redisClientMock, new ServerConfiguration(), new RedisDatabase("0")) { @Override protected void addCommonsActions() { } }; } }); frameFixture = Containers.showInFrame(redisPanelWrapper); } @Test public void displayTreeWithEachSupportedKeyType() throws Exception { redisPanelWrapper.updateResultTableTree(createRedisResults(), false, ""); frameFixture.table("resultTreeTable").cellReader(new TableCellReader()) .requireColumnCount(2) .requireContents(new String[][]{ {"foo:bar", "john"}, {"stuff:bar", "[drink, some, beer]"}, {"[0]", "drink"}, {"[1]", "some"}, {"[2]", "beer"}, {"stuff:countries", "{France, Canada, Japan}"}, {"-", "France"}, {"-", "Canada"}, {"-", "Japan"}, {"stuff:aliases", "{david=dada, mickael=mike, bruno=nono}"}, {"david", "dada"}, {"mickael", "mike"}, {"bruno", "nono"}, {"stuff:games:critics", "{(unreal, 8.0), (quake, 9.0), (half-life, 10.0)}"}, {"-", "(unreal, 8.0)"}, {"-", "(quake, 9.0)"}, {"-", "(half-life, 10.0)"}, }); } @Test public void testDisplayTreeWithFragmentedKey() throws Exception { redisPanelWrapper.updateResultTableTree(createRedisResults(), true, ":"); redisPanelWrapper.expandAll(); JTableFixture resultTreeTable = frameFixture.table("resultTreeTable"); resultTreeTable.cellReader(new TableCellReader()) .requireColumnCount(2) .requireContents(new String[][]{ {"foo", ""}, {"bar", "john"}, {"stuff", ""}, {"bar", "[drink, some, beer]"}, {"[0]", "drink"}, {"[1]", "some"}, {"[2]", "beer"}, {"countries", "{France, Canada, Japan}"}, {"-", "France"}, {"-", "Canada"}, {"-", "Japan"}, {"aliases", "{david=dada, mickael=mike, bruno=nono}"}, {"david", "dada"}, {"mickael", "mike"}, {"bruno", "nono"}, {"games", ""}, {"critics", "{(unreal, 8.0), (quake, 9.0), (half-life, 10.0)}"}, {"-", "(unreal, 8.0)"}, {"-", "(quake, 9.0)"}, {"-", "(half-life, 10.0)"}, }); } private RedisResult createRedisResults() { RedisResult redisResult = new RedisResult(); redisResult.addString("foo:bar", "john"); redisResult.addList("stuff:bar", Arrays.asList("drink", "some", "beer")); Set countries = new HashSet<>(); countries.add("France"); countries.add("Japan"); countries.add("Canada"); redisResult.addSet("stuff:countries", countries); Map aliasByPeopleName = new HashMap<>(); aliasByPeopleName.put("david", "dada"); aliasByPeopleName.put("mickael", "mike"); aliasByPeopleName.put("bruno", "nono"); redisResult.addHash("stuff:aliases", aliasByPeopleName); SortedSet scoreByGameTitle = new TreeSet<>(); scoreByGameTitle.add(new Tuple("quake", 9d)); scoreByGameTitle.add(new Tuple("half-life", 10d)); scoreByGameTitle.add(new Tuple("unreal", 8d)); redisResult.addSortedSet("stuff:games:critics", scoreByGameTitle); return redisResult; } } ================================================ FILE: src/test/java/org/codinjutsu/tools/nosql/redis/view/ServerConfigurationPanelTest.java ================================================ /* * Copyright (c) 2015 David Boissier * * 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 org.codinjutsu.tools.nosql.redis.view; import com.intellij.openapi.command.impl.DummyProject; import org.codinjutsu.tools.nosql.DatabaseVendor; import org.codinjutsu.tools.nosql.ServerConfiguration; import org.codinjutsu.tools.nosql.commons.logic.DatabaseClient; import org.codinjutsu.tools.nosql.commons.model.AuthenticationSettings; import org.codinjutsu.tools.nosql.commons.view.ServerConfigurationPanel; import org.codinjutsu.tools.nosql.redis.view.RedisAuthenticationPanel; import org.fest.swing.edt.GuiActionRunner; import org.fest.swing.edt.GuiQuery; import org.fest.swing.fixture.Containers; import org.fest.swing.fixture.FrameFixture; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.mockito.Mockito; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; public class ServerConfigurationPanelTest { @Rule public ExpectedException thrown = ExpectedException.none(); private ServerConfigurationPanel configurationPanel; private DatabaseClient databaseClientMock; private FrameFixture frameFixture; @Before public void setUp() throws Exception { databaseClientMock = Mockito.mock(DatabaseClient.class); configurationPanel = GuiActionRunner.execute(new GuiQuery() { protected ServerConfigurationPanel executeInEDT() { return new ServerConfigurationPanel(DummyProject.getInstance(), DatabaseVendor.REDIS, databaseClientMock, new RedisAuthenticationPanel() ); } }); frameFixture = Containers.showInFrame(configurationPanel); } @After public void tearDown() { frameFixture.cleanUp(); } @Test public void createRedisConfiguration() throws Exception { frameFixture.textBox("labelField").setText("Localhost"); frameFixture.label("databaseVendorLabel").requireText("RedisDB"); frameFixture.label("databaseTipsLabel").requireText("format: host:port. If cluster: host:port1,host:port2,..."); frameFixture.textBox("serverUrlField").setText("localhost:25"); frameFixture.textBox("passwordField").setText("johnpassword"); frameFixture.textBox("userDatabaseField").setText("0"); frameFixture.checkBox("autoConnectField").check(); ServerConfiguration configuration = new ServerConfiguration(); configurationPanel.applyConfigurationData(configuration); assertEquals("Localhost", configuration.getLabel()); assertEquals(DatabaseVendor.REDIS, configuration.getDatabaseVendor()); assertEquals("localhost:25", configuration.getServerUrl()); AuthenticationSettings authenticationSettings = configuration.getAuthenticationSettings(); assertEquals("johnpassword", authenticationSettings.getPassword()); assertEquals("0", configuration.getUserDatabase()); assertTrue(configuration.isConnectOnIdeStartup()); } @Test public void loadRedisConfiguration() throws Exception { ServerConfiguration configuration = new ServerConfiguration(); configuration.setLabel("Localhost"); configuration.setDatabaseVendor(DatabaseVendor.REDIS); configuration.setServerUrl("localhost:6379"); AuthenticationSettings authenticationSettings = new AuthenticationSettings(); authenticationSettings.setPassword("johnpassword"); configuration.setAuthenticationSettings(authenticationSettings); configurationPanel.loadConfigurationData(configuration); frameFixture.textBox("labelField").requireText("Localhost"); frameFixture.label("databaseVendorLabel").requireText("RedisDB"); frameFixture.label("databaseTipsLabel").requireText("format: host:port. If cluster: host:port1,host:port2,..."); frameFixture.textBox("serverUrlField").requireText("localhost:6379"); frameFixture.textBox("passwordField").requireText("johnpassword"); } } ================================================ FILE: src/test/resources/org/codinjutsu/tools/nosql/mongo/logic/dummyCollection.json ================================================ [ { "label":"tata", "comment":"prout", "price":15 }, { "label":"tata", "comment":"prout", "price":10 }, { "label":"tutu", "comment":"prout", "price":15 }, { "label":"titi", "comment":"prout", "price":20 }, { "label":"tete", "comment":"prout", "price":20 } ] ================================================ FILE: src/test/resources/org/codinjutsu/tools/nosql/mongo/view/arrayOfDocuments.json ================================================ [ { "id":0, "label":"toto", "visible":false, "doc":{ "title":"hello", "nbPages":10, "keyWord":[ "toto", true, 10 ] } }, { "id":1, "label":"tata", "visible":true, "doc":{ "title":"ola", "nbPages":1, "keyWord":[ "tutu", false, 10 ] } } ] ================================================ FILE: src/test/resources/org/codinjutsu/tools/nosql/mongo/view/model/arrayOfDocuments.json ================================================ [ { "_id": "50b8d63414f85401b9268b99", "label": "toto", "visible": false, "doc": { "title": "hello", "nbPages": 10, "keyWord": [ "toto", true, 10 ] } }, { "_id": "50b8d63414f85401b9268baa", "label": "tata", "visible": true, "doc": { "title": "ola", "nbPages": 1, "keyWord": [ "tutu", false, 10 ] } } ] ================================================ FILE: src/test/resources/org/codinjutsu/tools/nosql/mongo/view/model/simpleDocument.json ================================================ { "_id": "50b8d63414f85401b9268b99", "label":"toto", "visible":false, "image":null } ================================================ FILE: src/test/resources/org/codinjutsu/tools/nosql/mongo/view/model/simpleDocumentWithInnerNodes.json ================================================ { "_id": "50b8d63414f85401b9268b99", "label": "toto", "visible": false, "image": null, "innerdoc": { "title" : "What?", "numberOfPages": 52, "soldOut": true } } ================================================ FILE: src/test/resources/org/codinjutsu/tools/nosql/mongo/view/model/simpleDocumentWithSubList.json ================================================ { "_id": { "$oid": "50b8d63414f85401b9268b99" }, "title": "XP by example", "tags": [ "pair programming", "tdd", "agile"], "innerList" : [ [1, 2, 3, 4], [false , true], [ { "tagName": "pouet"}, { "tagName": "paf"} ] ] } ================================================ FILE: src/test/resources/org/codinjutsu/tools/nosql/mongo/view/simpleArray.json ================================================ [ "toto", true, 10, null ] ================================================ FILE: src/test/resources/org/codinjutsu/tools/nosql/mongo/view/simpleDocument.json ================================================ { "_id": "50b8d63414f85401b9268b99", "label":"toto", "visible":false, "image":null } ================================================ FILE: src/test/resources/org/codinjutsu/tools/nosql/mongo/view/simpleDocumentForEdition.json ================================================ { "_id": "50b8d63414f85401b9268b99", "label":"toto", "visible":false, "image":null } ================================================ FILE: src/test/resources/org/codinjutsu/tools/nosql/mongo/view/simpleDocumentWithSubList.json ================================================ { "_id": { "$oid": "50b8d63414f85401b9268b99" }, "title": "XP by example", "tags": [ "pair programming", "tdd", "agile"], "innerList" : [ [1, 2, 3, 4], [false , true], [ { "tagName": "pouet"}, { "tagName": "paf"} ] ] } ================================================ FILE: src/test/resources/org/codinjutsu/tools/nosql/mongo/view/structuredDocument.json ================================================ { "id":0, "label":"toto", "visible":false, "doc":{ "title":"hello", "nbPages":10, "keyWord":[ "toto", true, 10 ] } }