[
  {
    "path": ".gitignore",
    "content": "*.iml\n*.ipr\n*.iws\ntarget/\n"
  },
  {
    "path": "CHANGELOG.txt",
    "content": "0.1.0 - Initial version\n  * RedisDB: view database content with filter (KEYS instruction is temporary used) and group with separator pattern\n  * Couchbase: view bucket content with row limit options\n  * MongoDB: all features from the mongo4idea-0.7.3 ;)\n"
  },
  {
    "path": "LICENSE.txt",
    "content": "Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"{}\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright {yyyy} {name of copyright owner}\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "README.md",
    "content": "# NoSql Plugin for IntelliJ IDEA version 0.1.0-SNAPSHOT\n\n## Description\nThis 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.\n\n## Current status: EAP\n\n* [Download the current SNAPSHOT for Idea 14](https://github.com/dboissier/nosql4idea/raw/master/snapshot/nosql4idea-0.1.0-SNAPSHOT-distribution.zip)\n* [Download the current SNAPSHOT for Idea 15](https://github.com/dboissier/nosql4idea/raw/master/snapshot/nosql4idea-0.1.0-SNAPSHOT-Idea15-distribution.zip)\n\n## Plugin Compatibility\n\nThis plugin is built with JDK 1.7 and idea 14.1 version.\n\nThe plugin has been tested with the following databases:\n* MongoDB 2.7 and 3.0\n* Redis 2.8.21\n* Couchbase Community 4.0.0\n\n## Installation \n \nTo install it : `Settings > Plugins > Install plugin from Disk`\n\n## Configuration\n\nOn the right, you will see a new tool window named NoSql Explorer\n\n![NoSqlBrowser](https://github.com/dboissier/nosql4idea/raw/master/doc/explorer.png)\n\n* Click on the Wrench Icon from the toolbar and you will be redirected to the Plugin Settings.\n* You can specify the mongo and redis CLI paths at the top of the panel\n* To add a server, click on the **\\[+\\]** button and choose you database vendor\n\n![SettingsAddAServer](https://github.com/dboissier/nosql4idea/raw/master/doc/settings_add_a_server.png)\n\n* Click on the **OK** button and enter the settings of your database\n\n![MongoSettings](https://github.com/dboissier/nosql4idea/raw/master/doc/mongo_settings.png)\n\n* When all your dabatase are configured you should see then in the explorer panel\n \n![NoSqlBrowserWithServers](https://github.com/dboissier/nosql4idea/raw/master/doc/explorer_with_servers.png)\n\n## Viewing the Redis database content\n\nDouble click on the database icon from your redis server and the results will appear as a tab\n\n![RedisResults](https://github.com/dboissier/nosql4idea/raw/master/doc/redis_results.png)\n\nYou can filter the results (Currently, it runs a `KEYS <filter>` command. A `SCAN <filter>` will replace it in the future for optimization purpose.)\n\nLike 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\n\n![RedisResultsGroupedByPrefix](https://github.com/dboissier/nosql4idea/raw/master/doc/redis_group_by_prefix.png)\n\n## Viewing the Couchbase database content\n \nDouble click on the database icon from your couchbase server and the results will appear as a tab\n\n![CouchbaseResults](https://github.com/dboissier/nosql4idea/raw/master/doc/couchbase_results.png)\n\n**Important note**\nTo get the results from each bucket, an **Index** must be created. Otherwise an error message is raised.\n\n## Roadmap\n\n### 0.1.0\n\n* integrate Redis : view results with 'Group by prefix' feature like **properties editor**\n* integrate Couchbase : view results \n\n### 0.2.0\n\n* delete, update and add features for Redis and Couchbase\n\n\n"
  },
  {
    "path": "fetchIdea.sh",
    "content": "#!/usr/bin/env bash\n# original file from https://github.com/go-lang-plugin-org/go-lang-idea-plugin\n# thanks zolotov :)\n\nideaVersion='14.1.5'\nideaVersionForMaven='14.1'\n#ideaVersion='15.0'\n#ideaVersionForMaven='15.0'\n\nrm -rf ./idea-IC\n\n# Get our IDEA dependency\nwget http://download.jetbrains.com/idea/ideaIC-${ideaVersion}.tar.gz\n\n# Unzip IDEA\ntar -xzf ideaIC-${ideaVersion}.tar.gz\nrm -rf ideaIC-${ideaVersion}.tar.gz\n\n# Move the versioned IDEA folder to a known location\nideaPath=$(find . -name 'idea-IC*' | head -n 1)\necho 'Found Intellij path:' + ${ideaPath}\nmv ${ideaPath} ./idea-IC\ncd ./idea-IC\n\n# install IDEA dependencies\nIDEA_HOME=$(pwd)\nlibs=( 'forms_rt' 'openapi' 'util' 'idea' 'resources' 'resources_en' 'swingx-core-1.6.2' 'annotations' 'extensions' 'jna' 'jdom' 'icons')\nfor lib in \"${libs[@]}\"\ndo\n    mvn install:install-file -Dfile=${IDEA_HOME}/lib/${lib}.jar -DgroupId=com.intellij -DartifactId=${lib} -Dversion=${ideaVersionForMaven} -Dpackaging=jar\ndone\n"
  },
  {
    "path": "nosql4idea.iml.template",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<module type=\"PLUGIN_MODULE\" version=\"4\">\r\n  <component name=\"DevKit.ModuleBuildProperties\" url=\"file://$MODULE_DIR$/src/main/resources/META-INF/plugin.xml\" />\r\n  <component name=\"NewModuleRootManager\" inherit-compiler-output=\"true\">\r\n    <exclude-output />\r\n    <content url=\"file://$MODULE_DIR$\">\r\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/java\" isTestSource=\"false\" />\r\n      <sourceFolder url=\"file://$MODULE_DIR$/src/test/java\" isTestSource=\"true\" />\r\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/resources\" type=\"java-resource\" />\r\n      <sourceFolder url=\"file://$MODULE_DIR$/src/test/resources\" type=\"java-test-resource\" />\r\n      <excludeFolder url=\"file://$MODULE_DIR$/target\" />\r\n    </content>\r\n    <orderEntry type=\"inheritedJdk\" />\r\n    <orderEntry type=\"sourceFolder\" forTests=\"false\" />\r\n    <orderEntry type=\"module-library\">\r\n      <library>\r\n        <CLASSES>\r\n          <root url=\"jar://$MAVEN_REPOSITORY$/org/mongodb/mongo-java-driver/3.0.4/mongo-java-driver-3.0.4.jar!/\" />\r\n        </CLASSES>\r\n        <JAVADOC />\r\n        <SOURCES />\r\n      </library>\r\n    </orderEntry>\r\n    <orderEntry type=\"module-library\">\r\n      <library>\r\n        <CLASSES>\r\n          <root url=\"jar://$MAVEN_REPOSITORY$/redis/clients/jedis/2.7.3/jedis-2.7.3.jar!/\" />\r\n        </CLASSES>\r\n        <JAVADOC />\r\n        <SOURCES />\r\n      </library>\r\n    </orderEntry>\r\n    <orderEntry type=\"module-library\">\r\n      <library>\r\n        <CLASSES>\r\n          <root url=\"jar://$MAVEN_REPOSITORY$/com/couchbase/client/java-client/2.2.1/java-client-2.2.1.jar!/\" />\r\n        </CLASSES>\r\n        <JAVADOC />\r\n        <SOURCES />\r\n      </library>\r\n    </orderEntry>\r\n    <orderEntry type=\"module-library\">\r\n      <library>\r\n        <CLASSES>\r\n          <root url=\"jar://$MAVEN_REPOSITORY$/com/couchbase/client/core-io/1.2.1/core-io-1.2.1.jar!/\" />\r\n        </CLASSES>\r\n        <JAVADOC />\r\n        <SOURCES />\r\n      </library>\r\n    </orderEntry>\r\n    <orderEntry type=\"module-library\">\r\n      <library>\r\n        <CLASSES>\r\n          <root url=\"jar://$MAVEN_REPOSITORY$/io/reactivex/rxjava/1.0.14/rxjava-1.0.14.jar!/\" />\r\n        </CLASSES>\r\n        <JAVADOC />\r\n        <SOURCES />\r\n      </library>\r\n    </orderEntry>\r\n    <orderEntry type=\"module-library\">\r\n      <library>\r\n        <CLASSES>\r\n          <root url=\"jar://$MAVEN_REPOSITORY$/commons-lang/commons-lang/2.4/commons-lang-2.4.jar!/\" />\r\n        </CLASSES>\r\n        <JAVADOC />\r\n        <SOURCES />\r\n      </library>\r\n    </orderEntry>\r\n    <orderEntry type=\"module-library\" scope=\"TEST\">\r\n      <library>\r\n        <CLASSES>\r\n          <root url=\"jar://$MAVEN_REPOSITORY$/commons-io/commons-io/1.4/commons-io-1.4.jar!/\" />\r\n        </CLASSES>\r\n        <JAVADOC />\r\n        <SOURCES />\r\n      </library>\r\n    </orderEntry>\r\n    <orderEntry type=\"module-library\" scope=\"TEST\">\r\n      <library>\r\n        <CLASSES>\r\n          <root url=\"jar://$MAVEN_REPOSITORY$/org/mockito/mockito-all/1.8.5/mockito-all-1.8.5.jar!/\" />\r\n        </CLASSES>\r\n        <JAVADOC />\r\n        <SOURCES />\r\n      </library>\r\n    </orderEntry>\r\n    <orderEntry type=\"module-library\" scope=\"TEST\">\r\n      <library>\r\n        <CLASSES>\r\n          <root url=\"jar://$MAVEN_REPOSITORY$/junit/junit/4.10/junit-4.10.jar!/\" />\r\n        </CLASSES>\r\n        <JAVADOC />\r\n        <SOURCES />\r\n      </library>\r\n    </orderEntry>\r\n    <orderEntry type=\"module-library\" scope=\"TEST\">\r\n      <library>\r\n        <CLASSES>\r\n          <root url=\"jar://$MAVEN_REPOSITORY$/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar!/\" />\r\n        </CLASSES>\r\n        <JAVADOC />\r\n        <SOURCES />\r\n      </library>\r\n    </orderEntry>\r\n    <orderEntry type=\"module-library\" scope=\"TEST\">\r\n      <library>\r\n        <CLASSES>\r\n          <root url=\"jar://$MAVEN_REPOSITORY$/org/easytesting/fest-swing/1.2/fest-swing-1.2.jar!/\" />\r\n        </CLASSES>\r\n        <JAVADOC />\r\n        <SOURCES />\r\n      </library>\r\n    </orderEntry>\r\n    <orderEntry type=\"module-library\" scope=\"TEST\">\r\n      <library>\r\n        <CLASSES>\r\n          <root url=\"jar://$MAVEN_REPOSITORY$/org/easytesting/fest-assert/1.2/fest-assert-1.2.jar!/\" />\r\n        </CLASSES>\r\n        <JAVADOC />\r\n        <SOURCES />\r\n      </library>\r\n    </orderEntry>\r\n    <orderEntry type=\"module-library\" scope=\"TEST\">\r\n      <library>\r\n        <CLASSES>\r\n          <root url=\"jar://$MAVEN_REPOSITORY$/org/easytesting/fest-util/1.1.3/fest-util-1.1.3.jar!/\" />\r\n        </CLASSES>\r\n        <JAVADOC />\r\n        <SOURCES />\r\n      </library>\r\n    </orderEntry>\r\n    <orderEntry type=\"module-library\" scope=\"TEST\">\r\n      <library>\r\n        <CLASSES>\r\n          <root url=\"jar://$MAVEN_REPOSITORY$/org/easytesting/fest-reflect/1.2/fest-reflect-1.2.jar!/\" />\r\n        </CLASSES>\r\n        <JAVADOC />\r\n        <SOURCES />\r\n      </library>\r\n    </orderEntry>\r\n  </component>\r\n</module>"
  },
  {
    "path": "pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <groupId>org.codinjutsu.tools.nosql</groupId>\n    <artifactId>nosql4idea</artifactId>\n    <version>0.1.0-SNAPSHOT</version>\n\n    <properties>\n        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n\n        <maven.compiler.source>1.7</maven.compiler.source>\n        <maven.compiler.target>1.7</maven.compiler.target>\n\n        <intellij.sdk.name>141.2735.5</intellij.sdk.name>\n        <intellij.sdk.version>14.1</intellij.sdk.version>\n        <!--<intellij.sdk.name>143.381.42</intellij.sdk.name>-->\n        <!--<intellij.sdk.version>15.0</intellij.sdk.version>-->\n        <intellij.lib.path>${env.IDEA_HOME}/lib</intellij.lib.path>\n    </properties>\n\n    <packaging>jar</packaging>\n\n    <!--\n      | Project Information\n    -->\n    <name>NoSQL Idea Plugin</name>\n    <description>NoSQL databases integration for Intellij</description>\n    <inceptionYear>2015</inceptionYear>\n\n    <developers>\n        <developer>\n            <name>David Boissier</name>\n            <email>david [dot] boissier [at] gmail [dot] com</email>\n            <organization>Codinjutsu</organization>\n            <timezone>+1</timezone>\n        </developer>\n    </developers>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.mongodb</groupId>\n            <artifactId>mongo-java-driver</artifactId>\n            <version>3.0.4</version>\n        </dependency>\n        <dependency>\n            <groupId>org.slf4j</groupId>\n            <artifactId>slf4j-nop</artifactId>\n            <version>1.7.12</version>\n        </dependency>\n        <dependency>\n            <groupId>redis.clients</groupId>\n            <artifactId>jedis</artifactId>\n            <version>2.7.3</version>\n        </dependency>\n        <dependency>\n            <groupId>com.couchbase.client</groupId>\n            <artifactId>java-client</artifactId>\n            <version>2.2.1</version>\n        </dependency>\n        <dependency>\n            <groupId>commons-lang</groupId>\n            <artifactId>commons-lang</artifactId>\n            <version>2.4</version>\n        </dependency>\n        <dependency>\n            <groupId>log4j</groupId>\n            <artifactId>log4j</artifactId>\n            <version>1.2.14</version>\n        </dependency>\n\n        <dependency>\n            <groupId>com.intellij</groupId>\n            <artifactId>forms_rt</artifactId>\n            <version>${intellij.sdk.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>com.intellij</groupId>\n            <artifactId>openapi</artifactId>\n            <version>${intellij.sdk.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>com.intellij</groupId>\n            <artifactId>util</artifactId>\n            <version>${intellij.sdk.version}</version>\n        </dependency>\n\n        <!-- Test dependencies -->\n        <dependency>\n            <groupId>junit</groupId>\n            <artifactId>junit</artifactId>\n            <version>4.10</version>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.mockito</groupId>\n            <artifactId>mockito-all</artifactId>\n            <version>1.8.5</version>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.easytesting</groupId>\n            <artifactId>fest-swing</artifactId>\n            <version>1.2</version>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.easytesting</groupId>\n            <artifactId>fest-util</artifactId>\n            <version>1.1.3</version>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>commons-io</groupId>\n            <artifactId>commons-io</artifactId>\n            <version>1.4</version>\n            <scope>test</scope>\n        </dependency>\n        \n        <!-- IntelliJ SDK dependencies -->\n        <dependency>\n            <groupId>com.intellij</groupId>\n            <artifactId>idea</artifactId>\n            <scope>system</scope>\n            <systemPath>${intellij.lib.path}/idea.jar</systemPath>\n            <version>${intellij.sdk.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>com.intellij</groupId>\n            <artifactId>extensions</artifactId>\n            <scope>system</scope>\n            <systemPath>${intellij.lib.path}/extensions.jar</systemPath>\n            <version>${intellij.sdk.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>com.intellij</groupId>\n            <artifactId>icons</artifactId>\n            <scope>system</scope>\n            <systemPath>${intellij.lib.path}/icons.jar</systemPath>\n            <version>${intellij.sdk.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>com.intellij</groupId>\n            <artifactId>trove4j</artifactId>\n            <scope>system</scope>\n            <systemPath>${intellij.lib.path}/trove4j.jar</systemPath>\n            <version>${intellij.sdk.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>com.intellij</groupId>\n            <artifactId>annotations</artifactId>\n            <scope>system</scope>\n            <systemPath>${intellij.lib.path}/annotations.jar</systemPath>\n            <version>${intellij.sdk.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>com.intellij</groupId>\n            <artifactId>jdom</artifactId>\n            <scope>system</scope>\n            <systemPath>${intellij.lib.path}/jdom.jar</systemPath>\n            <version>${intellij.sdk.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>com.intellij</groupId>\n            <artifactId>swingx-core</artifactId>\n            <scope>system</scope>\n            <systemPath>${intellij.lib.path}/swingx-core-1.6.2.jar</systemPath>\n            <version>${intellij.sdk.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>com.intellij</groupId>\n            <artifactId>jna</artifactId>\n            <scope>system</scope>\n            <systemPath>${intellij.lib.path}/jna.jar</systemPath>\n            <version>${intellij.sdk.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>com.intellij</groupId>\n            <artifactId>resources</artifactId>\n            <scope>system</scope>\n            <systemPath>${intellij.lib.path}/resources.jar</systemPath>\n            <version>${intellij.sdk.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>com.intellij</groupId>\n            <artifactId>resources_en</artifactId>\n            <scope>system</scope>\n            <systemPath>${intellij.lib.path}/resources_en.jar</systemPath>\n            <version>${intellij.sdk.version}</version>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.codehaus.mojo</groupId>\n                <artifactId>ideauidesigner-maven-plugin</artifactId>\n                <version>1.0-beta-1</version>\n                <executions>\n                    <execution>\n                        <phase>compile</phase>\n                        <goals>\n                            <goal>javac2</goal>\n                        </goals>\n                    </execution>\n                </executions>\n                <configuration>\n                    <fork>true</fork>\n                    <debug>false</debug>\n                    <verbose>true</verbose>\n                    <failOnError>true</failOnError>\n                </configuration>\n            </plugin>\n            <plugin>\n                <artifactId>maven-assembly-plugin</artifactId>\n                <version>2.2.1</version>\n                <executions>\n                    <execution>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>assembly</goal>\n                        </goals>\n                    </execution>\n                </executions>\n                <configuration>\n                    <finalName>${project.artifactId}-${project.version}</finalName>\n                    <descriptors>\n                        <descriptor>src/main/resources/assemblies/plugin-assembly.xml</descriptor>\n                    </descriptors>\n                </configuration>\n            </plugin>\n        </plugins>\n        <resources>\n            <resource>\n                <directory>src/main/resources</directory>\n            </resource>\n        </resources>\n        <testResources>\n            <testResource>\n                <directory>src/test/resources</directory>\n            </testResource>\n        </testResources>\n    </build>\n\n    <!--\n      { License Information\n    -->\n    <licenses>\n        <license>\n            <name>The Apache Software License, Version 2.0</name>\n            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>\n        </license>\n    </licenses>\n\n    <!--\n      | SCM Information\n    -->\n\n    <scm>\n        <connection>scm:git:ssh://git@github.com/dboissier/nosql4idea.git</connection>\n        <url>git:ssh://git@github.com/dboissier/nosql4idea.git</url>\n    </scm>\n</project>\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/ConfigurationDialog.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql;\n\nimport com.intellij.openapi.ui.DialogWrapper;\nimport com.intellij.openapi.ui.ValidationInfo;\nimport org.codinjutsu.tools.nosql.commons.view.ServerConfigurationPanel;\nimport org.codinjutsu.tools.nosql.commons.view.ServerConfigurationPanelFactory;\nimport org.jetbrains.annotations.Nullable;\n\nimport javax.swing.*;\nimport java.awt.*;\n\nclass ConfigurationDialog extends DialogWrapper {\n\n    private final ServerConfigurationPanelFactory serverConfigurationPanelFactory;\n    private final ServerConfiguration configuration;\n    private ServerConfigurationPanel serverConfigurationPanel;\n\n    ConfigurationDialog(Component parent,\n                        ServerConfigurationPanelFactory serverConfigurationPanelFactory,\n                        ServerConfiguration configuration) {\n        super(parent, true);\n        this.serverConfigurationPanelFactory = serverConfigurationPanelFactory;\n        this.configuration = configuration;\n\n        init();\n    }\n\n    @Nullable\n    @Override\n    protected JComponent createCenterPanel() {\n        serverConfigurationPanel = this.serverConfigurationPanelFactory.create(configuration.getDatabaseVendor());\n        serverConfigurationPanel.loadConfigurationData(configuration);\n        return serverConfigurationPanel;\n    }\n\n    @Nullable\n    @Override\n    protected ValidationInfo doValidate() {\n        return serverConfigurationPanel.validateInputs();\n    }\n\n    @Override\n    protected void doOKAction() {\n        super.doOKAction();\n        serverConfigurationPanel.applyConfigurationData(configuration);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/DatabaseVendor.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql;\n\nimport org.codinjutsu.tools.nosql.commons.utils.GuiUtils;\n\nimport javax.swing.*;\n\npublic enum DatabaseVendor {\n\n    MONGO(\"MongoDB\", \"mongodb.png\", \"localhost:27017\", \"format: host:port. If replicat set: host:port1,host:port2,...\"),\n    REDIS(\"RedisDB\", \"redis.png\", \"localhost:6379\", \"format: host:port. If cluster: host:port1,host:port2,...\"),\n    COUCHBASE(\"Couchbase\", \"couchbase.png\", \"localhost\", \"format: host:port. If cluster: host:port1,host:port2,...\");\n\n    public final String name;\n    public final Icon icon;\n    public final String defaultUrl;\n    public final String tips;\n\n    DatabaseVendor(String name, String iconFilename, String defaultUrl, String tips) {\n        this.name = name;\n        this.icon = GuiUtils.loadIcon(iconFilename);\n        this.defaultUrl = defaultUrl;\n        this.tips = tips;\n    }\n\n    @Override\n    public String toString() {\n        return \"DatabaseVendor{name='\" + name + \"'}\";\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/DatabaseVendorClientManager.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql;\n\nimport com.intellij.openapi.components.ServiceManager;\nimport com.intellij.openapi.project.Project;\nimport org.codinjutsu.tools.nosql.commons.logic.DatabaseClient;\nimport org.codinjutsu.tools.nosql.commons.model.DatabaseServer;\nimport org.codinjutsu.tools.nosql.couchbase.logic.CouchbaseClient;\nimport org.codinjutsu.tools.nosql.mongo.logic.MongoClient;\nimport org.codinjutsu.tools.nosql.redis.logic.RedisClient;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class DatabaseVendorClientManager {\n\n    private static final Map<DatabaseVendor, Class<? extends DatabaseClient>> dataClientByVendor = new HashMap<>();\n\n    static {\n        dataClientByVendor.put(DatabaseVendor.MONGO, MongoClient.class);\n        dataClientByVendor.put(DatabaseVendor.REDIS, RedisClient.class);\n        dataClientByVendor.put(DatabaseVendor.COUCHBASE, CouchbaseClient.class);\n    }\n\n    private final Project project;\n\n    public DatabaseVendorClientManager(Project project) {\n        this.project = project;\n    }\n\n    public static DatabaseVendorClientManager getInstance(Project project) {\n        return ServiceManager.getService(project, DatabaseVendorClientManager.class);\n    }\n\n    public DatabaseClient get(DatabaseVendor databaseVendor) {\n        return ServiceManager.getService(project, dataClientByVendor.get(databaseVendor));\n    }\n\n    public void cleanUpServers() {\n        for (DatabaseVendor databaseVendor : dataClientByVendor.keySet()) {\n            this.get(databaseVendor).cleanUpServers();\n        }\n    }\n\n    public void registerServer(DatabaseServer databaseServer) {\n        this.get(databaseServer.getConfiguration().getDatabaseVendor()).registerServer(databaseServer);\n    }\n\n    public void loadServer(DatabaseServer databaseServer) {\n        this.get(databaseServer.getConfiguration().getDatabaseVendor()).loadServer(databaseServer);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/DatabaseVendorUIManager.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql;\n\nimport com.intellij.openapi.components.ServiceManager;\nimport com.intellij.openapi.project.Project;\nimport com.intellij.openapi.vfs.VirtualFile;\nimport org.codinjutsu.tools.nosql.commons.DatabaseUI;\nimport org.codinjutsu.tools.nosql.couchbase.CouchbaseUI;\nimport org.codinjutsu.tools.nosql.couchbase.view.editor.CouchbaseObjectFile;\nimport org.codinjutsu.tools.nosql.mongo.MongoUI;\nimport org.codinjutsu.tools.nosql.mongo.view.editor.MongoObjectFile;\nimport org.codinjutsu.tools.nosql.redis.RedisUI;\nimport org.codinjutsu.tools.nosql.redis.view.editor.RedisObjectFile;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class DatabaseVendorUIManager {\n\n    private static final Map<DatabaseVendor, Class<? extends DatabaseUI>> databaseUIByVendor = new HashMap<>();\n\n    static {\n        databaseUIByVendor.put(DatabaseVendor.MONGO, MongoUI.class);\n        databaseUIByVendor.put(DatabaseVendor.REDIS, RedisUI.class);\n        databaseUIByVendor.put(DatabaseVendor.COUCHBASE, CouchbaseUI.class);\n    }\n\n    private final Project project;\n\n    public DatabaseVendorUIManager(Project project) {\n        this.project = project;\n    }\n\n    public static DatabaseVendorUIManager getInstance(Project project) {\n        return ServiceManager.getService(project, DatabaseVendorUIManager.class);\n    }\n\n    public DatabaseUI get(DatabaseVendor databaseVendor) {\n        return ServiceManager.getService(project, databaseUIByVendor.get(databaseVendor));\n    }\n\n    public boolean accept(VirtualFile file) {\n        return file instanceof MongoObjectFile || file instanceof RedisObjectFile || file instanceof CouchbaseObjectFile;\n\n    }\n}"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/NoSqlComponent.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql;\n\nimport com.intellij.openapi.components.AbstractProjectComponent;\nimport com.intellij.openapi.project.Project;\nimport org.jetbrains.annotations.NotNull;\n\n\npublic class NoSqlComponent extends AbstractProjectComponent {\n\n    private static final String COMPONENT_NAME = \"NoSql\";\n\n    public NoSqlComponent(Project project) {\n        super(project);\n\n    }\n\n    @NotNull\n    public String getComponentName() {\n        return COMPONENT_NAME;\n    }\n\n\n    public void projectOpened() {\n        NoSqlWindowManager.getInstance(myProject);\n    }\n\n    public void projectClosed() {\n        NoSqlWindowManager.getInstance(myProject).unregisterMyself();\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/NoSqlConfigurable.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql;\n\nimport com.intellij.execution.ExecutionException;\nimport com.intellij.execution.configurations.GeneralCommandLine;\nimport com.intellij.execution.process.CapturingProcessHandler;\nimport com.intellij.execution.process.ProcessOutput;\nimport com.intellij.openapi.Disposable;\nimport com.intellij.openapi.fileChooser.FileChooserDescriptor;\nimport com.intellij.openapi.options.BaseConfigurable;\nimport com.intellij.openapi.options.ConfigurationException;\nimport com.intellij.openapi.progress.ProcessCanceledException;\nimport com.intellij.openapi.progress.ProgressIndicator;\nimport com.intellij.openapi.progress.ProgressManager;\nimport com.intellij.openapi.project.Project;\nimport com.intellij.openapi.ui.LabeledComponent;\nimport com.intellij.openapi.ui.Messages;\nimport com.intellij.openapi.ui.TextFieldWithBrowseButton;\nimport com.intellij.openapi.util.ThrowableComputable;\nimport com.intellij.openapi.vfs.CharsetToolkit;\nimport com.intellij.ui.*;\nimport com.intellij.ui.table.JBTable;\nimport org.apache.commons.lang.StringUtils;\nimport org.codinjutsu.tools.nosql.commons.view.ServerConfigurationPanelFactory;\nimport org.jetbrains.annotations.Nls;\nimport org.jetbrains.annotations.Nullable;\n\nimport javax.swing.*;\nimport javax.swing.table.TableCellEditor;\nimport javax.swing.table.TableColumn;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.concurrent.TimeoutException;\n\nimport static org.apache.commons.lang.StringUtils.isBlank;\n\npublic class NoSqlConfigurable extends BaseConfigurable {\n\n\n    private final Project project;\n\n    private final NoSqlConfiguration configuration;\n\n    private final List<ServerConfiguration> configurations;\n    private final ServerConfigurationPanelFactory serverConfigurationPanelFactory;\n    private final DatabaseVendorClientManager databaseVendorClientManager;\n\n    private JPanel mainPanel;\n    private JBTable table;\n    private final NoSqlServerTableModel tableModel;\n    private ShellPathPanel mongoShellPanel;\n    private ShellPathPanel redisShellPanel;\n\n\n    public NoSqlConfigurable(Project project) {\n        this.project = project;\n        this.configuration = NoSqlConfiguration.getInstance(project);\n        databaseVendorClientManager = DatabaseVendorClientManager.getInstance(project);\n        this.serverConfigurationPanelFactory = new ServerConfigurationPanelFactory(\n                project,\n                databaseVendorClientManager,\n                DatabaseVendorUIManager.getInstance(project)\n        );\n        configurations = new LinkedList<>(this.configuration.getServerConfigurations());\n        tableModel = new NoSqlServerTableModel(configurations);\n        mainPanel = new JPanel(new BorderLayout());\n    }\n\n    @Nls\n    @Override\n    public String getDisplayName() {\n        return \"NoSql Servers\";\n    }\n\n    @Nullable\n    @Override\n    public String getHelpTopic() {\n        return \"preferences.noSqlOptions\";\n    }\n\n    @Nullable\n    @Override\n    public JComponent createComponent() {\n        JPanel databaseVendorShellOptionsPanel = new JPanel();\n        databaseVendorShellOptionsPanel.setLayout(new BoxLayout(databaseVendorShellOptionsPanel, BoxLayout.Y_AXIS));\n        mongoShellPanel = new ShellPathPanel(DatabaseVendor.MONGO, \"--version\");\n        databaseVendorShellOptionsPanel.add(mongoShellPanel);\n        redisShellPanel = new ShellPathPanel(DatabaseVendor.REDIS, \"--version\");\n        databaseVendorShellOptionsPanel.add(redisShellPanel);\n\n        mainPanel.add(databaseVendorShellOptionsPanel, BorderLayout.NORTH);\n\n\n        PanelWithButtons panelWithButtons = new PanelWithButtons() {\n\n            {\n                initPanel();\n            }\n\n            @Nullable\n            @Override\n            protected String getLabelText() {\n                return \"Servers\";\n            }\n\n            @Override\n            protected JButton[] createButtons() {\n                return new JButton[]{};\n            }\n\n            @Override\n            protected JComponent createMainComponent() {\n                table = new JBTable(tableModel);\n                table.getEmptyText().setText(\"No server configuration set\");\n                table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n                table.setDefaultRenderer(DatabaseVendor.class, new ColoredTableCellRenderer() {\n                    @Override\n                    protected void customizeCellRenderer(JTable jTable, Object value, boolean b, boolean b1, int i, int i1) {\n                        DatabaseVendor databaseVendor = (DatabaseVendor) value;\n                        this.setIcon(databaseVendor.icon);\n                        this.append(databaseVendor.name);\n                    }\n                });\n\n                TableColumn autoConnectColumn = table.getColumnModel().getColumn(3);\n                int autoConnectColumnWidth = table.getFontMetrics(table.getFont()).stringWidth(table.getColumnName(3)) + 10;\n                autoConnectColumn.setPreferredWidth(autoConnectColumnWidth);\n                autoConnectColumn.setMaxWidth(autoConnectColumnWidth);\n                autoConnectColumn.setMinWidth(autoConnectColumnWidth);\n\n                return ToolbarDecorator.createDecorator(table)\n                        .setAddAction(new AnActionButtonRunnable() {\n                            @Override\n                            public void run(AnActionButton button) {\n                                stopEditing();\n\n                                SelectDatabaseVendorDialog databaseVendorDialog = new SelectDatabaseVendorDialog(mainPanel);\n                                databaseVendorDialog.setTitle(\"Add a NoSql Server\");\n                                databaseVendorDialog.show();\n                                if (!databaseVendorDialog.isOK()) {\n                                    return;\n                                }\n\n                                DatabaseVendor selectedDatabaseVendor = databaseVendorDialog.getSelectedDatabaseVendor();\n                                ServerConfiguration serverConfiguration = databaseVendorClientManager.get(selectedDatabaseVendor).defaultConfiguration();\n                                serverConfiguration.setDatabaseVendor(selectedDatabaseVendor);\n\n                                ConfigurationDialog dialog = new ConfigurationDialog(\n                                        mainPanel,\n                                        serverConfigurationPanelFactory,\n                                        serverConfiguration\n                                );\n                                dialog.setTitle(\"Add a NoSql Server\");\n                                dialog.show();\n                                if (!dialog.isOK()) {\n                                    return;\n                                }\n\n                                configurations.add(serverConfiguration);\n                                int index = configurations.size() - 1;\n                                tableModel.fireTableRowsInserted(index, index);\n                                table.getSelectionModel().setSelectionInterval(index, index);\n                                table.scrollRectToVisible(table.getCellRect(index, 0, true));\n                            }\n                        })\n                        .setAddActionName(\"addServer\")\n                        .setEditAction(new AnActionButtonRunnable() {\n                            @Override\n                            public void run(AnActionButton button) {\n                                stopEditing();\n\n                                int selectedIndex = table.getSelectedRow();\n                                if (selectedIndex < 0 || selectedIndex >= tableModel.getRowCount()) {\n                                    return;\n                                }\n                                ServerConfiguration sourceConfiguration = configurations.get(selectedIndex);\n                                ServerConfiguration copiedConfiguration = sourceConfiguration.clone();\n\n\n                                ConfigurationDialog dialog = new ConfigurationDialog(\n                                        mainPanel,\n                                        serverConfigurationPanelFactory,\n                                        copiedConfiguration\n                                );\n                                dialog.setTitle(\"Edit a NoSql Server\");\n                                dialog.show();\n                                if (!dialog.isOK()) {\n                                    return;\n                                }\n\n                                configurations.set(selectedIndex, copiedConfiguration);\n                                tableModel.fireTableRowsUpdated(selectedIndex, selectedIndex);\n                                table.getSelectionModel().setSelectionInterval(selectedIndex, selectedIndex);\n                            }\n                        })\n                        .setEditActionName(\"editServer\")\n                        .setRemoveAction(new AnActionButtonRunnable() {\n                            @Override\n                            public void run(AnActionButton button) {\n                                stopEditing();\n\n                                int selectedIndex = table.getSelectedRow();\n                                if (selectedIndex < 0 || selectedIndex >= tableModel.getRowCount()) {\n                                    return;\n                                }\n                                TableUtil.removeSelectedItems(table);\n                            }\n                        })\n                        .setRemoveActionName(\"removeServer\")\n                        .disableUpDownActions().createPanel();\n            }\n        };\n\n        mainPanel.add(panelWithButtons, BorderLayout.CENTER);\n\n        return mainPanel;\n    }\n\n    public boolean isModified() {\n        return areConfigurationsModified() || isRedisShellPathModified();\n    }\n\n    @Override\n    public void apply() throws ConfigurationException {\n        stopEditing();\n        if (areConfigurationsModified()) {\n            configuration.setServerConfigurations(configurations);\n        }\n\n        if (isMongoShellPathModified()) {\n            configuration.setShellPath(DatabaseVendor.MONGO, mongoShellPanel.getShellPath());\n        }\n\n        if (isRedisShellPathModified()) {\n            configuration.setShellPath(DatabaseVendor.REDIS, redisShellPanel.getShellPath());\n        }\n\n        NoSqlWindowManager.getInstance(project).apply();\n    }\n\n    private boolean isMongoShellPathModified() {\n        return mongoShellPanel.isShellPathModified(NoSqlConfiguration.getInstance(project).getShellPath(DatabaseVendor.MONGO));\n    }\n\n    private boolean isRedisShellPathModified() {\n        return redisShellPanel.isShellPathModified(NoSqlConfiguration.getInstance(project).getShellPath(DatabaseVendor.REDIS));\n    }\n\n    private boolean areConfigurationsModified() {\n        List<ServerConfiguration> existingConfigurations = NoSqlConfiguration.getInstance(project).getServerConfigurations();\n\n        if (configurations.size() != existingConfigurations.size()) {\n            return true;\n        }\n\n        for (ServerConfiguration existingConfiguration : existingConfigurations) {\n            if (!configurations.contains(existingConfiguration)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    @Override\n    public void reset() {\n    }\n\n    @Override\n    public void disposeUIResources() {\n        mainPanel = null;\n        tableModel.removeTableModelListener(table);\n        mongoShellPanel.dispose();\n        redisShellPanel.dispose();\n        table = null;\n    }\n\n    private void stopEditing() {\n        if (table.isEditing()) {\n            TableCellEditor editor = table.getCellEditor();\n            if (editor != null) {\n                editor.stopCellEditing();\n            }\n        }\n    }\n\n\n    private class ShellPathPanel extends JPanel implements Disposable {\n\n        private static final int TIMEOUT_MS = 60 * 1000;\n        private final String testParameter;\n        private LabeledComponent<TextFieldWithBrowseButton> shellPathField;\n\n        private ShellPathPanel(DatabaseVendor databaseVendor, String testParameter) {\n            this.testParameter = testParameter;\n            setLayout(new BoxLayout(this, BoxLayout.X_AXIS));\n            add(createLabel(databaseVendor.name));\n            shellPathField = createShellPathField(databaseVendor);\n            add(shellPathField);\n            add(createTestButton(databaseVendor));\n        }\n\n        private JLabel createLabel(String databaseVendorName) {\n            return new JLabel(String.format(\"Path to %s CLI:\\t\\t\", databaseVendorName));\n        }\n\n        private JButton createTestButton(final DatabaseVendor databaseVendorName) {\n            JButton testButton = new JButton(\"Test\");\n            testButton.addActionListener(new ActionListener() {\n                @Override\n                public void actionPerformed(ActionEvent actionEvent) {\n                    testPath(databaseVendorName);\n                }\n            });\n            return testButton;\n        }\n\n\n        private void testPath(final DatabaseVendor databaseVendor) {\n            ProcessOutput processOutput;\n            try {\n                processOutput = ProgressManager.getInstance().runProcessWithProgressSynchronously(new ThrowableComputable<ProcessOutput, Exception>() {\n                    @Override\n                    public ProcessOutput compute() throws Exception {\n                        return checkShellPath(databaseVendor, getShellPath());\n                    }\n                }, \"Testing \" + databaseVendor.name + \" CLI Executable...\", true, NoSqlConfigurable.this.project);\n            } catch (ProcessCanceledException pce) {\n                return;\n            } catch (Exception e) {\n                Messages.showErrorDialog(mainPanel, e.getMessage(), \"Something wrong happened\");\n                return;\n            }\n            if (processOutput != null && processOutput.getExitCode() == 0) {\n                Messages.showInfoMessage(mainPanel, processOutput.getStdout(), databaseVendor.name + \" CLI Path Checked\");\n            }\n        }\n\n        public ProcessOutput checkShellPath(DatabaseVendor databaseVendor, String shellPath) throws ExecutionException, TimeoutException {\n            if (isBlank(shellPath)) {\n                return null;\n            }\n\n            GeneralCommandLine commandLine = new GeneralCommandLine();\n            commandLine.setExePath(shellPath);\n            if (testParameter != null) {\n                commandLine.addParameter(testParameter);\n            }\n            CapturingProcessHandler handler = new CapturingProcessHandler(commandLine.createProcess(), CharsetToolkit.getDefaultSystemCharset());\n            ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();\n            ProcessOutput result = indicator == null ?\n                    handler.runProcess(TIMEOUT_MS) :\n                    handler.runProcessWithProgressIndicator(indicator);\n            if (result.isTimeout()) {\n                throw new TimeoutException(\"Couldn't check \" + databaseVendor.name + \" CLI executable - stopped by timeout.\");\n            } else if (result.isCancelled()) {\n                throw new ProcessCanceledException();\n            } else if (result.getExitCode() != 0 || !result.getStderr().isEmpty()) {\n                throw new ExecutionException(String.format(\"Errors while executing %s. exitCode=%s errors: %s\",\n                        commandLine.toString(),\n                        result.getExitCode(),\n                        result.getStderr()));\n            }\n            return result;\n        }\n\n\n        public String getShellPath() {\n            String shellPath = shellPathField.getComponent().getText();\n            if (StringUtils.isNotBlank(shellPath)) {\n                return shellPath;\n            }\n\n            return null;\n        }\n\n        public boolean isShellPathModified(String shellPath) {\n            return !StringUtils.equals(shellPath, getShellPath());\n        }\n\n        private LabeledComponent<TextFieldWithBrowseButton> createShellPathField(DatabaseVendor databaseVendor) {\n            LabeledComponent<TextFieldWithBrowseButton> shellPathField = new LabeledComponent<>();\n            TextFieldWithBrowseButton component = new TextFieldWithBrowseButton();\n            component.getChildComponent().setName(\"shellPathField\");\n            shellPathField.setComponent(component);\n            shellPathField.getComponent().addBrowseFolderListener(String.format(\"%s CLI configuration\", databaseVendor.name), \"\", null,\n                    new FileChooserDescriptor(true, false, false, false, false, false));\n\n            shellPathField.getComponent().setText(configuration.getShellPath(databaseVendor));\n\n            return shellPathField;\n        }\n\n        @Override\n        public void dispose() {\n            shellPathField = null;\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/NoSqlConfiguration.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql;\n\nimport com.intellij.openapi.components.*;\nimport com.intellij.openapi.project.Project;\nimport com.intellij.util.xmlb.XmlSerializerUtil;\n\nimport java.util.HashMap;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Map;\n\n@SuppressWarnings(\"unused\")\n@State(\n        name = \"NoSqlConfiguration\",\n        storages = {\n                @Storage(file = \"$PROJECT_FILE$\"),\n                @Storage(file = \"$PROJECT_CONFIG_DIR$/noSqlSettings.xml\", scheme = StorageScheme.DIRECTORY_BASED)\n        }\n)\npublic class NoSqlConfiguration implements PersistentStateComponent<NoSqlConfiguration> {\n\n    private List<ServerConfiguration> serverConfigurations = new LinkedList<ServerConfiguration>();\n    private Map<DatabaseVendor, String> shellPathByDatabaseVendor = new HashMap<DatabaseVendor, String>();\n\n    public static NoSqlConfiguration getInstance(Project project) {\n        return ServiceManager.getService(project, NoSqlConfiguration.class);\n    }\n\n\n    public NoSqlConfiguration getState() {\n        return this;\n    }\n\n    public void loadState(NoSqlConfiguration noSqlConfiguration) {\n        XmlSerializerUtil.copyBean(noSqlConfiguration, this);\n    }\n\n    public void setServerConfigurations(List<ServerConfiguration> serverConfigurations) {\n        this.serverConfigurations = serverConfigurations;\n    }\n\n    public List<ServerConfiguration> getServerConfigurations() {\n        return serverConfigurations;\n    }\n\n    public String getShellPath(DatabaseVendor databaseVendor) {\n        return shellPathByDatabaseVendor.get(databaseVendor);\n    }\n\n    public void setShellPathByDatabaseVendor(Map<DatabaseVendor, String> shellPathByDatabaseVendor) {\n        this.shellPathByDatabaseVendor = shellPathByDatabaseVendor;\n    }\n\n    public Map<DatabaseVendor, String> getShellPathByDatabaseVendor() {\n        return shellPathByDatabaseVendor;\n    }\n\n    public void setShellPath(DatabaseVendor databaseVendor, String shellPath) {\n        shellPathByDatabaseVendor.put(databaseVendor, shellPath);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/NoSqlExplorerPanel.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<form xmlns=\"http://www.intellij.com/uidesigner/form/\" version=\"1\" bind-to-class=\"org.codinjutsu.tools.nosql.NoSqlExplorerPanel\">\n  <grid id=\"27dc6\" binding=\"rootPanel\" layout-manager=\"GridLayoutManager\" row-count=\"2\" column-count=\"1\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n    <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n    <constraints>\n      <xy x=\"20\" y=\"20\" width=\"500\" height=\"400\"/>\n    </constraints>\n    <properties/>\n    <border type=\"none\"/>\n    <children>\n      <grid id=\"9cc34\" binding=\"toolBarPanel\" layout-manager=\"GridLayoutManager\" row-count=\"1\" column-count=\"1\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n        <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n        <constraints>\n          <grid row=\"0\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n        <border type=\"none\"/>\n        <children/>\n      </grid>\n      <grid id=\"b900\" binding=\"treePanel\" layout-manager=\"GridLayoutManager\" row-count=\"1\" column-count=\"1\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n        <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n        <constraints>\n          <grid row=\"1\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n        <border type=\"none\"/>\n        <children/>\n      </grid>\n    </children>\n  </grid>\n</form>\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/NoSqlExplorerPanel.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql;\n\nimport com.intellij.ide.CommonActionsManager;\nimport com.intellij.ide.TreeExpander;\nimport com.intellij.openapi.Disposable;\nimport com.intellij.openapi.actionSystem.ActionManager;\nimport com.intellij.openapi.actionSystem.AnAction;\nimport com.intellij.openapi.actionSystem.DefaultActionGroup;\nimport com.intellij.openapi.application.ApplicationManager;\nimport com.intellij.openapi.project.Project;\nimport com.intellij.openapi.ui.MessageType;\nimport com.intellij.openapi.ui.popup.Balloon;\nimport com.intellij.openapi.util.Disposer;\nimport com.intellij.ui.PopupHandler;\nimport com.intellij.ui.components.JBScrollPane;\nimport com.intellij.ui.treeStructure.Tree;\nimport com.intellij.util.ui.tree.TreeUtil;\nimport org.codinjutsu.tools.nosql.commons.logic.ConfigurationException;\nimport org.codinjutsu.tools.nosql.commons.logic.DatabaseClient;\nimport org.codinjutsu.tools.nosql.commons.model.Database;\nimport org.codinjutsu.tools.nosql.commons.model.DatabaseServer;\nimport org.codinjutsu.tools.nosql.commons.utils.GuiUtils;\nimport org.codinjutsu.tools.nosql.commons.view.action.NoSqlDatabaseConsoleAction;\nimport org.codinjutsu.tools.nosql.commons.view.action.OpenPluginSettingsAction;\nimport org.codinjutsu.tools.nosql.commons.view.action.RefreshServerAction;\nimport org.codinjutsu.tools.nosql.commons.view.action.ViewCollectionValuesAction;\nimport org.codinjutsu.tools.nosql.commons.view.editor.NoSqlDatabaseFileSystem;\nimport org.codinjutsu.tools.nosql.commons.view.editor.NoSqlDatabaseObjectFile;\nimport org.codinjutsu.tools.nosql.couchbase.model.CouchbaseDatabase;\nimport org.codinjutsu.tools.nosql.couchbase.view.editor.CouchbaseObjectFile;\nimport org.codinjutsu.tools.nosql.mongo.logic.MongoClient;\nimport org.codinjutsu.tools.nosql.mongo.model.MongoCollection;\nimport org.codinjutsu.tools.nosql.mongo.model.MongoDatabase;\nimport org.codinjutsu.tools.nosql.mongo.view.action.DropCollectionAction;\nimport org.codinjutsu.tools.nosql.mongo.view.action.DropDatabaseAction;\nimport org.codinjutsu.tools.nosql.mongo.view.editor.MongoObjectFile;\nimport org.codinjutsu.tools.nosql.redis.model.RedisDatabase;\nimport org.codinjutsu.tools.nosql.redis.view.editor.RedisObjectFile;\nimport org.jetbrains.annotations.NotNull;\n\nimport javax.swing.*;\nimport javax.swing.tree.DefaultMutableTreeNode;\nimport javax.swing.tree.DefaultTreeModel;\nimport javax.swing.tree.TreeSelectionModel;\nimport java.awt.*;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.net.URL;\nimport java.util.List;\n\nimport static org.codinjutsu.tools.nosql.commons.utils.GuiUtils.showNotification;\n\npublic class NoSqlExplorerPanel extends JPanel implements Disposable {\n\n    private static final URL pluginSettingsUrl = GuiUtils.isUnderDarcula() ? GuiUtils.getIconResource(\"pluginSettings_dark.png\") : GuiUtils.getIconResource(\"pluginSettings.png\");\n\n    private JPanel rootPanel;\n\n    private JPanel treePanel;\n    private Tree databaseTree;\n\n    private JPanel toolBarPanel;\n\n    private final Project project;\n    private final DatabaseVendorClientManager databaseVendorClientManager;\n\n    public NoSqlExplorerPanel(Project project, DatabaseVendorClientManager databaseVendorClientManager) {\n        this.project = project;\n        this.databaseVendorClientManager = databaseVendorClientManager;\n\n        treePanel.setLayout(new BorderLayout());\n\n        databaseTree = createTree();\n        databaseTree.setCellRenderer(new NoSqlTreeRenderer());\n        databaseTree.setName(\"databaseTree\");\n\n        JBScrollPane mongoTreeScrollPane = new JBScrollPane(databaseTree);\n\n        setLayout(new BorderLayout());\n        treePanel.add(mongoTreeScrollPane, BorderLayout.CENTER);\n        add(rootPanel, BorderLayout.CENTER);\n\n        toolBarPanel.setLayout(new BorderLayout());\n\n        ApplicationManager.getApplication().invokeLater(new Runnable() {\n            @Override\n            public void run() {\n                reloadAllServerConfigurations();\n            }\n        });\n    }\n\n    public void reloadAllServerConfigurations() {\n        this.databaseVendorClientManager.cleanUpServers();\n        databaseTree.setRootVisible(false);\n\n        List<ServerConfiguration> serverConfigurations = getServerConfigurations();\n        if (serverConfigurations.size() == 0) {\n            databaseTree.setModel(null);\n            return;\n        }\n\n        final DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode();\n        databaseTree.setModel(new DefaultTreeModel(rootNode));\n\n        for (ServerConfiguration serverConfiguration : serverConfigurations) {\n            DatabaseServer mongoServer = new DatabaseServer(serverConfiguration);\n            this.databaseVendorClientManager.registerServer(mongoServer);\n            DefaultMutableTreeNode serverNode = new DefaultMutableTreeNode(mongoServer);\n            rootNode.add(serverNode);\n            if (serverConfiguration.isConnectOnIdeStartup()) {\n                this.reloadServerConfiguration(serverNode, false);\n            }\n        }\n\n        TreeUtil.expand(databaseTree, 2);\n    }\n\n\n    public void reloadServerConfiguration(final DefaultMutableTreeNode serverNode, final boolean expandAfterLoading) {\n        databaseTree.setPaintBusy(true);\n\n        ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {\n\n            @Override\n            public void run() {\n                final DatabaseServer databaseServer = (DatabaseServer) serverNode.getUserObject();\n                try {\n                    databaseVendorClientManager.loadServer(databaseServer);\n\n                    GuiUtils.runInSwingThread(new Runnable() {\n                        @Override\n                        public void run() {\n                            databaseTree.invalidate();\n\n                            serverNode.removeAllChildren();\n                            addDatabasesIfAny(databaseServer, serverNode);\n\n                            ((DefaultTreeModel) databaseTree.getModel()).reload(serverNode);\n\n                            databaseTree.revalidate();\n\n                            if (expandAfterLoading) {\n                                GuiUtils.expand(databaseTree, TreeUtil.getPathFromRoot(serverNode), 1);\n                            }\n\n                        }\n                    });\n\n                } catch (ConfigurationException confEx) {\n                    databaseServer.setStatus(DatabaseServer.Status.ERROR);\n                    showNotification(treePanel,\n                            MessageType.ERROR,\n                            String.format(\"Error when connecting on %s\", databaseServer.getLabel()),\n                            Balloon.Position.atLeft);\n                } finally {\n                    databaseTree.setPaintBusy(false);\n                }\n            }\n        });\n    }\n\n    private void addDatabasesIfAny(DatabaseServer databaseServer, DefaultMutableTreeNode serverNode) {\n        for (Database database : databaseServer.getDatabases()) {\n            DefaultMutableTreeNode databaseNode = new DefaultMutableTreeNode(database);\n            if (database instanceof MongoDatabase) {\n                MongoDatabase mongoDatabase = (MongoDatabase) database;\n                for (MongoCollection collection : mongoDatabase.getCollections()) {\n                    databaseNode.add(new DefaultMutableTreeNode(collection));\n                }\n            }\n            serverNode.add(databaseNode);\n        }\n    }\n\n    private List<ServerConfiguration> getServerConfigurations() {\n        return NoSqlConfiguration.getInstance(project).getServerConfigurations();\n    }\n\n    public void installActions() {\n\n        final TreeExpander treeExpander = new TreeExpander() {\n            @Override\n            public void expandAll() {\n                NoSqlExplorerPanel.this.expandAll();\n            }\n\n            @Override\n            public boolean canExpand() {\n                return true;\n            }\n\n            @Override\n            public void collapseAll() {\n                NoSqlExplorerPanel.this.collapseAll();\n            }\n\n            @Override\n            public boolean canCollapse() {\n                return true;\n            }\n        };\n\n        CommonActionsManager actionsManager = CommonActionsManager.getInstance();\n\n        final AnAction expandAllAction = actionsManager.createExpandAllAction(treeExpander, rootPanel);\n        final AnAction collapseAllAction = actionsManager.createCollapseAllAction(treeExpander, rootPanel);\n\n        Disposer.register(this, new Disposable() {\n            @Override\n            public void dispose() {\n                collapseAllAction.unregisterCustomShortcutSet(rootPanel);\n                expandAllAction.unregisterCustomShortcutSet(rootPanel);\n            }\n        });\n\n\n        DefaultActionGroup actionGroup = new DefaultActionGroup(\"NoSqlExplorerGroup\", false);\n        ViewCollectionValuesAction viewCollectionValuesAction = new ViewCollectionValuesAction(this);\n        RefreshServerAction refreshServerAction = new RefreshServerAction(this);\n        if (ApplicationManager.getApplication() != null) {\n            actionGroup.add(refreshServerAction);\n            actionGroup.add(new NoSqlDatabaseConsoleAction(this));\n            actionGroup.add(viewCollectionValuesAction);\n            actionGroup.add(expandAllAction);\n            actionGroup.add(collapseAllAction);\n            actionGroup.addSeparator();\n            actionGroup.add(new OpenPluginSettingsAction());\n        }\n\n        GuiUtils.installActionGroupInToolBar(actionGroup, toolBarPanel, ActionManager.getInstance(), \"NoSqlExplorerActions\", true);\n\n        DefaultActionGroup actionPopupGroup = new DefaultActionGroup(\"NoSqlExplorerPopupGroup\", true);\n        if (ApplicationManager.getApplication() != null) {\n            actionPopupGroup.add(refreshServerAction);\n            actionPopupGroup.add(viewCollectionValuesAction);\n            actionPopupGroup.add(new DropCollectionAction(this));\n            actionPopupGroup.add(new DropDatabaseAction(this));\n        }\n\n        PopupHandler.installPopupHandler(databaseTree, actionPopupGroup, \"POPUP\", ActionManager.getInstance());\n\n        databaseTree.addMouseListener(new MouseAdapter() {\n            @Override\n            public void mouseClicked(MouseEvent mouseEvent) {\n                if (!(mouseEvent.getSource() instanceof JTree)) {\n                    return;\n                }\n\n                DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) databaseTree.getLastSelectedPathComponent();\n                if (treeNode == null) {\n                    return;\n                }\n\n                if (mouseEvent.getClickCount() == 2) {\n                    if (treeNode.getUserObject() instanceof DatabaseServer && treeNode.getChildCount() == 0) {\n                        reloadServerConfiguration(getSelectedServerNode(), true);\n                    }\n                    if (treeNode.getUserObject() instanceof MongoCollection) {\n                        loadRecords();\n                    }\n                    if (treeNode.getUserObject() instanceof RedisDatabase) {\n                        loadRecords();\n                    }\n\n                    if (treeNode.getUserObject() instanceof CouchbaseDatabase) {\n                        loadRecords();\n                    }\n                }\n            }\n        });\n    }\n\n    private void expandAll() {\n        TreeUtil.expandAll(databaseTree);\n    }\n\n    private void collapseAll() {\n        TreeUtil.collapseAll(databaseTree, 1);\n    }\n\n    @Override\n    public void dispose() {\n        databaseTree = null;\n    }\n\n    public DefaultMutableTreeNode getSelectedServerNode() {\n        DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) databaseTree.getLastSelectedPathComponent();\n        if (treeNode != null) {\n            Object userObject = treeNode.getUserObject();\n            if (userObject instanceof MongoCollection) {\n                return (DefaultMutableTreeNode) treeNode.getParent().getParent();\n            }\n\n            if (userObject instanceof Database) {\n                return (DefaultMutableTreeNode) treeNode.getParent();\n            }\n\n            if (userObject instanceof DatabaseServer) {\n                return treeNode;\n            }\n        }\n        return null;\n    }\n\n\n    private DefaultMutableTreeNode getSelectedDatabaseNode() {\n        DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) databaseTree.getLastSelectedPathComponent();\n        if (treeNode != null) {\n            Object userObject = treeNode.getUserObject();\n//            if (userObject instanceof MongoCollection) {\n//                return (DefaultMutableTreeNode) treeNode.getParent();\n//            }\n\n            if (userObject instanceof Database) {\n                return treeNode;\n            }\n        }\n\n        return null;\n    }\n\n    private DefaultMutableTreeNode getSelectedCollectionNode() {\n        DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) databaseTree.getLastSelectedPathComponent();\n        if (treeNode != null) {\n            Object userObject = treeNode.getUserObject();\n            if (userObject instanceof MongoCollection) {\n                return treeNode;\n            }\n        }\n        return null;\n    }\n\n    public ServerConfiguration getConfiguration() {\n\n        DefaultMutableTreeNode serverNode = getSelectedServerNode();\n        if (serverNode == null) {\n            return null;\n        }\n\n        return ((DatabaseServer) serverNode.getUserObject()).getConfiguration();\n    }\n\n    public RedisDatabase getSelectedRedisDatabase() {\n        DefaultMutableTreeNode databaseNode = getSelectedDatabaseNode();\n        if (databaseNode == null) {\n            return null;\n        }\n\n        Object database = databaseNode.getUserObject();\n        if (!(database instanceof RedisDatabase)) {\n            return null;\n        }\n        return (RedisDatabase) database;\n\n    }\n\n    public CouchbaseDatabase getSelectedCouchaseDatabase() {\n        DefaultMutableTreeNode databaseNode = getSelectedDatabaseNode();\n        if (databaseNode == null) {\n            return null;\n        }\n\n        Object database = databaseNode.getUserObject();\n        if (!(database instanceof CouchbaseDatabase)) {\n            return null;\n        }\n        return (CouchbaseDatabase) database;\n    }\n\n    public MongoDatabase getSelectedMongoDatabase() {\n        DefaultMutableTreeNode databaseNode = getSelectedDatabaseNode();\n        if (databaseNode == null) {\n            return null;\n        }\n\n        Object database = databaseNode.getUserObject();\n        if (!(database instanceof MongoDatabase)) {\n            return null;\n        }\n\n        return (MongoDatabase) databaseNode.getUserObject();\n\n    }\n\n    public MongoCollection getSelectedCollection() {\n        DefaultMutableTreeNode collectionNode = getSelectedCollectionNode();\n        if (collectionNode == null) {\n            return null;\n        }\n\n        return (MongoCollection) collectionNode.getUserObject();\n    }\n\n    public void loadRecords() {\n        NoSqlDatabaseFileSystem.getInstance().openEditor(createNoSqlObjectFile());\n    }\n\n    @NotNull\n    private NoSqlDatabaseObjectFile createNoSqlObjectFile() { // TODO need to put in the database UI manager\n        ServerConfiguration selectedConfiguration = getConfiguration();\n        if (DatabaseVendor.MONGO.equals(selectedConfiguration.getDatabaseVendor())) {\n            return new MongoObjectFile(project, selectedConfiguration, getSelectedCollection());\n        } else if (DatabaseVendor.COUCHBASE.equals(selectedConfiguration.getDatabaseVendor())) {\n            return new CouchbaseObjectFile(project, selectedConfiguration, getSelectedCouchaseDatabase());\n        }\n        return new RedisObjectFile(project, selectedConfiguration, getSelectedRedisDatabase());\n    }\n\n    public void dropCollection() {// TODO need to put in a customizer\n        MongoClient databaseClient = (MongoClient) databaseVendorClientManager.get(DatabaseVendor.MONGO);\n        databaseClient.dropCollection(getConfiguration(), getSelectedCollection());\n        reloadServerConfiguration(getSelectedServerNode(), true);\n    }\n\n    public void dropDatabase() {// TODO need to put in a customizer\n        MongoClient databaseClient = (MongoClient) databaseVendorClientManager.get(DatabaseVendor.MONGO);\n        databaseClient.dropDatabase(getConfiguration(), getSelectedMongoDatabase());\n        reloadServerConfiguration(getSelectedServerNode(), true);\n    }\n\n    private Tree createTree() {\n\n        Tree tree = new Tree() {\n\n            private final JLabel myLabel = new JLabel(\n                    String.format(\"<html><center>NoSql server list is empty<br><br>You may use <img src=\\\"%s\\\"> to add configuration</center></html>\", pluginSettingsUrl)\n            );\n\n            @Override\n            protected void paintComponent(Graphics g) {\n                super.paintComponent(g);\n                if (!getServerConfigurations().isEmpty()) return;\n\n                myLabel.setFont(getFont());\n                myLabel.setBackground(getBackground());\n                myLabel.setForeground(getForeground());\n                Rectangle bounds = getBounds();\n                Dimension size = myLabel.getPreferredSize();\n                myLabel.setBounds(0, 0, size.width, size.height);\n\n                int x = (bounds.width - size.width) / 2;\n                Graphics g2 = g.create(bounds.x + x, bounds.y + 20, bounds.width, bounds.height);\n                try {\n                    myLabel.paint(g2);\n                } finally {\n                    g2.dispose();\n                }\n            }\n        };\n\n        tree.getEmptyText().clear();\n        tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);\n\n        return tree;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/NoSqlServerTableModel.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql;\n\nimport com.intellij.util.ui.ItemRemovable;\n\nimport javax.swing.table.AbstractTableModel;\nimport java.util.List;\n\nclass NoSqlServerTableModel extends AbstractTableModel implements ItemRemovable {\n    private final String[] columnNames = new String[]{\n            \"Label\",\n            \"Vendor\",\n            \"URL\",\n            \"Autoconnect\"\n    };\n    private final Class[] columnClasses = new Class[]{String.class, DatabaseVendor.class, String.class, Boolean.class};\n\n    private final List<ServerConfiguration> mongoServerConfigurations;\n\n    public NoSqlServerTableModel(List<ServerConfiguration> mongoServerConfigurations) {\n        this.mongoServerConfigurations = mongoServerConfigurations;\n    }\n\n    public String getColumnName(int column) {\n        return columnNames[column];\n    }\n\n    public Class getColumnClass(int column) {\n        return columnClasses[column];\n    }\n\n    public int getColumnCount() {\n        return columnNames.length;\n    }\n\n    public int getRowCount() {\n        return mongoServerConfigurations.size();\n    }\n\n    @Override\n    public boolean isCellEditable(int rowIndex, int columnIndex) {\n        return false;\n    }\n\n    public Object getValueAt(int row, int column) {\n        ServerConfiguration configuration = mongoServerConfigurations.get(row);\n        switch (column) {\n            case 0: { // \"Label\" column\n                return configuration.getLabel();\n            }\n            case 1: { // \"Vendor\" column\n                return configuration.getDatabaseVendor();\n            }\n            case 2: { // \"URL\" column\n                return configuration.getServerUrl();\n            }\n            case 3: { // \"Autoconnect\" column\n                return configuration.isConnectOnIdeStartup();\n            }\n            default: {\n                throw new IllegalArgumentException();\n            }\n        }\n    }\n\n    public void setValueAt(Object value, int row, int column) {\n        ServerConfiguration configuration = mongoServerConfigurations.get(row);\n        switch (column) {\n            case 0: {\n                configuration.setLabel((String) value);\n                break;\n            }\n            case 1: {\n                //do nothing ??\n                break;\n            }\n            case 2: {\n                //do nothing url = serverHosts\n                break;\n            }\n            case 3: {\n                configuration.setConnectOnIdeStartup((Boolean) value);\n                break;\n            }\n            default: {\n                throw new IllegalArgumentException();\n            }\n        }\n    }\n\n    public void removeRow(int index) {\n        mongoServerConfigurations.remove(index);\n        fireTableRowsDeleted(index, index);\n    }\n}"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/NoSqlTreeRenderer.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql;\n\nimport com.intellij.icons.AllIcons;\nimport com.intellij.ui.ColoredTreeCellRenderer;\nimport com.intellij.ui.JBColor;\nimport org.apache.commons.lang.StringUtils;\nimport org.codinjutsu.tools.nosql.commons.model.Database;\nimport org.codinjutsu.tools.nosql.commons.model.DatabaseServer;\nimport org.codinjutsu.tools.nosql.commons.utils.GuiUtils;\nimport org.codinjutsu.tools.nosql.mongo.model.MongoCollection;\nimport org.jetbrains.annotations.NotNull;\n\nimport javax.swing.*;\nimport javax.swing.tree.DefaultMutableTreeNode;\n\npublic class NoSqlTreeRenderer extends ColoredTreeCellRenderer {\n\n    private static final Icon DATABASE = GuiUtils.loadIcon(\"database.png\");\n    private static final Icon MONGO_COLLECTION = AllIcons.Nodes.Folder;\n\n    @Override\n    public void customizeCellRenderer(@NotNull JTree mongoTree, Object value, boolean isSelected, boolean isExpanded, boolean isLeaf, int row, boolean focus) {\n\n        DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;\n\n        Object userObject = node.getUserObject();\n        if (userObject instanceof DatabaseServer) {\n            DatabaseServer mongoServer = (DatabaseServer) userObject;\n            String label = mongoServer.getLabel();\n            String host = mongoServer.getServerUrl();\n            append(StringUtils.isBlank(label) ? host : label);\n\n            if (DatabaseServer.Status.OK.equals(mongoServer.getStatus())) {\n                setToolTipText(host);\n                setIcon(mongoServer.getConfiguration().getDatabaseVendor().icon);\n            } else {\n                setForeground(JBColor.RED);\n                setToolTipText(\"Unable to connect\");\n            }\n        } else if (userObject instanceof Database) {\n            Database noSqlDatabase = (Database) userObject;\n            append(noSqlDatabase.getName());\n            setIcon(DATABASE);\n        } else if (userObject instanceof MongoCollection) {\n            MongoCollection mongoCollection = (MongoCollection) userObject;\n            append(mongoCollection.getName());\n            setIcon(MONGO_COLLECTION);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/NoSqlWindowManager.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql;\n\nimport com.intellij.openapi.application.ApplicationManager;\nimport com.intellij.openapi.components.ServiceManager;\nimport com.intellij.openapi.project.Project;\nimport com.intellij.openapi.wm.ToolWindow;\nimport com.intellij.openapi.wm.ToolWindowAnchor;\nimport com.intellij.openapi.wm.ToolWindowManager;\nimport com.intellij.ui.content.Content;\nimport com.intellij.ui.content.ContentFactory;\nimport org.codinjutsu.tools.nosql.commons.utils.GuiUtils;\n\nimport javax.swing.*;\n\n\npublic class NoSqlWindowManager {\n\n    private static final Icon NOSQL_ICON = GuiUtils.loadIcon(\"nosql_13x13.png\");\n\n    public static final String NOSQL_RUNNER = \"NoSql Runner\";\n    private static final String NOSQL_EXPLORER = \"NoSql Explorer\";\n\n    private final Project project;\n    private final NoSqlExplorerPanel noSqlExplorerPanel;\n\n    public static NoSqlWindowManager getInstance(Project project) {\n        return ServiceManager.getService(project, NoSqlWindowManager.class);\n    }\n\n    public NoSqlWindowManager(Project project) {\n        this.project = project;\n\n        ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(project);\n        noSqlExplorerPanel = new NoSqlExplorerPanel(project, DatabaseVendorClientManager.getInstance(project));\n        noSqlExplorerPanel.installActions();\n        Content nosqlExplorer = ContentFactory.SERVICE.getInstance().createContent(noSqlExplorerPanel, null, false);\n\n        ToolWindow toolNoSqlExplorerWindow = toolWindowManager.registerToolWindow(NOSQL_EXPLORER, false, ToolWindowAnchor.RIGHT);\n        toolNoSqlExplorerWindow.getContentManager().addContent(nosqlExplorer);\n        toolNoSqlExplorerWindow.setIcon(NOSQL_ICON);\n    }\n\n    public void unregisterMyself() {\n        ToolWindowManager.getInstance(project).unregisterToolWindow(NOSQL_RUNNER);\n        ToolWindowManager.getInstance(project).unregisterToolWindow(NOSQL_EXPLORER);\n    }\n\n    public void apply() {\n        ApplicationManager.getApplication().invokeLater(new Runnable() {\n            @Override\n            public void run() {\n                noSqlExplorerPanel.reloadAllServerConfigurations();\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/SelectDatabaseVendorDialog.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<form xmlns=\"http://www.intellij.com/uidesigner/form/\" version=\"1\" bind-to-class=\"org.codinjutsu.tools.nosql.SelectDatabaseVendorDialog\">\n  <grid id=\"27dc6\" binding=\"mainPanel\" layout-manager=\"GridLayoutManager\" row-count=\"2\" column-count=\"2\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n    <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n    <constraints>\n      <xy x=\"20\" y=\"20\" width=\"500\" height=\"400\"/>\n    </constraints>\n    <properties/>\n    <border type=\"none\"/>\n    <children>\n      <component id=\"5d1ce\" class=\"javax.swing.JLabel\">\n        <constraints>\n          <grid row=\"0\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties>\n          <text value=\"Database Vendor:\"/>\n        </properties>\n      </component>\n      <vspacer id=\"5dc43\">\n        <constraints>\n          <grid row=\"1\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"6\" hsize-policy=\"1\" anchor=\"0\" fill=\"2\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n      </vspacer>\n      <component id=\"6fcf8\" class=\"com.intellij.openapi.ui.ComboBox\" binding=\"databaseVendorCombobox\">\n        <constraints>\n          <grid row=\"0\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"3\" anchor=\"0\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n      </component>\n    </children>\n  </grid>\n</form>\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/SelectDatabaseVendorDialog.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql;\n\nimport com.intellij.openapi.ui.ComboBox;\nimport com.intellij.openapi.ui.DialogWrapper;\nimport com.intellij.ui.ColoredListCellRenderer;\nimport org.jetbrains.annotations.Nullable;\n\nimport javax.swing.*;\nimport java.awt.*;\n\npublic class SelectDatabaseVendorDialog extends DialogWrapper {\n\n\n    private JPanel mainPanel;\n    private ComboBox databaseVendorCombobox;\n\n    protected SelectDatabaseVendorDialog(Component parent) {\n        super(parent, true);\n        databaseVendorCombobox.setName(\"databaseVendorCombobox\");\n\n        init();\n    }\n\n    @Nullable\n    @Override\n    protected JComponent createCenterPanel() {\n        return mainPanel;\n    }\n\n    @Override\n    protected void init() {\n        super.init();\n        initCombobox();\n    }\n\n    private void initCombobox() {\n\n        databaseVendorCombobox.setModel(new DefaultComboBoxModel(DatabaseVendor.values()));\n        databaseVendorCombobox.setRenderer(new ColoredListCellRenderer() {\n            @Override\n            protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) {\n                DatabaseVendor databaseVendor = (DatabaseVendor) value;\n                setIcon(databaseVendor.icon);\n                append(databaseVendor.name);\n            }\n        });\n\n        databaseVendorCombobox.setSelectedItem(DatabaseVendor.MONGO);\n    }\n\n    public DatabaseVendor getSelectedDatabaseVendor() {\n        return (DatabaseVendor) databaseVendorCombobox.getSelectedItem();\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/ServerConfiguration.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql;\n\nimport org.codinjutsu.tools.nosql.commons.model.AuthenticationSettings;\n\npublic class ServerConfiguration implements Cloneable {\n\n    private String label;\n\n    private DatabaseVendor databaseVendor = DatabaseVendor.MONGO;\n\n    private String serverUrl;\n\n    private String userDatabase;\n\n    private boolean connectOnIdeStartup = false;\n\n    private String shellArgumentsLine;\n    private String shellWorkingDir;\n\n    private AuthenticationSettings authenticationSettings = new AuthenticationSettings();\n\n    public DatabaseVendor getDatabaseVendor() {\n        return databaseVendor;\n    }\n\n    public void setDatabaseVendor(DatabaseVendor databaseVendor) {\n        this.databaseVendor = databaseVendor;\n    }\n\n    public String getServerUrl() {\n        return serverUrl;\n    }\n\n    public void setServerUrl(String serverUrl) {\n        this.serverUrl = serverUrl;\n    }\n\n    public void setUserDatabase(String userDatabase) {\n        this.userDatabase = userDatabase;\n    }\n\n    public String getUserDatabase() {\n        return userDatabase;\n    }\n\n    public boolean isConnectOnIdeStartup() {\n        return connectOnIdeStartup;\n    }\n\n    public void setConnectOnIdeStartup(boolean connectOnIdeStartup) {\n        this.connectOnIdeStartup = connectOnIdeStartup;\n    }\n\n    public String getLabel() {\n        return label;\n    }\n\n    public void setLabel(String label) {\n        this.label = label;\n    }\n\n    public String getShellArgumentsLine() {\n        return shellArgumentsLine;\n    }\n\n    public void setShellArgumentsLine(String shellArgumentsLine) {\n        this.shellArgumentsLine = shellArgumentsLine;\n    }\n\n    public String getShellWorkingDir() {\n        return shellWorkingDir;\n    }\n\n    public void setShellWorkingDir(String shellWorkingDir) {\n        this.shellWorkingDir = shellWorkingDir;\n    }\n\n    public boolean isSingleServer() {\n        return serverUrl.split(\",\").length == 1;\n    }\n\n    public void setAuthenticationSettings(AuthenticationSettings authenticationSettings) {\n        this.authenticationSettings = authenticationSettings;\n    }\n\n\n    public AuthenticationSettings getAuthenticationSettings() {\n        return authenticationSettings;\n    }\n\n    public ServerConfiguration clone() {\n        try {\n            return (ServerConfiguration) super.clone();\n        } catch (CloneNotSupportedException e) {\n            return null;\n        }\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        ServerConfiguration that = (ServerConfiguration) o;\n\n        if (connectOnIdeStartup != that.connectOnIdeStartup) return false;\n        if (!label.equals(that.label)) return false;\n        if (databaseVendor != that.databaseVendor) return false;\n        if (!serverUrl.equals(that.serverUrl)) return false;\n        if (userDatabase != null ? !userDatabase.equals(that.userDatabase) : that.userDatabase != null) return false;\n        if (shellArgumentsLine != null ? !shellArgumentsLine.equals(that.shellArgumentsLine) : that.shellArgumentsLine != null)\n            return false;\n        if (shellWorkingDir != null ? !shellWorkingDir.equals(that.shellWorkingDir) : that.shellWorkingDir != null)\n            return false;\n        return !(authenticationSettings != null ? !authenticationSettings.equals(that.authenticationSettings) : that.authenticationSettings != null);\n\n    }\n\n    @Override\n    public int hashCode() {\n        int result = label.hashCode();\n        result = 31 * result + databaseVendor.hashCode();\n        result = 31 * result + serverUrl.hashCode();\n        result = 31 * result + (userDatabase != null ? userDatabase.hashCode() : 0);\n        result = 31 * result + (connectOnIdeStartup ? 1 : 0);\n        result = 31 * result + (shellArgumentsLine != null ? shellArgumentsLine.hashCode() : 0);\n        result = 31 * result + (shellWorkingDir != null ? shellWorkingDir.hashCode() : 0);\n        result = 31 * result + (authenticationSettings != null ? authenticationSettings.hashCode() : 0);\n        return result;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/DatabaseUI.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons;\n\nimport com.intellij.openapi.project.Project;\nimport org.codinjutsu.tools.nosql.commons.view.AuthenticationView;\nimport org.codinjutsu.tools.nosql.commons.view.NoSqlResultView;\nimport org.codinjutsu.tools.nosql.commons.view.editor.NoSqlDatabaseObjectFile;\n\npublic interface DatabaseUI {\n    AuthenticationView createAythenticationView();\n\n    NoSqlResultView createResultPanel(Project project, NoSqlDatabaseObjectFile objectFile);\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/logic/ConfigurationException.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.logic;\n\npublic class ConfigurationException extends RuntimeException {\n    public ConfigurationException(String message) {\n        super(message);\n    }\n\n    public ConfigurationException(Exception ex) {\n        super(ex);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/logic/DatabaseClient.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.logic;\n\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.codinjutsu.tools.nosql.commons.model.DatabaseServer;\n\npublic interface DatabaseClient {\n\n    void connect(ServerConfiguration serverConfiguration);\n\n    void loadServer(DatabaseServer databaseServer);\n\n    void cleanUpServers();\n\n    void registerServer(DatabaseServer databaseServer);\n\n    ServerConfiguration defaultConfiguration();\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/model/AuthenticationSettings.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.model;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class AuthenticationSettings {\n\n    private String username = null;\n    private String password = null;\n\n    private Map<String, String> extras = new HashMap<>();\n\n    public String getUsername() {\n        return username;\n    }\n\n    public void setUsername(String username) {\n        this.username = username;\n    }\n\n    public String getPassword() {\n        return password;\n    }\n\n    public void setPassword(String password) {\n        this.password = password;\n    }\n\n    public Map<String, String> getExtras() {\n        return extras;\n    }\n\n    public void setExtras(Map<String, String> extras) {\n        this.extras = extras;\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        AuthenticationSettings that = (AuthenticationSettings) o;\n\n        if (username != null ? !username.equals(that.username) : that.username != null) return false;\n        if (password != null ? !password.equals(that.password) : that.password != null) return false;\n        return !(extras != null ? !extras.equals(that.extras) : that.extras != null);\n\n    }\n\n    @Override\n    public int hashCode() {\n        int result = username != null ? username.hashCode() : 0;\n        result = 31 * result + (password != null ? password.hashCode() : 0);\n        result = 31 * result + (extras != null ? extras.hashCode() : 0);\n        return result;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/model/Database.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.model;\n\npublic class Database {\n    protected final String name;\n\n    public Database(String name) {\n        this.name = name;\n    }\n\n    public String getName() {\n        return name;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/model/DatabaseServer.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.model;\n\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\n\nimport java.util.LinkedList;\nimport java.util.List;\n\npublic class DatabaseServer {\n\n    public enum Status {\n        OK, LOADING, ERROR\n    }\n\n    private List<Database> databases = new LinkedList<Database>();\n\n    private final ServerConfiguration configuration;\n\n    private Status status = Status.OK;\n\n    public DatabaseServer(ServerConfiguration configuration) {\n        this.configuration = configuration;\n    }\n\n    public String getServerUrl() {\n        return configuration.getServerUrl();\n    }\n\n    public String getLabel() {\n        return configuration.getLabel();\n    }\n\n    public void setDatabases(List<Database> databases) {\n        this.databases = databases;\n    }\n\n    public boolean hasDatabases() {\n        return !databases.isEmpty();\n    }\n\n    public List<Database> getDatabases() {\n        return databases;\n    }\n\n    public Status getStatus() {\n        return status;\n    }\n\n    public void setStatus(Status status) {\n        this.status = status;\n    }\n\n    public ServerConfiguration getConfiguration() {\n        return configuration;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/style/StyleAttributesProvider.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.style;\n\nimport com.intellij.ui.Gray;\nimport com.intellij.ui.JBColor;\nimport com.intellij.ui.SimpleTextAttributes;\n\nimport java.awt.*;\n\npublic class StyleAttributesProvider {\n\n    private static final Color LIGNT_GREEN = new JBColor(new Color(0, 128, 0), new Color(165, 194, 97));\n    private static final Color LIGHT_GRAY = Gray._128;\n    public static final Color KEY_COLOR = new JBColor(new Color(102, 14, 122), new Color(204, 120, 50));\n    public static final Color NUMBER_COLOR = JBColor.BLUE;\n\n    private static final SimpleTextAttributes INDEX = new SimpleTextAttributes(Font.BOLD, JBColor.BLACK);\n    private static final SimpleTextAttributes KEY_VALUE = new SimpleTextAttributes(Font.BOLD, KEY_COLOR);\n    private static final SimpleTextAttributes INTEGER_TEXT_ATTRIBUTE = new SimpleTextAttributes(Font.PLAIN, NUMBER_COLOR);\n    private static final SimpleTextAttributes BOOLEAN_TEXT_ATTRIBUTE = INTEGER_TEXT_ATTRIBUTE;\n    private static final SimpleTextAttributes STRING_TEXT_ATTRIBUTE = new SimpleTextAttributes(Font.PLAIN, LIGNT_GREEN);\n    private static final SimpleTextAttributes NULL_TEXT_ATTRIBUTE = new SimpleTextAttributes(Font.ITALIC, LIGHT_GRAY);\n    private static final SimpleTextAttributes OBJECT_TEXT_ATTRIBUTE = new SimpleTextAttributes(Font.BOLD, LIGHT_GRAY);\n    private static final SimpleTextAttributes OBJECT_ID_TEXT_ATTRIBUTE = INTEGER_TEXT_ATTRIBUTE;\n\n    public static SimpleTextAttributes getIndexAttribute() {\n        return INDEX;\n    }\n\n    public static SimpleTextAttributes getKeyValueAttribute() {\n        return KEY_VALUE;\n    }\n\n    public static SimpleTextAttributes getNumberAttribute() {\n        return INTEGER_TEXT_ATTRIBUTE;\n    }\n\n    public static SimpleTextAttributes getBooleanAttribute() {\n        return BOOLEAN_TEXT_ATTRIBUTE;\n    }\n\n    public static SimpleTextAttributes getStringAttribute() {\n        return STRING_TEXT_ATTRIBUTE;\n    }\n\n    public static SimpleTextAttributes getNullAttribute() {\n        return NULL_TEXT_ATTRIBUTE;\n    }\n\n    public static SimpleTextAttributes getObjectAttribute() {\n        return OBJECT_TEXT_ATTRIBUTE;\n    }\n\n    public static SimpleTextAttributes getObjectIdAttribute() {\n        return OBJECT_ID_TEXT_ATTRIBUTE;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/utils/DateUtils.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.utils;\n\nimport java.text.DateFormat;\nimport java.util.Locale;\nimport java.util.TimeZone;\n\npublic class DateUtils {\n\n    public static DateFormat utcDateTime(Locale locale) {\n        DateFormat format = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG, locale);\n        format.setTimeZone(TimeZone.getTimeZone(\"UTC\"));\n        return format;\n    }\n\n    public static DateFormat utcTime(Locale locale) {\n        DateFormat format = DateFormat.getTimeInstance(DateFormat.MEDIUM, locale);\n        format.setTimeZone(TimeZone.getTimeZone(\"UTC\"));\n        return format;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/utils/GuiUtils.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.utils;\n\nimport com.intellij.openapi.actionSystem.ActionManager;\nimport com.intellij.openapi.actionSystem.DefaultActionGroup;\nimport com.intellij.openapi.application.ApplicationManager;\nimport com.intellij.openapi.ui.MessageType;\nimport com.intellij.openapi.ui.popup.Balloon;\nimport com.intellij.openapi.ui.popup.JBPopupFactory;\nimport com.intellij.openapi.util.IconLoader;\nimport com.intellij.ui.awt.RelativePoint;\nimport org.jetbrains.annotations.NotNull;\n\nimport javax.swing.*;\nimport javax.swing.tree.TreeNode;\nimport javax.swing.tree.TreePath;\nimport java.awt.*;\nimport java.net.URL;\nimport java.util.Enumeration;\n\npublic class GuiUtils {\n\n    private static final String ICON_FOLDER = \"/icons/\";\n\n    public static Icon loadIcon(String iconFilename) {\n        return IconLoader.findIcon(ICON_FOLDER + iconFilename);\n    }\n\n    public static Icon loadIcon(String iconFilename, String darkIconFilename) {\n        String iconPath = ICON_FOLDER;\n        if (isUnderDarcula()) {\n            iconPath += darkIconFilename;\n        } else {\n            iconPath += iconFilename;\n        }\n        return IconLoader.findIcon(iconPath);\n    }\n\n    public static URL getIconResource(String iconFilename) {\n        return GuiUtils.class.getResource(ICON_FOLDER + iconFilename);\n    }\n\n    public static void installActionGroupInToolBar(DefaultActionGroup actionGroup, JPanel toolBarPanel, ActionManager actionManager, String toolbarName, boolean horizontal) {\n        if (actionManager == null) {\n            return;\n        }\n\n        JComponent actionToolbar = ActionManager.getInstance().createActionToolbar(toolbarName, actionGroup, horizontal).getComponent();\n        toolBarPanel.add(actionToolbar, BorderLayout.CENTER);\n    }\n\n    public static boolean isUnderDarcula() {\n        return UIManager.getLookAndFeel().getName().contains(\"Darcula\");\n    }\n\n    public static void runInSwingThread(Runnable runnable) {\n        ApplicationManager.getApplication().invokeLater(runnable);\n    }\n\n    //    Copy from private method com.intellij.util.ui.tree.TreeUtils#expand need to expand specifically some node instead of the whole tree\n    public static void expand(@NotNull JTree tree, @NotNull TreePath path, int levels) {\n        if (levels == 0) return;\n        tree.expandPath(path);\n        TreeNode node = (TreeNode) path.getLastPathComponent();\n        Enumeration children = node.children();\n        while (children.hasMoreElements()) {\n            expand(tree, path.pathByAddingChild(children.nextElement()), levels - 1);\n        }\n    }\n\n    public static Dimension enlargeWidth(Dimension preferredSize, double factor) {\n        int enlargedWidth = new Double(preferredSize.width * factor).intValue();\n        return new Dimension(enlargedWidth, preferredSize.height);\n    }\n\n    public static void showNotification(final JComponent component, final MessageType info, final String message, final Balloon.Position position) {\n        runInSwingThread(new Runnable() {\n            @Override\n            public void run() {\n                JBPopupFactory.getInstance().createBalloonBuilder(new JLabel(message))\n                        .setFillColor(info.getPopupBackground())\n                        .createBalloon()\n                        .show(new RelativePoint(component, new Point(0, 0)), position);\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/utils/StringUtils.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.utils;\n\npublic class StringUtils {\n\n    private static final String ELLIPSIS = \"...\";\n\n    public static String abbreviateInCenter(String stringToAbbreviate, int length) {\n        int halfLength = length / 2;\n        int firstPartLastIndex = halfLength - ELLIPSIS.length();\n        int stringLength = stringToAbbreviate.length();\n        return String.format(\"%s%s%s\",\n                stringToAbbreviate.substring(0, firstPartLastIndex),\n                ELLIPSIS,\n                stringToAbbreviate.substring(stringLength - halfLength, stringLength));\n    }\n\n    public static Number parseNumber(String number) {\n        try {\n            return Integer.parseInt(number);\n\n        } catch (NumberFormatException ex) {\n            ; //UGLY :(\n        }\n        try {\n            return Long.parseLong(number);\n\n        } catch (NumberFormatException ex) {\n            ; //UGLY :(\n        }\n        return Double.parseDouble(number);\n    }\n\n    public static String[] explode(String key, String separator) {\n        return org.apache.commons.lang.StringUtils.split(key, separator);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/view/AuthenticationView.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.view;\n\nimport org.codinjutsu.tools.nosql.commons.model.AuthenticationSettings;\n\nimport javax.swing.*;\n\npublic interface AuthenticationView {\n\n\n    JPanel getComponent();\n\n    AuthenticationSettings create();\n\n    void load(AuthenticationSettings settings);\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/view/ErrorPanel.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.view;\n\nimport com.intellij.openapi.ui.Messages;\nimport com.intellij.ui.HoverHyperlinkLabel;\nimport com.intellij.ui.JBColor;\nimport com.intellij.ui.components.JBLabel;\n\nimport javax.swing.*;\nimport javax.swing.event.HyperlinkEvent;\nimport javax.swing.event.HyperlinkListener;\nimport java.awt.*;\n\npublic class ErrorPanel extends JPanel {\n\n    public ErrorPanel(final Exception ex) {\n        setLayout(new BoxLayout(this, BoxLayout.X_AXIS));\n        JBLabel comp = new JBLabel(\"Error during query execution:\");\n        comp.setForeground(JBColor.RED);\n        add(comp);\n        final HoverHyperlinkLabel hoverHyperlinkLabel = new HoverHyperlinkLabel(\"more detail...\");\n        hoverHyperlinkLabel.addHyperlinkListener(new HyperlinkListener() {\n            @Override\n            public void hyperlinkUpdate(HyperlinkEvent hyperlinkEvent) {\n                if (hyperlinkEvent.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {\n                    Messages.showErrorDialog(ex.toString(), \"Error During Query Execution\");\n                }\n            }\n        });\n        add(Box.createRigidArea(new Dimension(10, 10)));\n        add(hoverHyperlinkLabel);\n\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/view/NoSqlResultView.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.view;\n\nimport com.intellij.openapi.Disposable;\n\nimport javax.swing.*;\n\npublic abstract class NoSqlResultView<R> extends JPanel implements Disposable {\n\n    public abstract void showResults();\n\n    public abstract JPanel getResultPanel();\n\n    public abstract R getRecords();\n\n    public abstract void executeQuery();\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/view/NoSqlTreeNode.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.view;\n\nimport org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor;\n\nimport javax.swing.tree.DefaultMutableTreeNode;\n\npublic class NoSqlTreeNode extends DefaultMutableTreeNode {\n\n    public NoSqlTreeNode(NodeDescriptor nodeDescriptor) {\n        setUserObject(nodeDescriptor);\n    }\n\n    public NodeDescriptor getDescriptor() {\n        return (NodeDescriptor) this.getUserObject();\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/view/ServerConfigurationPanel.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<form xmlns=\"http://www.intellij.com/uidesigner/form/\" version=\"1\" bind-to-class=\"org.codinjutsu.tools.nosql.commons.view.ServerConfigurationPanel\">\n  <grid id=\"27dc6\" binding=\"rootPanel\" layout-manager=\"GridLayoutManager\" row-count=\"10\" column-count=\"3\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n    <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n    <constraints>\n      <xy x=\"20\" y=\"20\" width=\"926\" height=\"597\"/>\n    </constraints>\n    <properties/>\n    <border type=\"none\"/>\n    <children>\n      <component id=\"3c8c4\" class=\"javax.swing.JLabel\">\n        <constraints>\n          <grid row=\"2\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties>\n          <text value=\"Server url(s):\"/>\n        </properties>\n      </component>\n      <vspacer id=\"79c7c\">\n        <constraints>\n          <grid row=\"9\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"6\" hsize-policy=\"1\" anchor=\"0\" fill=\"2\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n      </vspacer>\n      <component id=\"264eb\" class=\"javax.swing.JTextField\" binding=\"serverUrlField\">\n        <constraints>\n          <grid row=\"2\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"6\" anchor=\"8\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\">\n            <preferred-size width=\"150\" height=\"-1\"/>\n          </grid>\n        </constraints>\n        <properties>\n          <text value=\"\"/>\n        </properties>\n      </component>\n      <grid id=\"10cf3\" layout-manager=\"GridLayoutManager\" row-count=\"1\" column-count=\"2\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n        <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n        <constraints>\n          <grid row=\"6\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n        <border type=\"none\"/>\n        <children>\n          <component id=\"93de1\" class=\"javax.swing.JButton\" binding=\"testConnectionButton\">\n            <constraints>\n              <grid row=\"0\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"3\" anchor=\"0\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\"/>\n            </constraints>\n            <properties>\n              <text value=\"Test Connection\"/>\n            </properties>\n          </component>\n          <hspacer id=\"953d2\">\n            <constraints>\n              <grid row=\"0\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"1\" hsize-policy=\"6\" anchor=\"0\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\"/>\n            </constraints>\n          </hspacer>\n        </children>\n      </grid>\n      <grid id=\"5672e\" binding=\"mongoShellOptionsPanel\" layout-manager=\"GridLayoutManager\" row-count=\"3\" column-count=\"2\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n        <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n        <constraints>\n          <grid row=\"8\" column=\"0\" row-span=\"1\" col-span=\"2\" vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n        <border type=\"none\" title=\"Mongo shell\"/>\n        <children>\n          <component id=\"dc5d9\" class=\"javax.swing.JLabel\">\n            <constraints>\n              <grid row=\"0\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n            </constraints>\n            <properties>\n              <text value=\"Arguments:\"/>\n            </properties>\n          </component>\n          <component id=\"e731d\" class=\"com.intellij.ui.RawCommandLineEditor\" binding=\"shellArgumentsLineField\">\n            <constraints>\n              <grid row=\"0\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\"/>\n            </constraints>\n            <properties/>\n          </component>\n          <component id=\"23136\" class=\"javax.swing.JLabel\">\n            <constraints>\n              <grid row=\"1\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n            </constraints>\n            <properties>\n              <text value=\"Working dir:\"/>\n            </properties>\n          </component>\n          <component id=\"d4144\" class=\"com.intellij.openapi.ui.TextFieldWithBrowseButton\" binding=\"shellWorkingDirField\" custom-create=\"true\">\n            <constraints>\n              <grid row=\"1\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\" indent=\"0\" use-parent-layout=\"false\"/>\n            </constraints>\n            <properties/>\n          </component>\n          <component id=\"943fb\" class=\"javax.swing.JLabel\">\n            <constraints>\n              <grid row=\"2\" column=\"0\" row-span=\"1\" col-span=\"2\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n            </constraints>\n            <properties>\n              <font/>\n              <text value=\"Note: Do not put url, port, username and password in the above arguments\"/>\n            </properties>\n          </component>\n        </children>\n      </grid>\n      <component id=\"63c7f\" class=\"javax.swing.JLabel\">\n        <constraints>\n          <grid row=\"1\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties>\n          <text value=\"Label:\"/>\n        </properties>\n      </component>\n      <component id=\"20aea\" class=\"javax.swing.JTextField\" binding=\"labelField\">\n        <constraints>\n          <grid row=\"1\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"6\" anchor=\"8\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\">\n            <preferred-size width=\"150\" height=\"-1\"/>\n          </grid>\n        </constraints>\n        <properties/>\n      </component>\n      <component id=\"ab51\" class=\"javax.swing.JLabel\" binding=\"databaseTipsLabel\">\n        <constraints>\n          <grid row=\"3\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties>\n          <font style=\"2\"/>\n          <text value=\"format: host:port. If replicat set: host:port1,host:port2,...\"/>\n        </properties>\n      </component>\n      <component id=\"d7fc6\" class=\"javax.swing.JLabel\">\n        <constraints>\n          <grid row=\"5\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties>\n          <text value=\"User Database:\"/>\n        </properties>\n      </component>\n      <component id=\"c9dec\" class=\"javax.swing.JCheckBox\" binding=\"autoConnectCheckBox\">\n        <constraints>\n          <grid row=\"7\" column=\"1\" row-span=\"1\" col-span=\"2\" vsize-policy=\"0\" hsize-policy=\"3\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties>\n          <horizontalTextPosition value=\"11\"/>\n          <text value=\"Connect on IDE startup\"/>\n        </properties>\n      </component>\n      <component id=\"8afaa\" class=\"javax.swing.JTextField\" binding=\"userDatabaseField\">\n        <constraints>\n          <grid row=\"5\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"6\" anchor=\"8\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\">\n            <preferred-size width=\"150\" height=\"-1\"/>\n          </grid>\n        </constraints>\n        <properties/>\n      </component>\n      <component id=\"90256\" class=\"javax.swing.JLabel\">\n        <constraints>\n          <grid row=\"0\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties>\n          <text value=\"Database Vendor:\"/>\n        </properties>\n      </component>\n      <component id=\"fea84\" class=\"javax.swing.JLabel\" binding=\"databaseVendorLabel\">\n        <constraints>\n          <grid row=\"0\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties>\n          <text value=\"Label\"/>\n        </properties>\n      </component>\n      <grid id=\"ba0c9\" binding=\"authenticationContainer\" layout-manager=\"BorderLayout\" hgap=\"0\" vgap=\"0\">\n        <constraints>\n          <grid row=\"4\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n        <border type=\"none\"/>\n        <children/>\n      </grid>\n    </children>\n  </grid>\n</form>\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/view/ServerConfigurationPanel.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.view;\n\nimport com.intellij.openapi.fileChooser.FileChooserDescriptor;\nimport com.intellij.openapi.progress.ProgressIndicator;\nimport com.intellij.openapi.progress.ProgressManager;\nimport com.intellij.openapi.project.Project;\nimport com.intellij.openapi.ui.*;\nimport com.intellij.openapi.util.Ref;\nimport com.intellij.ui.IdeBorderFactory;\nimport com.intellij.ui.RawCommandLineEditor;\nimport org.apache.commons.lang.StringUtils;\nimport org.codinjutsu.tools.nosql.DatabaseVendor;\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.codinjutsu.tools.nosql.commons.logic.ConfigurationException;\nimport org.codinjutsu.tools.nosql.commons.logic.DatabaseClient;\nimport org.jetbrains.annotations.NotNull;\n\nimport javax.swing.*;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\npublic class ServerConfigurationPanel extends JPanel {\n\n    private JPanel rootPanel;\n    private JTextField labelField;\n    private JPanel authenticationContainer;\n    private JTextField serverUrlField;\n    private JTextField userDatabaseField;\n    private JCheckBox autoConnectCheckBox;\n    private JButton testConnectionButton;\n    private JPanel mongoShellOptionsPanel;\n    private TextFieldWithBrowseButton shellWorkingDirField;\n    private RawCommandLineEditor shellArgumentsLineField;\n    private JLabel databaseTipsLabel;\n    private JLabel databaseVendorLabel;\n\n    private final Project project;\n\n    private final DatabaseClient databaseClient;\n    private final DatabaseVendor databaseVendor;\n    private final AuthenticationView authenticationView;\n\n\n    public ServerConfigurationPanel(Project project,\n                                    DatabaseVendor databaseVendor,\n                                    DatabaseClient databaseClient,\n                                    AuthenticationView authenticationView) {\n        this.project = project;\n        this.databaseClient = databaseClient;\n        this.databaseVendor = databaseVendor;\n        this.authenticationView = authenticationView;\n\n        setLayout(new BorderLayout());\n        add(rootPanel, BorderLayout.CENTER);\n        authenticationContainer.add(authenticationView.getComponent());\n\n        labelField.setName(\"labelField\");\n        databaseVendorLabel.setName(\"databaseVendorLabel\");\n        databaseVendorLabel.setText(databaseVendor.name);\n        databaseVendorLabel.setIcon(databaseVendor.icon);\n\n        databaseTipsLabel.setName(\"databaseTipsLabel\");\n        databaseTipsLabel.setText(databaseVendor.tips);\n\n        serverUrlField.setName(\"serverUrlField\");\n\n        authenticationContainer.setBorder(IdeBorderFactory.createTitledBorder(\"Authentication settings\", true));\n        userDatabaseField.setName(\"userDatabaseField\");\n        userDatabaseField.setToolTipText(\"If your access is restricted to a specific database (e.g.: MongoLab), you can set it right here\");\n\n        autoConnectCheckBox.setName(\"autoConnectField\");\n\n        mongoShellOptionsPanel.setBorder(IdeBorderFactory.createTitledBorder(\"Mongo shell options\", true));\n        shellArgumentsLineField.setDialogCaption(\"Mongo arguments\");\n\n        testConnectionButton.setName(\"testConnection\");\n\n        shellWorkingDirField.setText(null);\n        initListeners();\n    }\n\n    private void initListeners() {\n        testConnectionButton.addActionListener(new ActionListener() {\n            @Override\n            public void actionPerformed(ActionEvent actionEvent) {\n\n                final Ref<Exception> excRef = new Ref<>();\n                final ProgressManager progressManager = ProgressManager.getInstance();\n                progressManager.runProcessWithProgressSynchronously(new Runnable() {\n                    @Override\n                    public void run() {\n                        ServerConfiguration configuration = createServerConfigurationForTesting();\n\n                        final ProgressIndicator progressIndicator = progressManager.getProgressIndicator();\n                        if (progressIndicator != null) {\n                            progressIndicator.setText(\"Connecting to \" + configuration.getServerUrl());\n                        }\n                        try {\n                            databaseClient.connect(configuration);\n                        } catch (Exception ex) {\n                            excRef.set(ex);\n                        }\n                    }\n\n                }, \"Testing connection for \" + databaseVendor.name, true, ServerConfigurationPanel.this.project);\n\n                if (!excRef.isNull()) {\n                    Messages.showErrorDialog(rootPanel, excRef.get().getMessage(), \"Connection test failed\");\n                } else {\n                    Messages.showInfoMessage(rootPanel, \"Connection test successful for \" + databaseVendor.name, \"Connection test successful\");\n                }\n            }\n        });\n    }\n\n    public void loadConfigurationData(ServerConfiguration configuration) {\n        labelField.setText(configuration.getLabel());\n        serverUrlField.setText(configuration.getServerUrl());\n        userDatabaseField.setText(configuration.getUserDatabase());\n        shellArgumentsLineField.setText(configuration.getShellArgumentsLine());\n        shellWorkingDirField.setText(configuration.getShellWorkingDir());\n        autoConnectCheckBox.setSelected(configuration.isConnectOnIdeStartup());\n\n        authenticationView.load(configuration.getAuthenticationSettings());\n    }\n\n    @NotNull\n    private ServerConfiguration createServerConfigurationForTesting() {\n        ServerConfiguration configuration = new ServerConfiguration();\n        configuration.setDatabaseVendor(databaseVendor);\n        configuration.setServerUrl(getServerUrls());\n        configuration.setAuthenticationSettings(authenticationView.create());\n        configuration.setUserDatabase(getUserDatabase());\n        return configuration;\n    }\n\n    public void applyConfigurationData(ServerConfiguration configuration) {\n\n        configuration.setLabel(getLabel());\n        configuration.setDatabaseVendor(databaseVendor);\n        configuration.setServerUrl(getServerUrls());\n        configuration.setAuthenticationSettings(authenticationView.create());\n\n        configuration.setUserDatabase(getUserDatabase());\n        configuration.setShellArgumentsLine(getShellArgumentsLine());\n        configuration.setShellWorkingDir(getShellWorkingDir());\n        configuration.setConnectOnIdeStartup(isAutoConnect());\n    }\n\n    public ValidationInfo validateInputs() {\n        if (StringUtils.isEmpty(getLabel())) {\n            return new ValidationInfo(\"Label should be set\");\n        }\n        String serverUrl = getServerUrls();\n        if (serverUrl == null) {\n            return new ValidationInfo(\"URL(s) should be set\");\n        }\n        return null;\n    }\n\n\n    private void validateUrls() {\n        String serverUrl = getServerUrls();\n        if (serverUrl == null) {\n            throw new ConfigurationException(\"URL(s) should be set\");\n        }\n        for (String subServerUrl : serverUrl.split(\",\")) {\n            String[] host_port = subServerUrl.split(\":\");\n            if (host_port.length < 2) {\n                throw new ConfigurationException(String.format(\"URL '%s' format is incorrect. It should be 'host:port'\", subServerUrl));\n            }\n\n            try {\n                Integer.valueOf(host_port[1].trim());\n            } catch (NumberFormatException e) {\n                throw new ConfigurationException(String.format(\"Port in the URL '%s' is incorrect. It should be a number\", subServerUrl));\n            }\n        }\n\n    }\n\n    private String getLabel() {\n        String label = labelField.getText();\n        if (StringUtils.isNotBlank(label)) {\n            return label;\n        }\n        return null;\n    }\n\n    private String getServerUrls() {\n        String serverUrl = serverUrlField.getText();\n        if (StringUtils.isNotBlank(serverUrl)) {\n            return serverUrl;\n        }\n        return null;\n    }\n\n    private String getUserDatabase() {\n        String userDatabase = userDatabaseField.getText();\n        if (StringUtils.isNotBlank(userDatabase)) {\n            return userDatabase;\n        }\n        return null;\n    }\n\n\n    private String getShellArgumentsLine() {\n        String shellArgumentsLine = shellArgumentsLineField.getText();\n        if (StringUtils.isNotBlank(shellArgumentsLine)) {\n            return shellArgumentsLine;\n        }\n\n        return null;\n    }\n\n    private String getShellWorkingDir() {\n        String shellWorkingDir = shellWorkingDirField.getText();\n        if (StringUtils.isNotBlank(shellWorkingDir)) {\n            return shellWorkingDir;\n        }\n\n        return null;\n    }\n\n    private boolean isAutoConnect() {\n        return autoConnectCheckBox.isSelected();\n    }\n\n    private void createUIComponents() {\n        shellWorkingDirField = new TextFieldWithBrowseButton();\n        FileChooserDescriptor fileChooserDescriptor = new FileChooserDescriptor(false, true, false, false, false, false);\n        ComponentWithBrowseButton.BrowseFolderActionListener<JTextField> browseFolderActionListener =\n                new ComponentWithBrowseButton.BrowseFolderActionListener<>(\"Shell working directory\",\n                        null,\n                        shellWorkingDirField,\n                        null,\n                        fileChooserDescriptor,\n                        TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT);\n        shellWorkingDirField.addBrowseFolderListener(null, browseFolderActionListener, false);\n        shellWorkingDirField.setName(\"shellWorkingDirField\");\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/view/ServerConfigurationPanelFactory.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.view;\n\nimport com.intellij.openapi.project.Project;\nimport org.codinjutsu.tools.nosql.DatabaseVendor;\nimport org.codinjutsu.tools.nosql.DatabaseVendorClientManager;\nimport org.codinjutsu.tools.nosql.DatabaseVendorUIManager;\n\npublic class ServerConfigurationPanelFactory {\n\n    private final Project project;\n    private final DatabaseVendorClientManager databaseVendorClientManager;\n    private final DatabaseVendorUIManager databaseVendorUIManager;\n\n    public ServerConfigurationPanelFactory(Project project,\n                                           DatabaseVendorClientManager databaseVendorClientManager,\n                                           DatabaseVendorUIManager databaseVendorUIManager) {\n        this.project = project;\n        this.databaseVendorClientManager = databaseVendorClientManager;\n        this.databaseVendorUIManager = databaseVendorUIManager;\n    }\n\n    public ServerConfigurationPanel create(DatabaseVendor databaseVendor) {\n        return new ServerConfigurationPanel(\n                this.project,\n                databaseVendor,\n                databaseVendorClientManager.get(databaseVendor),\n                databaseVendorUIManager.get(databaseVendor).createAythenticationView()\n        );\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/view/action/ExecuteQuery.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.view.action;\n\nimport com.intellij.icons.AllIcons;\nimport com.intellij.openapi.actionSystem.AnAction;\nimport com.intellij.openapi.actionSystem.AnActionEvent;\nimport org.codinjutsu.tools.nosql.commons.view.NoSqlResultView;\n\nimport java.awt.event.InputEvent;\nimport java.awt.event.KeyEvent;\n\npublic class ExecuteQuery<G extends NoSqlResultView> extends AnAction {\n    private final G resultView;\n\n    public ExecuteQuery(G resultView) {\n        super(\"Execute query\", \"Execute query with options\", AllIcons.Actions.Execute);\n        this.resultView = resultView;\n\n        registerCustomShortcutSet(KeyEvent.VK_ENTER, InputEvent.CTRL_MASK, resultView);\n    }\n\n    @Override\n    public void actionPerformed(AnActionEvent anActionEvent) {\n        resultView.executeQuery();\n    }\n\n    @Override\n    public void update(AnActionEvent event) {\n        event.getPresentation().setEnabled(resultView.getRecords() != null);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/view/action/NoSqlDatabaseConsoleAction.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.view.action;\n\nimport com.intellij.execution.ExecutionException;\nimport com.intellij.openapi.actionSystem.AnAction;\nimport com.intellij.openapi.actionSystem.AnActionEvent;\nimport com.intellij.openapi.actionSystem.PlatformDataKeys;\nimport com.intellij.openapi.project.DumbAware;\nimport com.intellij.openapi.project.Project;\nimport org.apache.commons.lang.StringUtils;\nimport org.codinjutsu.tools.nosql.DatabaseVendor;\nimport org.codinjutsu.tools.nosql.NoSqlConfiguration;\nimport org.codinjutsu.tools.nosql.NoSqlExplorerPanel;\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.codinjutsu.tools.nosql.commons.utils.GuiUtils;\nimport org.codinjutsu.tools.nosql.mongo.view.console.MongoConsoleRunner;\nimport org.codinjutsu.tools.nosql.redis.view.console.RedisConsoleRunner;\n\npublic class NoSqlDatabaseConsoleAction extends AnAction implements DumbAware {\n\n\n    private final NoSqlExplorerPanel noSqlExplorerPanel;\n\n    public NoSqlDatabaseConsoleAction(NoSqlExplorerPanel noSqlExplorerPanel) {\n        super(\"DB Shell...\", \"DB Shell\", GuiUtils.loadIcon(\"toolConsole.png\"));\n        this.noSqlExplorerPanel = noSqlExplorerPanel;\n    }\n\n\n    @Override\n    public void update(AnActionEvent e) {\n        final Project project = e.getData(PlatformDataKeys.PROJECT);\n\n        boolean enabled = project != null;\n        if (!enabled) {\n            return;\n        }\n\n        NoSqlConfiguration configuration = NoSqlConfiguration.getInstance(project);\n\n        e.getPresentation().setVisible(\n                configuration != null &&\n                        (StringUtils.isNotBlank(configuration.getShellPath(DatabaseVendor.MONGO)) ||\n                                StringUtils.isNotBlank(configuration.getShellPath(DatabaseVendor.REDIS))\n                        ) &&\n                        noSqlExplorerPanel.getConfiguration() != null &&\n                        noSqlExplorerPanel.getConfiguration().isSingleServer()\n        );\n        e.getPresentation().setEnabled(\n                noSqlExplorerPanel.getSelectedMongoDatabase() != null ||\n                        noSqlExplorerPanel.getSelectedRedisDatabase() != null\n        );\n    }\n\n    @Override\n    public void actionPerformed(AnActionEvent e) {\n        final Project project = e.getData(PlatformDataKeys.PROJECT);\n        assert project != null;\n\n        runShell(project);\n    }\n\n    private void runShell(Project project) {\n        ServerConfiguration configuration = noSqlExplorerPanel.getConfiguration();\n        if (DatabaseVendor.MONGO.equals(configuration.getDatabaseVendor())) {\n            MongoConsoleRunner consoleRunner = new MongoConsoleRunner(project, configuration, noSqlExplorerPanel.getSelectedMongoDatabase());\n            try {\n                consoleRunner.initAndRun();\n            } catch (ExecutionException e1) {\n                throw new RuntimeException(e1);\n            }\n        } else if (DatabaseVendor.REDIS.equals(configuration.getDatabaseVendor())) {\n            RedisConsoleRunner consoleRunner = new RedisConsoleRunner(project, configuration, noSqlExplorerPanel.getSelectedRedisDatabase());\n            try {\n                consoleRunner.initAndRun();\n            } catch (ExecutionException e1) {\n                throw new RuntimeException(e1);\n            }\n        }\n\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/view/action/OpenPluginSettingsAction.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.view.action;\n\nimport com.intellij.icons.AllIcons;\nimport com.intellij.openapi.actionSystem.AnAction;\nimport com.intellij.openapi.actionSystem.AnActionEvent;\nimport com.intellij.openapi.actionSystem.DataContext;\nimport com.intellij.openapi.actionSystem.PlatformDataKeys;\nimport com.intellij.openapi.options.ShowSettingsUtil;\nimport com.intellij.openapi.project.DumbAware;\nimport com.intellij.openapi.project.Project;\n\npublic class OpenPluginSettingsAction extends AnAction implements DumbAware {\n\n    public OpenPluginSettingsAction() {\n        super(\"NoSql Settings\", \"Edit the NoSql settings for the current project\", AllIcons.General.Settings);\n    }\n\n    @Override\n    public void actionPerformed(AnActionEvent event) {\n        showSettingsFor(getProject(event));\n    }\n\n    private static void showSettingsFor(Project project) {\n        ShowSettingsUtil.getInstance().showSettingsDialog(project, \"NoSql Servers\");\n    }\n\n    private static Project getProject(AnActionEvent event) {\n        DataContext dataContext = event.getDataContext();\n        return PlatformDataKeys.PROJECT.getData(dataContext);\n    }\n}\n\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/view/action/RefreshServerAction.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.view.action;\n\nimport com.intellij.icons.AllIcons;\nimport com.intellij.openapi.actionSystem.AnAction;\nimport com.intellij.openapi.actionSystem.AnActionEvent;\nimport com.intellij.openapi.project.DumbAware;\nimport org.codinjutsu.tools.nosql.NoSqlExplorerPanel;\nimport org.codinjutsu.tools.nosql.commons.utils.GuiUtils;\nimport org.jetbrains.annotations.NotNull;\n\nimport javax.swing.*;\nimport javax.swing.tree.DefaultMutableTreeNode;\n\npublic class RefreshServerAction extends AnAction implements DumbAware {\n\n    private static final Icon CONNECT_ICON = GuiUtils.loadIcon(\"connector.png\", \"connector_dark.png\");\n    private static final Icon REFRESH_ICON = AllIcons.Actions.Refresh;\n    private static final String REFRESH_TEXT = \"Refresh this server\";\n    private static final String CONNECT_TEXT = \"Connect to this server\";\n\n    private final NoSqlExplorerPanel noSqlExplorerPanel;\n\n    public RefreshServerAction(NoSqlExplorerPanel noSqlExplorerPanel) {\n        super(REFRESH_TEXT);\n        this.noSqlExplorerPanel = noSqlExplorerPanel;\n    }\n\n    @Override\n    public void actionPerformed(@NotNull AnActionEvent anActionEvent) {\n        noSqlExplorerPanel.reloadServerConfiguration(noSqlExplorerPanel.getSelectedServerNode(), true);\n    }\n\n    @Override\n    public void update(@NotNull AnActionEvent event) {\n        DefaultMutableTreeNode selectedServerNode = noSqlExplorerPanel.getSelectedServerNode();\n        event.getPresentation().setVisible(selectedServerNode != null);\n        if (selectedServerNode == null) {\n            return;\n        }\n        boolean isConnected = selectedServerNode.getChildCount() > 0;\n        event.getPresentation().setIcon(isConnected ? REFRESH_ICON : CONNECT_ICON);\n        event.getPresentation().setText(isConnected ? REFRESH_TEXT : CONNECT_TEXT);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/view/action/ViewCollectionValuesAction.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.view.action;\n\nimport com.intellij.icons.AllIcons;\nimport com.intellij.openapi.actionSystem.AnAction;\nimport com.intellij.openapi.actionSystem.AnActionEvent;\nimport com.intellij.openapi.project.DumbAware;\nimport org.codinjutsu.tools.nosql.NoSqlExplorerPanel;\n\nimport javax.swing.*;\n\npublic class ViewCollectionValuesAction extends AnAction implements DumbAware {\n\n    private static Icon ICON = AllIcons.Nodes.DataSchema;\n\n    private final NoSqlExplorerPanel noSqlExplorerPanel;\n\n    public ViewCollectionValuesAction(NoSqlExplorerPanel noSqlExplorerPanel) {\n        super(\"View collection content\", \"View collection content\", ICON);\n        this.noSqlExplorerPanel = noSqlExplorerPanel;\n    }\n\n    @Override\n    public void actionPerformed(AnActionEvent anActionEvent) {\n        noSqlExplorerPanel.loadRecords();\n    }\n\n    public void update(AnActionEvent event) {\n        event.getPresentation().setVisible(noSqlExplorerPanel.getSelectedCollection() != null\n                || noSqlExplorerPanel.getSelectedRedisDatabase() != null\n                || noSqlExplorerPanel.getSelectedCouchaseDatabase() != null);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/view/console/NoSqlConsoleView.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.view.console;\n\nimport com.intellij.execution.console.LanguageConsoleImpl;\nimport com.intellij.openapi.fileTypes.StdFileTypes;\nimport com.intellij.openapi.project.Project;\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\n\npublic class NoSqlConsoleView extends LanguageConsoleImpl {\n    public NoSqlConsoleView(Project project, String title, ServerConfiguration configuration) {\n        super(project, title, StdFileTypes.PLAIN_TEXT.getLanguage());\n        setPrompt(String.format(\"%s> \", configuration.getServerUrl()));\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/view/editor/NoSqlDatabaseDataEditor.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.view.editor;\n\nimport com.intellij.codeHighlighting.BackgroundEditorHighlighter;\nimport com.intellij.ide.structureView.StructureViewBuilder;\nimport com.intellij.openapi.application.ApplicationManager;\nimport com.intellij.openapi.fileEditor.FileEditor;\nimport com.intellij.openapi.fileEditor.FileEditorLocation;\nimport com.intellij.openapi.fileEditor.FileEditorState;\nimport com.intellij.openapi.fileEditor.FileEditorStateLevel;\nimport com.intellij.openapi.util.UserDataHolderBase;\nimport org.codinjutsu.tools.nosql.commons.view.NoSqlResultView;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\nimport javax.swing.*;\nimport java.beans.PropertyChangeListener;\n\npublic class NoSqlDatabaseDataEditor extends UserDataHolderBase implements FileEditor {\n\n\n    private NoSqlResultView panel;\n    private boolean disposed;\n\n    public NoSqlDatabaseDataEditor(NoSqlResultView noSqlResultView) {\n        panel = noSqlResultView;\n        ApplicationManager.getApplication().invokeLater(new Runnable() {\n            @Override\n            public void run() {\n                panel.showResults();\n            }\n        });\n    }\n\n    @NotNull\n    @Override\n    public JComponent getComponent() {\n        return isDisposed() ? new JPanel() : panel;\n    }\n\n    @Nullable\n    @Override\n    public JComponent getPreferredFocusedComponent() {\n        return panel == null ? null : panel.getResultPanel();\n    }\n\n    @NotNull\n    @Override\n    public String getName() {\n        return \"NoSql Data\";\n    }\n\n    @Override\n    public void dispose() {\n        if (!disposed) {\n            panel.dispose();\n            panel = null;\n            disposed = true;\n        }\n    }\n\n    public boolean isDisposed() {\n        return disposed;\n    }\n\n    @NotNull\n    @Override\n    public FileEditorState getState(@NotNull FileEditorStateLevel level) {\n        return FileEditorState.INSTANCE;\n    }\n\n//    Unused methods\n\n    @Override\n    public void setState(@NotNull FileEditorState state) {\n\n    }\n\n    @Override\n    public boolean isModified() {\n        return false;\n    }\n\n    @Override\n    public boolean isValid() {\n        return true;\n    }\n\n    @Override\n    public void selectNotify() {\n\n    }\n\n    @Override\n    public void deselectNotify() {\n\n    }\n\n    @Override\n    public void addPropertyChangeListener(@NotNull PropertyChangeListener listener) {\n\n    }\n\n    @Override\n    public void removePropertyChangeListener(@NotNull PropertyChangeListener listener) {\n\n    }\n\n    @Nullable\n    @Override\n    public BackgroundEditorHighlighter getBackgroundHighlighter() {\n        return null;\n    }\n\n    @Nullable\n    @Override\n    public FileEditorLocation getCurrentLocation() {\n        return null;\n    }\n\n    @Nullable\n    @Override\n    public StructureViewBuilder getStructureViewBuilder() {\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/view/editor/NoSqlDatabaseDataEditorProvider.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.view.editor;\n\nimport com.intellij.openapi.components.ApplicationComponent;\nimport com.intellij.openapi.fileEditor.FileEditor;\nimport com.intellij.openapi.fileEditor.FileEditorPolicy;\nimport com.intellij.openapi.fileEditor.FileEditorProvider;\nimport com.intellij.openapi.fileEditor.FileEditorState;\nimport com.intellij.openapi.project.DumbAware;\nimport com.intellij.openapi.project.Project;\nimport com.intellij.openapi.vfs.VirtualFile;\nimport org.codinjutsu.tools.nosql.DatabaseVendorUIManager;\nimport org.codinjutsu.tools.nosql.commons.DatabaseUI;\nimport org.jdom.Element;\nimport org.jetbrains.annotations.NotNull;\n\npublic class NoSqlDatabaseDataEditorProvider implements FileEditorProvider, ApplicationComponent, DumbAware {\n\n\n    @Override\n    public boolean accept(@NotNull Project project, @NotNull VirtualFile file) {\n        return DatabaseVendorUIManager.getInstance(project).accept(file);\n    }\n\n    @NotNull\n    @Override\n    public FileEditor createEditor(@NotNull Project project, @NotNull VirtualFile file) {\n        NoSqlDatabaseObjectFile objectFile = (NoSqlDatabaseObjectFile) file;\n        DatabaseUI databaseUI = DatabaseVendorUIManager.getInstance(project).get(objectFile.getConfiguration().getDatabaseVendor());\n\n        if (databaseUI == null) {\n            throw new IllegalStateException(\"Unsupported file\");\n        }\n        return new NoSqlDatabaseDataEditor(databaseUI.createResultPanel(project, objectFile));\n    }\n\n    @Override\n    public void disposeEditor(@NotNull FileEditor editor) {\n        editor.dispose();\n    }\n\n    @Override\n    public void initComponent() {\n    }\n\n    @Override\n    public void disposeComponent() {\n    }\n\n    @NotNull\n    @Override\n    public FileEditorState readState(@NotNull Element sourceElement, @NotNull Project project, @NotNull VirtualFile file) {\n        return FileEditorState.INSTANCE;\n    }\n\n    @Override\n    public void writeState(@NotNull FileEditorState state, @NotNull Project project, @NotNull Element targetElement) {\n    }\n\n    @NotNull\n    @Override\n    public String getEditorTypeId() {\n        return \"NoSqlData\";\n    }\n\n    @NotNull\n    @Override\n    public FileEditorPolicy getPolicy() {\n        return FileEditorPolicy.HIDE_DEFAULT_EDITOR;\n    }\n\n    @NotNull\n    @Override\n    public String getComponentName() {\n        return \"NoSqlPlugin.NoSqlEditorProvider\";\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/view/editor/NoSqlDatabaseFileSystem.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.view.editor;\n\nimport com.intellij.openapi.application.ApplicationManager;\nimport com.intellij.openapi.components.ApplicationComponent;\nimport com.intellij.openapi.fileEditor.FileEditorManager;\nimport com.intellij.openapi.vfs.VirtualFile;\nimport com.intellij.openapi.vfs.VirtualFileListener;\nimport com.intellij.openapi.vfs.VirtualFileSystem;\nimport org.jetbrains.annotations.NonNls;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\nimport java.io.IOException;\n\npublic class NoSqlDatabaseFileSystem extends VirtualFileSystem implements ApplicationComponent {\n\n    private static final String PROTOCOL = \"nosql\";\n\n    public static NoSqlDatabaseFileSystem getInstance() {\n        return ApplicationManager.getApplication().getComponent(NoSqlDatabaseFileSystem.class);\n    }\n\n    @NotNull\n    @Override\n    public String getComponentName() {\n        return \"NoSqlPlugin.NoSqlDatabaseFileSystem\";\n    }\n\n    @NotNull\n    @Override\n    public String getProtocol() {\n        return PROTOCOL;\n    }\n\n    @Override\n    public void initComponent() {\n\n    }\n\n    @Override\n    public void disposeComponent() {\n\n    }\n\n    public void openEditor(final NoSqlDatabaseObjectFile databaseObjectFile) {\n        FileEditorManager fileEditorManager = FileEditorManager.getInstance(databaseObjectFile.getProject());\n        fileEditorManager.openFile(databaseObjectFile, true);\n    }\n\n//    Unused methods\n\n    @Nullable\n    @Override\n    public VirtualFile findFileByPath(@NotNull @NonNls String path) {\n        return null;\n    }\n\n    @Override\n    public void refresh(boolean asynchronous) {\n\n    }\n\n    @Nullable\n    @Override\n    public VirtualFile refreshAndFindFileByPath(@NotNull String path) {\n        return null;\n    }\n\n    @Override\n    public void addVirtualFileListener(@NotNull VirtualFileListener listener) {\n\n    }\n\n    @Override\n    public void removeVirtualFileListener(@NotNull VirtualFileListener listener) {\n\n    }\n\n    @Override\n    protected void deleteFile(Object requestor, @NotNull VirtualFile vFile) throws IOException {\n\n    }\n\n    @Override\n    protected void moveFile(Object requestor, @NotNull VirtualFile vFile, @NotNull VirtualFile newParent) throws IOException {\n\n    }\n\n    @Override\n    protected void renameFile(Object requestor, @NotNull VirtualFile vFile, @NotNull String newName) throws IOException {\n\n    }\n\n    @Override\n    protected VirtualFile createChildFile(Object requestor, @NotNull VirtualFile vDir, @NotNull String fileName) throws IOException {\n        return null;\n    }\n\n    @NotNull\n    @Override\n    protected VirtualFile createChildDirectory(Object requestor, @NotNull VirtualFile vDir, @NotNull String dirName) throws IOException {\n        throw new UnsupportedOperationException(\"No file management in this plugin\");\n    }\n\n    @Override\n    protected VirtualFile copyFile(Object requestor, @NotNull VirtualFile virtualFile, @NotNull VirtualFile newParent, @NotNull String copyName) throws IOException {\n        return null;\n    }\n\n    @Override\n    public boolean isReadOnly() {\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/view/editor/NoSqlDatabaseObjectFile.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.view.editor;\n\nimport com.intellij.openapi.project.Project;\nimport com.intellij.openapi.vfs.VirtualFile;\nimport com.intellij.openapi.vfs.VirtualFileSystem;\nimport com.intellij.util.LocalTimeCounter;\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\n\npublic abstract class NoSqlDatabaseObjectFile extends VirtualFile {\n\n    private final Project project;\n    private final ServerConfiguration configuration;\n    private final String name;\n    private final long myModStamp;\n\n    protected NoSqlDatabaseObjectFile(Project project, ServerConfiguration configuration, String name) {\n        this.project = project;\n        this.configuration = configuration;\n        this.name = name;\n        this.myModStamp = LocalTimeCounter.currentTime();\n    }\n\n    @NotNull\n    @Override\n    public String getName() {\n        return name;\n    }\n\n    @NotNull\n    @Override\n    public VirtualFileSystem getFileSystem() {\n        return NoSqlDatabaseFileSystem.getInstance();\n    }\n\n    @NotNull\n    @Override\n    public String getPath() {\n        return name;\n    }\n\n    @Override\n    public boolean isValid() {\n        return true;\n    }\n\n    @Override\n    public boolean isWritable() {\n        return false;\n    }\n\n    @Override\n    public boolean isDirectory() {\n        return false;\n    }\n\n    public ServerConfiguration getConfiguration() {\n        return configuration;\n    }\n\n    public Project getProject() {\n        return project;\n    }\n\n    //    Unused methods\n    @Override\n    public VirtualFile getParent() {\n        return null;\n    }\n\n    @Override\n    public VirtualFile[] getChildren() {\n        return new VirtualFile[0];\n    }\n\n    @NotNull\n    @Override\n    public OutputStream getOutputStream(Object requestor, long newModificationStamp, long newTimeStamp) throws IOException {\n        throw new UnsupportedOperationException(\"NoSqlResultFile is read-only\");\n    }\n\n    @Override\n    public long getModificationStamp() {\n        return myModStamp;\n    }\n\n    @NotNull\n    @Override\n    public byte[] contentsToByteArray() throws IOException {\n        return new byte[0];\n    }\n\n    @Override\n    public long getTimeStamp() {\n        return 0;\n    }\n\n    @Override\n    public long getLength() {\n        return 0;\n    }\n\n    @Override\n    public void refresh(boolean asynchronous, boolean recursive, @Nullable Runnable postRunnable) {\n\n    }\n\n    @Override\n    public InputStream getInputStream() throws IOException {\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/view/nodedescriptor/NodeDescriptor.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.view.nodedescriptor;\n\nimport com.intellij.ui.ColoredTableCellRenderer;\nimport com.intellij.ui.ColoredTreeCellRenderer;\n\n\npublic interface NodeDescriptor {\n\n    int MAX_LENGTH = 150;\n\n    void renderValue(ColoredTableCellRenderer cellRenderer, boolean isNodeExpanded);\n\n    void renderNode(ColoredTreeCellRenderer cellRenderer);\n\n    String getFormattedKey();\n\n    String getFormattedValue();\n\n    Object getValue();\n\n    void setValue(Object value);\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/view/renderer/KeyCellRenderer.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.view.renderer;\n\nimport com.intellij.ui.ColoredTreeCellRenderer;\nimport org.codinjutsu.tools.nosql.commons.view.NoSqlTreeNode;\nimport org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor;\nimport org.jetbrains.annotations.NotNull;\n\nimport javax.swing.*;\n\npublic class KeyCellRenderer extends ColoredTreeCellRenderer {\n\n    @Override\n    public void customizeCellRenderer(@NotNull JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {\n        NodeDescriptor descriptor = ((NoSqlTreeNode) value).getDescriptor();\n        descriptor.renderNode(this);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/view/renderer/ValueCellRenderer.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.view.renderer;\n\nimport com.intellij.ui.ColoredTableCellRenderer;\nimport com.intellij.ui.treeStructure.treetable.TreeTable;\nimport com.intellij.ui.treeStructure.treetable.TreeTableTree;\nimport org.codinjutsu.tools.nosql.commons.view.NoSqlTreeNode;\n\nimport javax.swing.*;\nimport javax.swing.tree.TreePath;\n\npublic class ValueCellRenderer extends ColoredTableCellRenderer {\n\n    @Override\n    protected void customizeCellRenderer(JTable table, Object value, boolean selected, boolean hasFocus, int row, int column) {\n\n        TreeTableTree tree = ((TreeTable) table).getTree();\n        TreePath pathForRow = tree.getPathForRow(row);\n\n        final NoSqlTreeNode node = (NoSqlTreeNode) pathForRow.getLastPathComponent();\n\n        node.getDescriptor().renderValue(this, tree.isExpanded(pathForRow));\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/view/table/CellEditor.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.view.table;\n\nimport com.intellij.ui.treeStructure.treetable.TreeTable;\nimport org.codinjutsu.tools.nosql.commons.view.NoSqlTreeNode;\n\nimport javax.swing.*;\nimport java.awt.*;\n\npublic class CellEditor extends DefaultCellEditor {\n\n\n    public CellEditor() {\n        super(new JTextField());\n    }\n\n\n    @Override\n    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {\n        JTextField stringEditor = (JTextField) getComponent();\n        final NoSqlTreeNode jsonNode = (NoSqlTreeNode) ((TreeTable) table).getTree().\n                getPathForRow(row).getLastPathComponent();\n\n        stringEditor.setText(String.valueOf(jsonNode.getDescriptor().getValue()));\n\n        return stringEditor;\n    }\n\n    @Override\n    public Object getCellEditorValue() {\n        return ((JTextField) getComponent()).getText();\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/commons/view/table/DateTimePicker.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * This is licensed under LGPL.  License can be found here:  http://www.gnu.org/licenses/lgpl-3.0.txt\n * <p/>\n * This is provided as is.  If you have questions please direct them to charlie.hubbard at gmail dot you know what.\n */\npackage org.codinjutsu.tools.nosql.commons.view.table;\n\nimport com.intellij.ui.JBColor;\nimport com.intellij.util.ui.UIUtil;\nimport org.codinjutsu.tools.nosql.commons.style.StyleAttributesProvider;\nimport org.codinjutsu.tools.nosql.commons.utils.DateUtils;\nimport org.jdesktop.swingx.JXDatePicker;\nimport org.jdesktop.swingx.JXMonthView;\nimport org.jdesktop.swingx.calendar.SingleDaySelectionModel;\n\nimport javax.swing.*;\nimport javax.swing.text.DateFormatter;\nimport javax.swing.text.DefaultFormatterFactory;\nimport java.awt.*;\nimport java.text.DateFormat;\nimport java.text.ParseException;\nimport java.util.*;\n\n\npublic class DateTimePicker extends JXDatePicker {\n\n    private static Color backgroundColor = JBColor.background();\n    private static Color foregroundColor = JBColor.foreground();\n    private static Color selectionBackgroundColor = UIUtil.getTableSelectionBackground();\n    private static Color selectionForegroundColor = UIUtil.getTableSelectionForeground();\n    private static Color monthForegroundColor = StyleAttributesProvider.NUMBER_COLOR;\n    private static Color dayOfTheWeekForegroundColor = StyleAttributesProvider.KEY_COLOR;\n    private static Color todayBackgroundColor = JBColor.WHITE;\n\n\n    private JSpinner timeSpinner;\n    private JPanel timePanel;\n    private DateFormat timeFormat;\n\n    public static DateTimePicker create() {\n        DateTimePicker dateTimePicker = new DateTimePicker();\n        dateTimePicker.setFormats(DateUtils.utcDateTime(Locale.getDefault()));\n        dateTimePicker.setTimeFormat(DateUtils.utcTime(Locale.getDefault()));\n        dateTimePicker.setTimeZone(TimeZone.getTimeZone(\"UTC\"));\n        dateTimePicker.applyUIStyle();\n\n        return dateTimePicker;\n    }\n\n    private DateTimePicker() {\n        super(null, Locale.getDefault());\n        getMonthView().setSelectionModel(new SingleDaySelectionModel());\n    }\n\n    public void commitEdit() throws ParseException {\n        commitTime();\n        super.commitEdit();\n    }\n\n    public void cancelEdit() {\n        super.cancelEdit();\n        setTimeSpinners();\n    }\n\n    @Override\n    public JPanel getLinkPanel() {\n        super.getLinkPanel();\n        if (timePanel == null) {\n            timePanel = createTimePanel();\n        }\n        setTimeSpinners();\n        return timePanel;\n    }\n\n    @Override\n    public Date getDate() {\n        return super.getDate();\n    }\n\n    private JPanel createTimePanel() {\n        JPanel newPanel = new JPanel();\n        newPanel.setLayout(new FlowLayout());\n\n        SpinnerDateModel dateModel = new SpinnerDateModel();\n        timeSpinner = new JSpinner(dateModel);\n        if (timeFormat == null) timeFormat = DateFormat.getTimeInstance(DateFormat.SHORT);\n        updateTextFieldFormat();\n        newPanel.add(timeSpinner);\n        return newPanel;\n    }\n\n    private void updateTextFieldFormat() {\n        if (timeSpinner == null) return;\n        JFormattedTextField tf = ((JSpinner.DefaultEditor) timeSpinner.getEditor()).getTextField();\n        DefaultFormatterFactory factory = (DefaultFormatterFactory) tf.getFormatterFactory();\n        DateFormatter formatter = (DateFormatter) factory.getDefaultFormatter();\n        // Change the date format to only show the hours\n        formatter.setFormat(timeFormat);\n    }\n\n    private void commitTime() {\n        Date date = getDate();\n        if (date != null) {\n            Date time = (Date) timeSpinner.getValue();\n            GregorianCalendar timeCalendar = new GregorianCalendar();\n            timeCalendar.setTime(time);\n\n            GregorianCalendar calendar = new GregorianCalendar();\n            calendar.setTime(date);\n            calendar.set(Calendar.HOUR_OF_DAY, timeCalendar.get(Calendar.HOUR_OF_DAY));\n            calendar.set(Calendar.MINUTE, timeCalendar.get(Calendar.MINUTE));\n            calendar.set(Calendar.SECOND, timeCalendar.get(Calendar.SECOND));\n            calendar.set(Calendar.MILLISECOND, 0);\n\n            Date newDate = calendar.getTime();\n            setDate(newDate);\n        }\n    }\n\n    private void setTimeSpinners() {\n        Date date = getDate();\n        if (date != null) {\n            timeSpinner.setValue(date);\n        }\n    }\n\n    public void setTimeFormat(DateFormat timeFormat) {\n        this.timeFormat = timeFormat;\n        updateTextFieldFormat();\n    }\n\n    private void applyUIStyle() {\n        JXMonthView monthView = getMonthView();\n        monthView.setMonthStringBackground(backgroundColor);\n        monthView.setMonthStringForeground(monthForegroundColor);\n        monthView.setSelectionBackground(selectionBackgroundColor);\n        monthView.setSelectionForeground(selectionForegroundColor);\n        monthView.setDaysOfTheWeekForeground(dayOfTheWeekForegroundColor);\n        monthView.setBackground(backgroundColor);\n        monthView.setForeground(foregroundColor);\n        monthView.setTodayBackground(todayBackgroundColor);\n\n        getLinkPanel().setBackground(backgroundColor);\n        getLinkPanel().setForeground(foregroundColor);\n    }\n\n\n    public static void main(String[] args) {\n        String[] ids = TimeZone.getAvailableIDs();\n        for (String id : ids) {\n            if (!id.startsWith(\"Etc\")) {\n                TimeZone zone = TimeZone.getTimeZone(id);\n                int offset = zone.getRawOffset() / 1000;\n                int hour = offset / 3600;\n                int minutes = (offset % 3600) / 60;\n                System.out.println(String.format(\"(GMT%+d:%02d) %s\", hour, minutes, id));\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/couchbase/CouchbaseUI.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.couchbase;\n\nimport com.intellij.openapi.project.Project;\nimport org.codinjutsu.tools.nosql.commons.DatabaseUI;\nimport org.codinjutsu.tools.nosql.commons.view.AuthenticationView;\nimport org.codinjutsu.tools.nosql.commons.view.NoSqlResultView;\nimport org.codinjutsu.tools.nosql.commons.view.editor.NoSqlDatabaseObjectFile;\nimport org.codinjutsu.tools.nosql.couchbase.logic.CouchbaseClient;\nimport org.codinjutsu.tools.nosql.couchbase.view.CouchbaseAuthenticationPanel;\nimport org.codinjutsu.tools.nosql.couchbase.view.CouchbasePanel;\nimport org.codinjutsu.tools.nosql.couchbase.view.editor.CouchbaseObjectFile;\n\npublic class CouchbaseUI implements DatabaseUI {\n    @Override\n    public AuthenticationView createAythenticationView() {\n        return new CouchbaseAuthenticationPanel();\n    }\n\n    @Override\n    public NoSqlResultView createResultPanel(Project project, NoSqlDatabaseObjectFile objectFile) {\n        CouchbaseObjectFile couchbaseObjectFile = (CouchbaseObjectFile) objectFile;\n        return new CouchbasePanel(project, CouchbaseClient.getInstance(project), couchbaseObjectFile.getConfiguration(), couchbaseObjectFile.getDatabase());\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/couchbase/logic/CouchbaseClient.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.couchbase.logic;\n\nimport com.couchbase.client.java.Bucket;\nimport com.couchbase.client.java.Cluster;\nimport com.couchbase.client.java.ConnectionString;\nimport com.couchbase.client.java.CouchbaseCluster;\nimport com.couchbase.client.java.cluster.BucketSettings;\nimport com.couchbase.client.java.cluster.ClusterManager;\nimport com.couchbase.client.java.document.json.JsonObject;\nimport com.couchbase.client.java.env.DefaultCouchbaseEnvironment;\nimport com.couchbase.client.java.query.N1qlQuery;\nimport com.couchbase.client.java.query.N1qlQueryResult;\nimport com.couchbase.client.java.query.N1qlQueryRow;\nimport com.intellij.openapi.components.ServiceManager;\nimport com.intellij.openapi.project.Project;\nimport org.apache.commons.lang.StringUtils;\nimport org.apache.log4j.Logger;\nimport org.codinjutsu.tools.nosql.DatabaseVendor;\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.codinjutsu.tools.nosql.commons.logic.ConfigurationException;\nimport org.codinjutsu.tools.nosql.commons.logic.DatabaseClient;\nimport org.codinjutsu.tools.nosql.commons.model.AuthenticationSettings;\nimport org.codinjutsu.tools.nosql.commons.model.Database;\nimport org.codinjutsu.tools.nosql.commons.model.DatabaseServer;\nimport org.codinjutsu.tools.nosql.couchbase.model.CouchbaseDatabase;\nimport org.codinjutsu.tools.nosql.couchbase.model.CouchbaseQuery;\nimport org.codinjutsu.tools.nosql.couchbase.model.CouchbaseResult;\n\nimport java.util.Arrays;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.concurrent.TimeUnit;\n\nimport static com.couchbase.client.java.query.Select.select;\nimport static com.couchbase.client.java.query.dsl.Expression.i;\n\npublic class CouchbaseClient implements DatabaseClient {\n\n    public static CouchbaseClient getInstance(Project project) {\n        return ServiceManager.getService(project, CouchbaseClient.class);\n    }\n\n    @Override\n    public void connect(ServerConfiguration serverConfiguration) {\n        CouchbaseCluster cluster = CouchbaseCluster.create(serverConfiguration.getServerUrl());\n        String userDatabase = serverConfiguration.getUserDatabase();\n        Bucket bucket = null;\n        try {\n            if (StringUtils.isEmpty(userDatabase)) {\n                bucket = cluster.openBucket();\n            } else {\n                bucket = cluster.openBucket(userDatabase);\n            }\n\n        } catch (Exception ex) {\n            throw new ConfigurationException(ex);\n        } finally {\n            if (bucket != null) {\n                bucket.close();\n            }\n            cluster.disconnect();\n        }\n\n    }\n\n    @Override\n    public void loadServer(DatabaseServer databaseServer) {\n        Cluster cluster = CouchbaseCluster.create(databaseServer.getConfiguration().getServerUrl());\n        AuthenticationSettings authenticationSettings = databaseServer.getConfiguration().getAuthenticationSettings();\n        ClusterManager clusterManager = cluster.clusterManager(authenticationSettings.getUsername(), authenticationSettings.getPassword());\n\n        List<Database> couchbaseDatabases = new LinkedList<>();\n        String userBucket = databaseServer.getConfiguration().getUserDatabase();\n        if (StringUtils.isNotBlank(userBucket)) {\n            BucketSettings bucketSettings = clusterManager.getBucket(userBucket);\n            couchbaseDatabases.add(new CouchbaseDatabase(bucketSettings.name()));\n        } else {\n            List<BucketSettings> buckets = clusterManager.getBuckets();\n\n            for (BucketSettings bucketSettings : buckets) {\n                CouchbaseDatabase database = new CouchbaseDatabase(bucketSettings.name());\n                couchbaseDatabases.add(database);\n            }\n        }\n\n        databaseServer.setDatabases(couchbaseDatabases);\n\n        cluster.disconnect();\n    }\n\n    @Override\n    public void cleanUpServers() {\n\n    }\n\n    @Override\n    public void registerServer(DatabaseServer databaseServer) {\n\n    }\n\n    @Override\n    public ServerConfiguration defaultConfiguration() {\n        ServerConfiguration configuration = new ServerConfiguration();\n        configuration.setDatabaseVendor(DatabaseVendor.COUCHBASE);\n        configuration.setServerUrl(\"localhost\");\n        configuration.setAuthenticationSettings(new AuthenticationSettings());\n        return configuration;\n    }\n\n    public CouchbaseResult loadRecords(ServerConfiguration configuration, CouchbaseDatabase database, CouchbaseQuery couchbaseQuery) {\n        Cluster cluster = CouchbaseCluster.create(DefaultCouchbaseEnvironment\n                .builder()\n                .queryEnabled(true)\n                .build(),\n                configuration.getServerUrl());\n//        AuthenticationSettings authenticationSettings = configuration.getAuthenticationSettings();\n//        ClusterManager clusterManager = cluster.clusterManager(authenticationSettings.getUsername(), authenticationSettings.getPassword());\n\n        Bucket beerBucket = cluster.openBucket(database.getName(), 10, TimeUnit.SECONDS);\n        N1qlQueryResult queryResult = beerBucket.query(N1qlQuery.simple(select(\"*\").from(i(database.getName())).limit(couchbaseQuery.getLimit())));\n\n//TODO dirty zone :(\n        CouchbaseResult result = new CouchbaseResult(database.getName());\n        List<JsonObject> errors = queryResult.errors();\n        if (!errors.isEmpty()) {\n            cluster.disconnect();\n            result.addErrors(errors);\n            return result;\n        }\n\n        for (N1qlQueryRow row : queryResult.allRows()) {\n            result.add(row.value());\n        }\n        cluster.disconnect();\n        return result;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/couchbase/model/CouchbaseDatabase.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.couchbase.model;\n\nimport org.codinjutsu.tools.nosql.commons.model.Database;\n\npublic class CouchbaseDatabase extends Database {\n\n    public CouchbaseDatabase(String name) {\n        super(name);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/couchbase/model/CouchbaseQuery.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.couchbase.model;\n\npublic class CouchbaseQuery {\n\n    private final int limit;\n\n    public CouchbaseQuery(int limit) {\n        this.limit = limit;\n    }\n\n    public int getLimit() {\n        return limit;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/couchbase/model/CouchbaseResult.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.couchbase.model;\n\nimport com.couchbase.client.java.document.json.JsonObject;\n\nimport java.util.LinkedList;\nimport java.util.List;\n\npublic class CouchbaseResult {\n    private final List<JsonObject> jsonObjects = new LinkedList<>();\n    private final List<JsonObject> errors = new LinkedList<>();\n    private final String name;\n\n    public CouchbaseResult(String name) {\n        this.name = name;\n    }\n\n    public void add(JsonObject jsonObject) {\n        this.jsonObjects.add(jsonObject);\n    }\n\n    public void addErrors(List<JsonObject> errors) {\n        this.errors.addAll(errors);\n    }\n\n    public String getName() {\n        return null;\n    }\n\n    public List<JsonObject> getRecords() {\n        return jsonObjects;\n    }\n\n    public boolean hasErrors() {\n        return !errors.isEmpty();\n    }\n\n    public List<JsonObject> getErrors() {\n        return errors;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/couchbase/view/CouchbaseAuthenticationPanel.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.couchbase.view;\n\nimport org.apache.commons.lang.StringUtils;\nimport org.codinjutsu.tools.nosql.commons.model.AuthenticationSettings;\nimport org.codinjutsu.tools.nosql.commons.view.AuthenticationView;\n\nimport javax.swing.*;\n\npublic class CouchbaseAuthenticationPanel implements AuthenticationView {\n\n    private JTextField usernameField;\n    private JPasswordField passwordField;\n    private JPanel mainPanel;\n\n    public CouchbaseAuthenticationPanel() {\n        usernameField.setName(\"usernameField\");\n        passwordField.setName(\"passwordField\");\n    }\n\n    @Override\n    public JPanel getComponent() {\n        return mainPanel;\n    }\n\n    @Override\n    public AuthenticationSettings create() {\n        AuthenticationSettings authenticationSettings = new AuthenticationSettings();\n        authenticationSettings.setUsername(getUsername());\n        authenticationSettings.setPassword(getPassword());\n        return authenticationSettings;\n    }\n\n    @Override\n    public void load(AuthenticationSettings settings) {\n        usernameField.setText(settings.getUsername());\n        passwordField.setText(settings.getPassword());\n    }\n\n    private String getUsername() {\n        String username = usernameField.getText();\n        if (StringUtils.isNotBlank(username)) {\n            return username;\n        }\n        return null;\n    }\n\n    private String getPassword() {\n        char[] password = passwordField.getPassword();\n        if (password != null && password.length != 0) {\n            return String.valueOf(password);\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/couchbase/view/CouchbasePanel.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<form xmlns=\"http://www.intellij.com/uidesigner/form/\" version=\"1\" bind-to-class=\"org.codinjutsu.tools.nosql.couchbase.view.CouchbasePanel\">\n  <grid id=\"27dc6\" binding=\"mainPanel\" layout-manager=\"GridLayoutManager\" row-count=\"3\" column-count=\"1\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n    <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n    <constraints>\n      <xy x=\"20\" y=\"20\" width=\"500\" height=\"400\"/>\n    </constraints>\n    <properties/>\n    <border type=\"none\"/>\n    <children>\n      <grid id=\"34871\" binding=\"containerPanel\" layout-manager=\"BorderLayout\" hgap=\"0\" vgap=\"0\">\n        <constraints>\n          <grid row=\"1\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n        <border type=\"none\"/>\n        <children/>\n      </grid>\n      <grid id=\"9469e\" binding=\"toolBarPanel\" layout-manager=\"GridLayoutManager\" row-count=\"1\" column-count=\"1\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n        <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n        <constraints>\n          <grid row=\"0\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n        <border type=\"none\"/>\n        <children/>\n      </grid>\n      <grid id=\"70bed\" binding=\"errorPanel\" layout-manager=\"BorderLayout\" hgap=\"0\" vgap=\"0\">\n        <constraints>\n          <grid row=\"2\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n        <border type=\"none\"/>\n        <children/>\n      </grid>\n    </children>\n  </grid>\n</form>\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/couchbase/view/CouchbasePanel.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.couchbase.view;\n\nimport com.intellij.icons.AllIcons;\nimport com.intellij.ide.CommonActionsManager;\nimport com.intellij.ide.TreeExpander;\nimport com.intellij.openapi.Disposable;\nimport com.intellij.openapi.actionSystem.ActionManager;\nimport com.intellij.openapi.actionSystem.ActionToolbar;\nimport com.intellij.openapi.actionSystem.AnAction;\nimport com.intellij.openapi.actionSystem.DefaultActionGroup;\nimport com.intellij.openapi.progress.ProgressIndicator;\nimport com.intellij.openapi.progress.ProgressManager;\nimport com.intellij.openapi.progress.Task;\nimport com.intellij.openapi.project.Project;\nimport com.intellij.openapi.ui.LoadingDecorator;\nimport com.intellij.openapi.util.Disposer;\nimport com.intellij.ui.NumberDocument;\nimport com.intellij.ui.components.JBLabel;\nimport com.intellij.ui.components.JBScrollPane;\nimport com.intellij.ui.components.panels.NonOpaquePanel;\nimport com.intellij.ui.treeStructure.treetable.TreeTableTree;\nimport com.intellij.util.ui.UIUtil;\nimport com.intellij.util.ui.tree.TreeUtil;\nimport org.apache.commons.lang.StringUtils;\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.codinjutsu.tools.nosql.commons.utils.GuiUtils;\nimport org.codinjutsu.tools.nosql.commons.view.ErrorPanel;\nimport org.codinjutsu.tools.nosql.commons.view.NoSqlResultView;\nimport org.codinjutsu.tools.nosql.commons.view.NoSqlTreeNode;\nimport org.codinjutsu.tools.nosql.commons.view.action.ExecuteQuery;\nimport org.codinjutsu.tools.nosql.couchbase.logic.CouchbaseClient;\nimport org.codinjutsu.tools.nosql.couchbase.model.CouchbaseDatabase;\nimport org.codinjutsu.tools.nosql.couchbase.model.CouchbaseQuery;\nimport org.codinjutsu.tools.nosql.couchbase.model.CouchbaseResult;\nimport org.codinjutsu.tools.nosql.mongo.view.JsonTreeTableView;\nimport org.jetbrains.annotations.NotNull;\n\nimport javax.swing.*;\nimport java.awt.*;\n\npublic class CouchbasePanel extends NoSqlResultView<CouchbaseDatabase> {\n    private JPanel mainPanel;\n    private JPanel toolBarPanel;\n    private JPanel containerPanel;\n    private JPanel errorPanel;\n    private JPanel resultPanel;\n    private final LoadingDecorator loadingDecorator;\n    private final JTextField rowLimitField = new JTextField(\"\");\n\n    private final Project project;\n\n    private final CouchbaseClient couchbaseClient;\n    private final ServerConfiguration configuration;\n    private final CouchbaseDatabase database;\n    private CouchbaseResult couchbaseResult;\n    private JsonTreeTableView resultTableView;\n\n\n    public CouchbasePanel(Project project, CouchbaseClient couchbaseClient, ServerConfiguration configuration, CouchbaseDatabase database) {\n        this.project = project;\n        this.couchbaseClient = couchbaseClient;\n        this.configuration = configuration;\n        this.database = database;\n        this.resultPanel = new JPanel(new BorderLayout());\n\n        loadingDecorator = new LoadingDecorator(resultPanel, this, 0);\n\n        containerPanel.add(loadingDecorator.getComponent());\n\n        initToolbar();\n\n        setLayout(new BorderLayout());\n        add(mainPanel);\n    }\n\n    private void loadAndDisplayResults(final int limit) throws Exception {\n        couchbaseResult = couchbaseClient.loadRecords(configuration, database, new CouchbaseQuery(limit));\n        if (couchbaseResult.hasErrors()) {\n            throw new Exception(StringUtils.join(couchbaseResult.getErrors(), \" \")); //TODO need to improve it\n        }\n        updateResultTableTree(couchbaseResult);\n    }\n\n    void updateResultTableTree(CouchbaseResult couchbaseResult) {\n        NoSqlTreeNode rootNode = CouchbaseTreeModel.buildTree(couchbaseResult);\n        resultTableView = new JsonTreeTableView(rootNode, JsonTreeTableView.COLUMNS_FOR_READING);\n        resultTableView.setName(\"resultTreeTable\");\n\n        resultPanel.invalidate();\n        resultPanel.removeAll();\n        resultPanel.add(new JBScrollPane(resultTableView));\n        resultPanel.validate();\n    }\n\n    private void initToolbar() {\n        toolBarPanel.setLayout(new BorderLayout());\n\n        rowLimitField.setColumns(5);\n        rowLimitField.setDocument(new NumberDocument());\n        rowLimitField.setText(\"100\");\n\n        JPanel rowLimitPanel = new NonOpaquePanel();\n        rowLimitPanel.add(new JLabel(\"Row limit:\"), BorderLayout.WEST);\n        rowLimitPanel.add(rowLimitField, BorderLayout.CENTER);\n        rowLimitPanel.add(Box.createHorizontalStrut(5), BorderLayout.EAST);\n        toolBarPanel.add(rowLimitPanel, BorderLayout.WEST);\n\n        addCommonsActions();\n    }\n\n    protected void addCommonsActions() {\n        final TreeExpander treeExpander = new TreeExpander() {\n            @Override\n            public void expandAll() {\n                CouchbasePanel.this.expandAll();\n            }\n\n            @Override\n            public boolean canExpand() {\n                return true;\n            }\n\n            @Override\n            public void collapseAll() {\n                CouchbasePanel.this.collapseAll();\n            }\n\n            @Override\n            public boolean canCollapse() {\n                return true;\n            }\n        };\n\n        CommonActionsManager actionsManager = CommonActionsManager.getInstance();\n\n        final AnAction expandAllAction = actionsManager.createExpandAllAction(treeExpander, resultPanel);\n        final AnAction collapseAllAction = actionsManager.createCollapseAllAction(treeExpander, resultPanel);\n\n        Disposer.register(this, new Disposable() {\n            @Override\n            public void dispose() {\n                collapseAllAction.unregisterCustomShortcutSet(resultPanel);\n                expandAllAction.unregisterCustomShortcutSet(resultPanel);\n            }\n        });\n\n        DefaultActionGroup actionResultGroup = new DefaultActionGroup(\"CouchbaseResultGroup\", true);\n        actionResultGroup.add(new ExecuteQuery<>(this));\n        actionResultGroup.addSeparator();\n        actionResultGroup.add(expandAllAction);\n        actionResultGroup.add(collapseAllAction);\n\n        ActionToolbar actionToolBar = ActionManager.getInstance().createActionToolbar(\"CouchbaseResultGroupActions\", actionResultGroup, true);\n        actionToolBar.setLayoutPolicy(ActionToolbar.AUTO_LAYOUT_POLICY);\n        JComponent actionToolBarComponent = actionToolBar.getComponent();\n        actionToolBarComponent.setBorder(null);\n        actionToolBarComponent.setOpaque(false);\n\n        toolBarPanel.add(actionToolBarComponent, BorderLayout.CENTER);\n    }\n\n\n    private int getLimit() {\n        return Integer.parseInt(rowLimitField.getText());\n    }\n\n    void expandAll() {\n        TreeUtil.expandAll(resultTableView.getTree());\n    }\n\n    void collapseAll() {\n        TreeTableTree tree = resultTableView.getTree();\n        TreeUtil.collapseAll(tree, 1);\n    }\n\n    @Override\n    public void showResults() {\n        executeQuery();\n    }\n\n    @Override\n    public JPanel getResultPanel() {\n        return resultPanel;\n    }\n\n    @Override\n    public CouchbaseDatabase getRecords() {\n        return database;\n    }\n\n    @Override\n    public void executeQuery() {\n        ProgressManager.getInstance().run(new Task.Backgroundable(project, \"Executing query\", true)  { //TODO need to abstract this method\n            @Override\n            public void run(@NotNull final ProgressIndicator indicator) {\n                try {\n                    loadAndDisplayResults(getLimit());\n                }  catch (final Exception ex) {\n                    GuiUtils.runInSwingThread(new Runnable() {\n                        @Override\n                        public void run() {\n                            errorPanel.invalidate();\n                            errorPanel.removeAll();\n                            errorPanel.add(new ErrorPanel(ex), BorderLayout.CENTER);\n                            errorPanel.validate();\n                            errorPanel.setVisible(true);\n                        }\n                    });\n                } finally {\n                    GuiUtils.runInSwingThread(new Runnable() {\n                        @Override\n                        public void run() {\n                            loadingDecorator.stopLoading();\n                        }\n                    });\n                }\n            }\n        });\n\n    }\n\n    @Override\n    public void dispose() {\n\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/couchbase/view/CouchbaseTreeModel.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.couchbase.view;\n\nimport com.couchbase.client.java.document.json.JsonArray;\nimport com.couchbase.client.java.document.json.JsonObject;\nimport org.codinjutsu.tools.nosql.commons.view.NoSqlTreeNode;\nimport org.codinjutsu.tools.nosql.couchbase.model.CouchbaseResult;\nimport org.codinjutsu.tools.nosql.couchbase.view.nodedescriptor.CouchbaseKeyValueDescriptor;\nimport org.codinjutsu.tools.nosql.couchbase.view.nodedescriptor.CouchbaseResultDescriptor;\nimport org.codinjutsu.tools.nosql.couchbase.view.nodedescriptor.CouchbaseValueDescriptor;\n\nimport javax.swing.tree.DefaultTreeModel;\n\npublic class CouchbaseTreeModel extends DefaultTreeModel {\n    public CouchbaseTreeModel(CouchbaseResult result) {\n        super(buildTree(result));\n    }\n\n    public static NoSqlTreeNode buildTree(CouchbaseResult couchbaseResult) {\n        NoSqlTreeNode resultTreeNode = new NoSqlTreeNode(new CouchbaseResultDescriptor(couchbaseResult.getName()));\n        for (JsonObject record : couchbaseResult.getRecords()) {\n            processRecord(resultTreeNode, record);\n        }\n\n        return resultTreeNode;\n    }\n\n    private static void processRecord(NoSqlTreeNode parentNode, JsonObject record) {\n        for (String key : record.getNames()) {\n            Object value = record.get(key);\n            NoSqlTreeNode currentNode = new NoSqlTreeNode(CouchbaseKeyValueDescriptor.createDescriptor(key, value));\n            if (value instanceof JsonArray) {\n                processRecordListValues(currentNode, (JsonArray) value);\n            } else if (value instanceof JsonObject) {\n                processRecord(currentNode, (JsonObject) value);\n            }\n\n            parentNode.add(currentNode);\n        }\n    }\n\n    private static void processRecordListValues(NoSqlTreeNode parentNode, JsonArray values) {\n        int index = 0;\n        for (Object value : values) {\n            NoSqlTreeNode currentValueNode = new NoSqlTreeNode(CouchbaseValueDescriptor.createDescriptor(index++, value));\n            if (value instanceof JsonArray) {\n                processRecordListValues(currentValueNode, (JsonArray) value);\n            } else if (value instanceof JsonObject) {\n                processRecord(currentValueNode, (JsonObject) value);\n            }\n            parentNode.add(currentValueNode);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/couchbase/view/couchbaseAuthenticationPanel.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<form xmlns=\"http://www.intellij.com/uidesigner/form/\" version=\"1\" bind-to-class=\"org.codinjutsu.tools.nosql.couchbase.view.CouchbaseAuthenticationPanel\">\n  <grid id=\"27dc6\" binding=\"mainPanel\" layout-manager=\"GridLayoutManager\" row-count=\"3\" column-count=\"2\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n    <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n    <constraints>\n      <xy x=\"20\" y=\"20\" width=\"554\" height=\"400\"/>\n    </constraints>\n    <properties/>\n    <border type=\"none\"/>\n    <children>\n      <component id=\"e1614\" class=\"javax.swing.JLabel\">\n        <constraints>\n          <grid row=\"0\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties>\n          <text value=\"Username:\"/>\n        </properties>\n      </component>\n      <component id=\"2422c\" class=\"javax.swing.JTextField\" binding=\"usernameField\">\n        <constraints>\n          <grid row=\"0\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"6\" anchor=\"8\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties>\n          <editable value=\"true\"/>\n          <enabled value=\"true\"/>\n        </properties>\n      </component>\n      <component id=\"3d63b\" class=\"javax.swing.JLabel\">\n        <constraints>\n          <grid row=\"1\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties>\n          <text value=\"Password:\"/>\n        </properties>\n      </component>\n      <component id=\"ca1e9\" class=\"javax.swing.JPasswordField\" binding=\"passwordField\">\n        <constraints>\n          <grid row=\"1\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"6\" anchor=\"8\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\">\n            <preferred-size width=\"150\" height=\"-1\"/>\n          </grid>\n        </constraints>\n        <properties/>\n      </component>\n      <vspacer id=\"498d2\">\n        <constraints>\n          <grid row=\"2\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"6\" hsize-policy=\"1\" anchor=\"0\" fill=\"2\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n      </vspacer>\n    </children>\n  </grid>\n</form>\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/couchbase/view/editor/CouchbaseFakeFileType.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.couchbase.view.editor;\n\nimport com.intellij.openapi.fileTypes.FileType;\nimport com.intellij.openapi.fileTypes.ex.FakeFileType;\nimport com.intellij.openapi.vfs.VirtualFile;\nimport org.codinjutsu.tools.nosql.commons.utils.GuiUtils;\nimport org.jetbrains.annotations.NotNull;\n\nimport javax.swing.*;\n\npublic class CouchbaseFakeFileType extends FakeFileType {\n\n    private static final Icon ICON = GuiUtils.loadIcon(\"couchbase.png\");\n    private static final String NAME = \"COUCHBASE\";\n\n    public static final FileType INSTANCE = new CouchbaseFakeFileType();\n\n\n    @Override\n    public Icon getIcon() {\n        return ICON;\n    }\n\n    @Override\n    public boolean isMyFileType(VirtualFile file) {\n        return false;\n    }\n\n    @NotNull\n    @Override\n    public String getDefaultExtension() {\n        return \"json\";\n    }\n\n    @NotNull\n    @Override\n    public String getName() {\n        return NAME;\n    }\n\n    @NotNull\n    @Override\n    public String getDescription() {\n        return NAME;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/couchbase/view/editor/CouchbaseObjectFile.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.couchbase.view.editor;\n\nimport com.intellij.openapi.fileTypes.FileType;\nimport com.intellij.openapi.project.Project;\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.codinjutsu.tools.nosql.commons.view.editor.NoSqlDatabaseObjectFile;\nimport org.codinjutsu.tools.nosql.couchbase.model.CouchbaseDatabase;\nimport org.jetbrains.annotations.NotNull;\n\npublic class CouchbaseObjectFile extends NoSqlDatabaseObjectFile {\n    private final CouchbaseDatabase couchbaseDatabase;\n\n    public CouchbaseObjectFile(Project project, ServerConfiguration configuration, CouchbaseDatabase database) {\n        super(project, configuration, String.format(\"%s/%s\", configuration.getLabel(), database.getName()));\n        this.couchbaseDatabase = database;\n    }\n\n    @NotNull\n    public FileType getFileType() {\n        return CouchbaseFakeFileType.INSTANCE;\n    }\n\n    public CouchbaseDatabase getDatabase() {\n        return couchbaseDatabase;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/couchbase/view/nodedescriptor/CouchbaseKeyValueDescriptor.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.couchbase.view.nodedescriptor;\n\nimport com.couchbase.client.java.document.json.JsonArray;\nimport com.couchbase.client.java.document.json.JsonObject;\nimport com.intellij.ui.ColoredTableCellRenderer;\nimport com.intellij.ui.ColoredTreeCellRenderer;\nimport com.intellij.ui.SimpleTextAttributes;\nimport org.codinjutsu.tools.nosql.commons.style.StyleAttributesProvider;\nimport org.codinjutsu.tools.nosql.commons.utils.StringUtils;\nimport org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor;\n\npublic class CouchbaseKeyValueDescriptor implements NodeDescriptor {\n\n    protected static final String TO_STRING_TEMPLATE = \"\\\"%s\\\" : %s\";\n\n\n    protected final String key;\n    protected final Object value;\n\n    private final SimpleTextAttributes valueTextAttributes;\n\n    public static CouchbaseKeyValueDescriptor createDescriptor(String key, Object value) {\n        if (value == null) {\n            return new CouchbaseKeyNullValueDescriptor(key);\n        }\n        if (value instanceof String) {\n            return new CouchbaseKeyStringValueDescriptor(key, (String) value);\n        }\n\n\n        SimpleTextAttributes textAttributes = StyleAttributesProvider.getStringAttribute();\n        if (value instanceof Boolean) {\n            textAttributes = StyleAttributesProvider.getBooleanAttribute();\n        } else if (value instanceof Number) {\n            textAttributes = StyleAttributesProvider.getNumberAttribute();\n        } else if (value instanceof JsonObject || value instanceof JsonArray) {\n            textAttributes = StyleAttributesProvider.getObjectAttribute();\n        }\n        return new CouchbaseKeyValueDescriptor(key, value, textAttributes);\n    }\n\n    private CouchbaseKeyValueDescriptor(String key, Object value, SimpleTextAttributes valueTextAttributes) {\n        this.key = key;\n        this.value = value;\n        this.valueTextAttributes = valueTextAttributes;\n    }\n\n\n    public void renderValue(ColoredTableCellRenderer cellRenderer, boolean isNodeExpanded) {\n        if (!isNodeExpanded) {\n            cellRenderer.append(getValueAndAbbreviateIfNecessary(), valueTextAttributes);\n        }\n    }\n\n    public void renderNode(ColoredTreeCellRenderer cellRenderer) {\n        cellRenderer.append(getFormattedKey(), StyleAttributesProvider.getKeyValueAttribute());\n    }\n\n    public String getFormattedKey() {\n        return key;\n    }\n\n    public String getFormattedValue() {\n        return getValueAndAbbreviateIfNecessary();\n    }\n\n    public String getKey() {\n        return key;\n    }\n\n    public Object getValue() {\n        return value;\n    }\n\n    public void setValue(Object value) {\n\n    }\n\n    @Override\n    public String toString() {\n        return String.format(TO_STRING_TEMPLATE, key, value);\n    }\n\n    protected String getValueAndAbbreviateIfNecessary() {\n        String stringifiedValue = value.toString();\n        if (stringifiedValue.length() > MAX_LENGTH) {\n            return StringUtils.abbreviateInCenter(stringifiedValue, MAX_LENGTH);\n        }\n        return stringifiedValue;\n    }\n\n    private static class CouchbaseKeyNullValueDescriptor extends CouchbaseKeyValueDescriptor {\n\n        private CouchbaseKeyNullValueDescriptor(String key) {\n            super(key, null, StyleAttributesProvider.getNullAttribute());\n        }\n\n        protected String getValueAndAbbreviateIfNecessary() {\n            return \"null\";\n        }\n    }\n\n    private static class CouchbaseKeyStringValueDescriptor extends CouchbaseKeyValueDescriptor {\n\n        private static final String STRING_SURROUNDED = \"\\\"%s\\\"\";\n        private static final String TO_STRING_FOR_STRING_VALUE_TEMPLATE = \"\\\"%s\\\" : \\\"%s\\\"\";\n\n        private CouchbaseKeyStringValueDescriptor(String key, String value) {\n            super(key, value, StyleAttributesProvider.getStringAttribute());\n        }\n\n        @Override\n        protected String getValueAndAbbreviateIfNecessary() {\n            return String.format(STRING_SURROUNDED, value);\n        }\n\n        @Override\n        public String toString() {\n            return String.format(TO_STRING_FOR_STRING_VALUE_TEMPLATE, key, value);\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/couchbase/view/nodedescriptor/CouchbaseResultDescriptor.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.couchbase.view.nodedescriptor;\n\nimport com.intellij.ui.ColoredTableCellRenderer;\nimport com.intellij.ui.ColoredTreeCellRenderer;\nimport org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor;\n\npublic class CouchbaseResultDescriptor implements NodeDescriptor {\n\n    private final String formattedText;\n\n    public CouchbaseResultDescriptor(String collectionName) {\n        formattedText = String.format(\"results of '%s'\", collectionName);\n    }\n\n    public CouchbaseResultDescriptor() {\n        this(\"\");\n    }\n\n    public void renderValue(ColoredTableCellRenderer cellRenderer, boolean isNodeExpanded) {\n    }\n\n    public void renderNode(ColoredTreeCellRenderer cellRenderer) {\n\n    }\n\n    public String getFormattedKey() {\n        return formattedText;\n    }\n\n    @Override\n    public String getFormattedValue() {\n        return \"\";\n    }\n\n    @Override\n    public String getValue() {\n        return null;\n    }\n\n    @Override\n    public void setValue(Object value) {\n\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/couchbase/view/nodedescriptor/CouchbaseValueDescriptor.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.couchbase.view.nodedescriptor;\n\nimport com.intellij.ui.ColoredTableCellRenderer;\nimport com.intellij.ui.ColoredTreeCellRenderer;\nimport com.intellij.ui.SimpleTextAttributes;\nimport org.codinjutsu.tools.nosql.commons.style.StyleAttributesProvider;\nimport org.codinjutsu.tools.nosql.commons.utils.StringUtils;\nimport org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor;\n\npublic class CouchbaseValueDescriptor implements NodeDescriptor {\n\n    private final int index;\n    protected Object value;\n    private final SimpleTextAttributes valueTextAttributes;\n\n    public static CouchbaseValueDescriptor createDescriptor(int index, Object value) {\n        if (value instanceof String) {\n            return new CouchbaseStringValueDescriptor(index, (String) value);\n        }\n        return new CouchbaseValueDescriptor(index, value, StyleAttributesProvider.getStringAttribute());\n\n    }\n\n    private CouchbaseValueDescriptor(int index, Object value, SimpleTextAttributes valueTextAttributes) {\n        this.index = index;\n        this.value = value;\n        this.valueTextAttributes = valueTextAttributes;\n    }\n\n    public void renderValue(ColoredTableCellRenderer cellRenderer, boolean isNodeExpanded) {\n        if (!isNodeExpanded) {\n            cellRenderer.append(getFormattedValue(), valueTextAttributes);\n        }\n    }\n\n    public void renderNode(ColoredTreeCellRenderer cellRenderer) {\n        cellRenderer.append(getFormattedKey(), StyleAttributesProvider.getIndexAttribute());\n    }\n\n    public String getFormattedKey() {\n        return String.format(\"[%s]\", index);\n    }\n\n    public String getFormattedValue() {\n        return String.format(\"%s\", getValueAndAbbreviateIfNecessary());\n    }\n\n    protected String getValueAndAbbreviateIfNecessary() {\n        String stringifiedValue = value.toString();\n        if (stringifiedValue.length() > MAX_LENGTH) {\n            return StringUtils.abbreviateInCenter(stringifiedValue, MAX_LENGTH);\n        }\n        return stringifiedValue;\n    }\n\n    public Object getValue() {\n        return value;\n    }\n\n    public void setValue(Object value) {\n        this.value = value;\n    }\n\n    @Override\n    public String toString() {\n        return value.toString();\n    }\n\n    private static class CouchbaseStringValueDescriptor extends CouchbaseValueDescriptor {\n\n        private CouchbaseStringValueDescriptor(int index, String value) {\n            super(index, value, StyleAttributesProvider.getStringAttribute());\n        }\n\n        @Override\n        public String getFormattedValue() {\n            return String.format(\"\\\"%s\\\"\", getValueAndAbbreviateIfNecessary());\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/MongoUI.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo;\n\nimport com.intellij.openapi.project.Project;\nimport org.codinjutsu.tools.nosql.commons.DatabaseUI;\nimport org.codinjutsu.tools.nosql.commons.view.AuthenticationView;\nimport org.codinjutsu.tools.nosql.commons.view.NoSqlResultView;\nimport org.codinjutsu.tools.nosql.commons.view.editor.NoSqlDatabaseObjectFile;\nimport org.codinjutsu.tools.nosql.mongo.logic.MongoClient;\nimport org.codinjutsu.tools.nosql.mongo.view.MongoAuthenticationPanel;\nimport org.codinjutsu.tools.nosql.mongo.view.MongoPanel;\nimport org.codinjutsu.tools.nosql.mongo.view.editor.MongoObjectFile;\n\npublic class MongoUI implements DatabaseUI {\n\n\n    @Override\n    public AuthenticationView createAythenticationView() {\n        return new MongoAuthenticationPanel();\n    }\n\n    @Override\n    public NoSqlResultView createResultPanel(Project project, NoSqlDatabaseObjectFile objectFile) {\n        MongoObjectFile mongoObjectFile = (MongoObjectFile) objectFile;\n        return new MongoPanel(project,\n                MongoClient.getInstance(project),\n                mongoObjectFile.getConfiguration(),\n                mongoObjectFile.getCollection());\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/MongoUtils.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo;\n\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.codinjutsu.tools.nosql.mongo.model.MongoDatabase;\n\npublic class MongoUtils {\n\n    private MongoUtils() {\n    }\n\n    public static String buildMongoUrl(ServerConfiguration serverConfiguration, MongoDatabase database) {\n        return String.format(\"%s/%s\", serverConfiguration.getServerUrl(), database == null ? \"test\" : database.getName());\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/logic/MongoClient.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.logic;\n\nimport com.intellij.openapi.components.ServiceManager;\nimport com.intellij.openapi.project.Project;\nimport com.mongodb.*;\nimport com.mongodb.client.MongoIterable;\nimport org.apache.commons.lang.StringUtils;\nimport org.apache.log4j.Logger;\nimport org.codinjutsu.tools.nosql.DatabaseVendor;\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.codinjutsu.tools.nosql.commons.logic.ConfigurationException;\nimport org.codinjutsu.tools.nosql.commons.logic.DatabaseClient;\nimport org.codinjutsu.tools.nosql.commons.model.AuthenticationSettings;\nimport org.codinjutsu.tools.nosql.commons.model.Database;\nimport org.codinjutsu.tools.nosql.commons.model.DatabaseServer;\nimport org.codinjutsu.tools.nosql.mongo.model.MongoCollection;\nimport org.codinjutsu.tools.nosql.mongo.model.MongoDatabase;\nimport org.codinjutsu.tools.nosql.mongo.model.MongoQueryOptions;\nimport org.codinjutsu.tools.nosql.mongo.model.MongoResult;\n\nimport java.io.IOException;\nimport java.net.UnknownHostException;\nimport java.util.*;\n\npublic class MongoClient implements DatabaseClient {\n\n    private static final Logger LOG = Logger.getLogger(MongoClient.class);\n    private final List<DatabaseServer> databaseServers = new LinkedList<>();\n\n    public static MongoClient getInstance(Project project) {\n        return ServiceManager.getService(project, MongoClient.class);\n    }\n\n    public void connect(ServerConfiguration configuration) {\n        com.mongodb.MongoClient mongo = null;\n        try {\n            String userDatabase = configuration.getUserDatabase();\n            mongo = createMongoClient(configuration);\n\n            MongoIterable<String> collectionNames;\n            if (StringUtils.isNotEmpty(userDatabase)) {\n                collectionNames = mongo.getDatabase(userDatabase).listCollectionNames();\n            } else {\n                collectionNames = mongo.getDatabase(\"test\").listCollectionNames();\n            }\n            collectionNames.first();\n\n        } catch (IOException ex) {\n            throw new MongoConnectionException(ex);\n        } catch (MongoException ex) {\n            LOG.error(\"Error when accessing Mongo server\", ex);\n            throw new MongoConnectionException(ex.getMessage());\n        } finally {\n            if (mongo != null) {\n                mongo.close();\n            }\n        }\n    }\n\n    public void cleanUpServers() {\n        databaseServers.clear();\n    }\n\n    public void registerServer(DatabaseServer databaseServer) {\n        databaseServers.add(databaseServer);\n    }\n\n    @Override\n    public ServerConfiguration defaultConfiguration() {\n        ServerConfiguration serverConfiguration = new ServerConfiguration();\n        serverConfiguration.setDatabaseVendor(DatabaseVendor.MONGO);\n        serverConfiguration.setServerUrl(DatabaseVendor.MONGO.defaultUrl);\n        return serverConfiguration;\n    }\n\n    public List<DatabaseServer> getServers() {\n        return databaseServers;\n    }\n\n    public void loadServer(DatabaseServer databaseServer) {\n        databaseServer.setStatus(DatabaseServer.Status.LOADING);\n        List<Database> mongoDatabases = loadDatabaseCollections(databaseServer.getConfiguration());\n        databaseServer.setDatabases(mongoDatabases);\n        databaseServer.setStatus(DatabaseServer.Status.OK);\n    }\n\n    List<Database> loadDatabaseCollections(ServerConfiguration configuration) {\n        com.mongodb.MongoClient mongo = null;\n        List<Database> mongoDatabases = new LinkedList<>();\n        try {\n            String userDatabase = configuration.getUserDatabase();\n\n            mongo = createMongoClient(configuration);\n\n            if (StringUtils.isNotEmpty(userDatabase)) {\n                DB database = mongo.getDB(userDatabase);\n                mongoDatabases.add(createMongoDatabaseAndItsCollections(database));\n            } else {\n                List<String> databaseNames = mongo.getDatabaseNames();\n                Collections.sort(databaseNames);\n                for (String databaseName : databaseNames) {\n                    DB database = mongo.getDB(databaseName);\n                    mongoDatabases.add(createMongoDatabaseAndItsCollections(database));\n                }\n            }\n\n            return mongoDatabases;\n        } catch (MongoException | UnknownHostException mongoEx) {\n            throw new ConfigurationException(mongoEx);\n        } finally {\n            if (mongo != null) {\n                mongo.close();\n            }\n        }\n    }\n\n    private MongoDatabase createMongoDatabaseAndItsCollections(DB database) {\n        MongoDatabase mongoDatabase = new MongoDatabase(database.getName());\n\n\n        Set<String> collectionNames = database.getCollectionNames();\n        for (String collectionName : collectionNames) {\n            mongoDatabase.addCollection(new MongoCollection(collectionName, database.getName()));\n        }\n        return mongoDatabase;\n    }\n\n    public void update(ServerConfiguration configuration, MongoCollection mongoCollection, DBObject mongoDocument) {\n        com.mongodb.MongoClient mongo = null;\n        try {\n            String databaseName = mongoCollection.getDatabaseName();\n            mongo = createMongoClient(configuration);\n\n            DB database = mongo.getDB(databaseName);\n            DBCollection collection = database.getCollection(mongoCollection.getName());\n\n            collection.save(mongoDocument);\n        } catch (UnknownHostException ex) {\n            throw new ConfigurationException(ex);\n        } finally {\n            if (mongo != null) {\n                mongo.close();\n            }\n        }\n    }\n\n    public void delete(ServerConfiguration configuration, MongoCollection mongoCollection, Object _id) {\n        com.mongodb.MongoClient mongo = null;\n        try {\n            String databaseName = mongoCollection.getDatabaseName();\n            mongo = createMongoClient(configuration);\n\n            DB database = mongo.getDB(databaseName);\n            DBCollection collection = database.getCollection(mongoCollection.getName());\n\n            collection.remove(new BasicDBObject(\"_id\", _id));\n        } catch (UnknownHostException ex) {\n            throw new ConfigurationException(ex);\n        } finally {\n            if (mongo != null) {\n                mongo.close();\n            }\n        }\n    }\n\n    public void dropCollection(ServerConfiguration configuration, MongoCollection mongoCollection) {\n        com.mongodb.MongoClient mongo = null;\n        try {\n            String databaseName = mongoCollection.getDatabaseName();\n            mongo = createMongoClient(configuration);\n\n            DB database = mongo.getDB(databaseName);\n            DBCollection collection = database.getCollection(mongoCollection.getName());\n\n            collection.drop();\n        } catch (UnknownHostException ex) {\n            throw new ConfigurationException(ex);\n        } finally {\n            if (mongo != null) {\n                mongo.close();\n            }\n        }\n    }\n\n    public void dropDatabase(ServerConfiguration configuration, MongoDatabase selectedDatabase) {\n        com.mongodb.MongoClient mongo = null;\n        try {\n            mongo = createMongoClient(configuration);\n            mongo.dropDatabase(selectedDatabase.getName());\n        } catch (UnknownHostException ex) {\n            throw new ConfigurationException(ex);\n        } finally {\n            if (mongo != null) {\n                mongo.close();\n            }\n        }\n    }\n\n    public MongoResult loadCollectionValues(ServerConfiguration configuration, MongoCollection mongoCollection, MongoQueryOptions mongoQueryOptions) {\n        com.mongodb.MongoClient mongo = null;\n        try {\n            String databaseName = mongoCollection.getDatabaseName();\n            mongo = createMongoClient(configuration);\n\n            DB database = mongo.getDB(databaseName);\n            DBCollection collection = database.getCollection(mongoCollection.getName());\n\n            MongoResult mongoResult = new MongoResult(mongoCollection.getName());\n            if (mongoQueryOptions.isAggregate()) {\n                return aggregate(mongoQueryOptions, mongoResult, collection);\n            }\n\n            return find(mongoQueryOptions, mongoResult, collection);\n\n        } catch (UnknownHostException ex) {\n            throw new ConfigurationException(ex);\n        } finally {\n            if (mongo != null) {\n                mongo.close();\n            }\n        }\n    }\n\n    public DBObject findMongoDocument(ServerConfiguration configuration, MongoCollection mongoCollection, Object _id) {\n        com.mongodb.MongoClient mongo = null;\n        try {\n            String databaseName = mongoCollection.getDatabaseName();\n            mongo = createMongoClient(configuration);\n\n            DB database = mongo.getDB(databaseName);\n            DBCollection collection = database.getCollection(mongoCollection.getName());\n            return collection.findOne(new BasicDBObject(\"_id\", _id));\n\n        } catch (UnknownHostException ex) {\n            throw new ConfigurationException(ex);\n        } finally {\n            if (mongo != null) {\n                mongo.close();\n            }\n        }\n    }\n\n    private MongoResult aggregate(MongoQueryOptions mongoQueryOptions, MongoResult mongoResult, DBCollection collection) {\n        AggregationOutput aggregate = collection.aggregate(mongoQueryOptions.getOperations());\n        int index = 0;\n        Iterator<DBObject> iterator = aggregate.results().iterator();\n        while (iterator.hasNext() && index < mongoQueryOptions.getResultLimit()) {\n            mongoResult.add(iterator.next());\n        }\n        return mongoResult;\n    }\n\n    private MongoResult find(MongoQueryOptions mongoQueryOptions, MongoResult mongoResult, DBCollection collection) {\n        DBObject filter = mongoQueryOptions.getFilter();\n        DBObject projection = mongoQueryOptions.getProjection();\n        DBObject sort = mongoQueryOptions.getSort();\n\n        DBCursor cursor;\n        if (projection == null) {\n            cursor = collection.find(filter);\n        } else {\n            cursor = collection.find(filter, projection);\n        }\n\n        if (sort != null) {\n            cursor = cursor.sort(sort);\n        }\n\n        try {\n            int index = 0;\n            while (cursor.hasNext() && index < mongoQueryOptions.getResultLimit()) {\n                mongoResult.add(cursor.next());\n                index++;\n            }\n        } finally {\n            cursor.close();\n        }\n        return mongoResult;\n    }\n\n    private com.mongodb.MongoClient createMongoClient(ServerConfiguration configuration) throws UnknownHostException {\n        String serverUrl = configuration.getServerUrl();\n        if (StringUtils.isEmpty(serverUrl)) {\n            throw new ConfigurationException(\"server host is not set\");\n        }\n\n        MongoClientURIBuilder uriBuilder = MongoClientURIBuilder.builder();\n        uriBuilder.setServerAddresses(serverUrl);\n        AuthenticationSettings authenticationSettings = configuration.getAuthenticationSettings();\n        MongoExtraSettings mongoExtraSettings = new MongoExtraSettings(authenticationSettings.getExtras());\n        if (StringUtils.isNotEmpty(authenticationSettings.getUsername())) {\n            uriBuilder.setCredential(authenticationSettings.getUsername(), authenticationSettings.getPassword(), mongoExtraSettings.getAuthenticationDatabase());\n        }\n\n\n        if (mongoExtraSettings.getAuthenticationMechanism() != null) {\n            uriBuilder.setAuthenticationMecanism(mongoExtraSettings.getAuthenticationMechanism());\n        }\n\n        if (mongoExtraSettings.isSsl()) {\n            uriBuilder.sslEnabled();\n        }\n\n        return new com.mongodb.MongoClient(new MongoClientURI(uriBuilder.build()));\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/logic/MongoClientURIBuilder.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.logic;\n\nimport com.mongodb.AuthenticationMechanism;\nimport org.apache.commons.lang.StringUtils;\nimport org.jetbrains.annotations.NotNull;\n\nimport java.util.HashMap;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Map;\n\npublic class MongoClientURIBuilder {\n\n    private static final String DEFAULT_AUTH_DB = \"admin\";\n\n    private String serverUrls;\n    private String username;\n    private String password;\n    private String authDatabase;\n    private AuthenticationMechanism authenticationMecanism;\n    private boolean sslEnabled = false;\n\n    private MongoClientURIBuilder() {\n    }\n\n    public static MongoClientURIBuilder builder() {\n        return new MongoClientURIBuilder();\n    }\n\n    public MongoClientURIBuilder setServerAddresses(String serverUrls) {\n        this.serverUrls = serverUrls;\n        return this;\n    }\n\n    public MongoClientURIBuilder setCredential(String username, String password, String authDatabase) {\n        this.username = username;\n        this.password = password;\n        this.authDatabase = StringUtils.isNotEmpty(authDatabase) ? authDatabase : DEFAULT_AUTH_DB;\n        return this;\n    }\n\n    public String build() {\n        StringBuilder strBuilder = new StringBuilder();\n        Map<String, String> options = new HashMap<String, String>();\n        if (StringUtils.isEmpty(username)) {\n            strBuilder.append(String.format(\"mongodb://%s/\", this.serverUrls));\n        } else {\n            strBuilder.append(String.format(\"mongodb://%s:%s@%s/\", username, password, serverUrls));\n        }\n        if (authDatabase != null) {\n            options.put(\"authSource\", authDatabase);\n        }\n\n        if (authenticationMecanism != null) {\n            options.put(\"authMechanism\", authenticationMecanism.getMechanismName());\n        }\n\n        if (sslEnabled) {\n            options.put(\"ssl\", Boolean.TRUE.toString());\n        }\n        if (options.size() == 0) {\n            return strBuilder.toString();\n        }\n        return strBuilder.append(buildOptions(options)).toString();\n    }\n\n    public MongoClientURIBuilder setAuthenticationMecanism(@NotNull AuthenticationMechanism authenticationMecanism) {\n        this.authenticationMecanism = authenticationMecanism;\n        return this;\n    }\n\n    public MongoClientURIBuilder sslEnabled() {\n        sslEnabled = true;\n        return this;\n    }\n\n    private static String buildOptions(Map<String, String> options) {\n        List<String> optionList = new LinkedList<String>();\n        for (Map.Entry<String, String> keyValue : options.entrySet()) {\n            optionList.add(String.format(\"%s=%s\", keyValue.getKey(), keyValue.getValue()));\n        }\n        return \"?\" + StringUtils.join(optionList, \"&\");\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/logic/MongoConnectionException.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.logic;\n\npublic class MongoConnectionException extends RuntimeException {\n    public MongoConnectionException(String message) {\n        super(message);\n    }\n\n    public MongoConnectionException(Exception ex) {\n        super(ex);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/logic/MongoExtraSettings.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.logic;\n\nimport com.mongodb.AuthenticationMechanism;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class MongoExtraSettings {\n\n    private static final String DEFAULT_AUTH_DATABASE = \"admin\";\n\n    private static final String SSL = \"ssl\";\n    private static final String AUTH_DATABASE = \"authDatabase\";\n    private static final String AUTH_MECHANISM = \"authMechanism\";\n    private Map<String, String> extras = new HashMap<>();\n\n    public MongoExtraSettings() {\n    }\n\n    public MongoExtraSettings(Map<String, String> extras) {\n        this.extras = extras;\n    }\n\n    public String getAuthenticationDatabase() {\n        String authDatabase = extras.get(AUTH_DATABASE);\n        return authDatabase == null ? DEFAULT_AUTH_DATABASE : authDatabase;\n    }\n\n    public AuthenticationMechanism getAuthenticationMechanism() {\n        String authMecanism = extras.get(AUTH_MECHANISM);\n        return authMecanism == null ? null : AuthenticationMechanism.valueOf(authMecanism);\n    }\n\n    public boolean isSsl() {\n        String isSsl = extras.get(SSL);\n        return isSsl == null ? false : Boolean.valueOf(isSsl);\n    }\n\n    public void setAuthenticationDatabase(String authenticationDatabase) {\n        extras.put(AUTH_DATABASE, authenticationDatabase);\n    }\n\n    public void setAuthenticationMechanism(AuthenticationMechanism authenticationMechanism) {\n        if (authenticationMechanism != null) {\n            extras.put(AUTH_MECHANISM, authenticationMechanism.name());\n        }\n    }\n\n    public void setSsl(boolean isSsl) {\n        extras.put(SSL, String.valueOf(isSsl));\n    }\n\n    public Map<String, String> get() {\n        return extras;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/model/JsonDataType.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.model;\n\npublic enum JsonDataType {\n\n    STRING(\"String\"),\n    NUMBER(\"Number\"),\n    BOOLEAN(\"Boolean\"),\n    ARRAY(\"Array\"),\n    OBJECT(\"Object\"),\n    NULL(\"Null\"),\n    DATE(\"Date\");\n\n    public final String type;\n\n    private JsonDataType(String type) {\n        this.type = type;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/model/MongoAggregateOperator.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.model;\n\npublic enum MongoAggregateOperator {\n\n    MATCH(\"$match\"),\n    PROJECT(\"$project\"),\n    GROUP(\"$group\"),\n    SORT(\"$sort\"),\n    LIMIT(\"$limit\"),\n    SKIP(\"$skip\"),\n    UNWIND(\"$unwind\");\n\n    private final String operator;\n\n    private MongoAggregateOperator(String operator) {\n        this.operator = operator;\n    }\n\n    public String getLabel() {\n        return operator;\n    }\n\n\n    @Override\n    public String toString() {\n        return name().toLowerCase();\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/model/MongoCollection.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.model;\n\nimport org.jetbrains.annotations.NotNull;\n\npublic class MongoCollection implements Comparable<MongoCollection> {\n\n    private final String name;\n    private final String databaseName;\n\n    public MongoCollection(String name, String databaseName) {\n        this.name = name;\n        this.databaseName = databaseName;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public String getDatabaseName() {\n        return databaseName;\n    }\n\n    @Override\n    public int compareTo(@NotNull MongoCollection otherCollection) {\n        return this.name.compareTo(otherCollection.getName());\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/model/MongoDatabase.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.model;\n\nimport org.codinjutsu.tools.nosql.commons.model.Database;\n\nimport java.util.Set;\nimport java.util.SortedSet;\nimport java.util.TreeSet;\n\npublic class MongoDatabase extends Database {\n\n    private final SortedSet<MongoCollection> collections = new TreeSet<MongoCollection>();\n\n    public MongoDatabase(String name) {\n        super(name);\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public Set<MongoCollection> getCollections() {\n        return collections;\n    }\n\n    public void addCollection(MongoCollection mongoCollection) {\n        collections.add(mongoCollection);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/model/MongoQueryOptions.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.model;\n\nimport com.mongodb.BasicDBList;\nimport com.mongodb.BasicDBObject;\nimport com.mongodb.DBObject;\nimport com.mongodb.util.JSON;\nimport org.apache.commons.lang.StringUtils;\n\nimport java.util.LinkedList;\nimport java.util.List;\n\npublic class MongoQueryOptions {\n\n    private static final int DEFAULT_RESULT_LIMIT = 300;\n\n    private static final BasicDBObject EMPTY_FILTER = new BasicDBObject();\n    private final List<Object> operations = new LinkedList<Object>();\n\n    private DBObject filter = EMPTY_FILTER;\n    private DBObject projection = null;\n    private DBObject sort;\n\n    private int resultLimit = DEFAULT_RESULT_LIMIT;\n\n    public boolean isAggregate() {\n        return !operations.isEmpty();\n    }\n\n    public List getOperations() {\n        return operations;\n    }\n\n    public void setOperations(String aggregateQuery) {\n        operations.clear();\n        BasicDBList operations = (BasicDBList) JSON.parse(aggregateQuery);\n        this.operations.addAll(operations);\n    }\n\n    public void setFilter(String query) {\n        if (!StringUtils.isBlank(query)) {\n            filter = (DBObject) JSON.parse(query);\n        }\n    }\n\n    public DBObject getFilter() {\n        return filter;\n    }\n\n    public void setProjection(String query) {\n        if (!StringUtils.isBlank(query)) {\n            projection = (DBObject) JSON.parse(query);\n        }\n    }\n\n\n    public DBObject getProjection() {\n        return projection;\n    }\n\n    public void setSort(String query) {\n        if (!StringUtils.isBlank(query)) {\n            sort = (DBObject) JSON.parse(query);\n        }\n    }\n\n    public DBObject getSort() {\n        return sort;\n    }\n\n    public int getResultLimit() {\n        return resultLimit;\n    }\n\n    public void setResultLimit(int resultLimit) {\n        this.resultLimit = resultLimit;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/model/MongoResult.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.model;\n\nimport com.mongodb.DBObject;\n\nimport java.util.LinkedList;\nimport java.util.List;\n\npublic class MongoResult {\n\n    private final String collectionName;\n    private final List<DBObject> mongoObjects = new LinkedList<DBObject>();\n\n    public MongoResult(String collectionName) {\n        this.collectionName = collectionName;\n    }\n\n    public void add(DBObject dbObject) {\n        mongoObjects.add(dbObject);\n    }\n\n    public List<DBObject> getMongoObjects() {\n        return mongoObjects;\n    }\n\n    public String getCollectionName() {\n        return collectionName;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/model/OperatorValueConverter.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.model;\n\nimport com.mongodb.DBObject;\nimport com.mongodb.util.JSON;\n\ninterface OperatorValueConverter<T> {\n\n    T convert(String operatorValue);\n\n\n    public static OperatorValueConverter integerValueConverter = new OperatorValueConverter<Integer>() {\n\n        @Override\n        public Integer convert(String operatorValue) {\n            return Integer.valueOf(operatorValue);\n        }\n    };\n\n    public static OperatorValueConverter stringValueConverter = new OperatorValueConverter<String>() {\n\n        @Override\n        public String convert(String operatorValue) {\n            return operatorValue;\n        }\n    };\n\n    public static OperatorValueConverter jSONValueConverter = new OperatorValueConverter<DBObject>() {\n\n        @Override\n        public DBObject convert(String operatorValue) {\n            return (DBObject) JSON.parse(operatorValue);\n        }\n    };\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/runner/MongoCommandLineState.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.runner;\n\nimport com.intellij.execution.ExecutionException;\nimport com.intellij.execution.configurations.CommandLineState;\nimport com.intellij.execution.configurations.GeneralCommandLine;\nimport com.intellij.execution.process.ColoredProcessHandler;\nimport com.intellij.execution.process.OSProcessHandler;\nimport com.intellij.execution.process.ProcessHandler;\nimport com.intellij.execution.process.ProcessTerminatedListener;\nimport com.intellij.execution.runners.ExecutionEnvironment;\nimport com.intellij.openapi.vfs.VirtualFile;\nimport org.apache.commons.lang.StringUtils;\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.codinjutsu.tools.nosql.mongo.MongoUtils;\nimport org.codinjutsu.tools.nosql.mongo.model.MongoDatabase;\nimport org.jetbrains.annotations.NotNull;\n\nclass MongoCommandLineState extends CommandLineState {\n\n    private final MongoRunConfiguration mongoRunConfiguration;\n\n    public MongoCommandLineState(MongoRunConfiguration mongoRunConfiguration, ExecutionEnvironment environment) {\n        super(environment);\n        this.mongoRunConfiguration = mongoRunConfiguration;\n    }\n\n    @NotNull\n    @Override\n    protected ProcessHandler startProcess() throws ExecutionException {\n        GeneralCommandLine commandLine = generateCommandLine();\n        final OSProcessHandler processHandler = new ColoredProcessHandler(commandLine);\n        ProcessTerminatedListener.attach(processHandler);\n        return processHandler;\n    }\n\n    private GeneralCommandLine generateCommandLine() {\n        final GeneralCommandLine commandLine = new GeneralCommandLine();\n\n        String exePath = mongoRunConfiguration.getMongoShell();\n        commandLine.setExePath(exePath);\n\n        ServerConfiguration serverConfiguration = mongoRunConfiguration.getServerConfiguration();\n        MongoDatabase database = mongoRunConfiguration.getDatabase();\n        commandLine.addParameter(MongoUtils.buildMongoUrl(serverConfiguration, database));\n\n        VirtualFile scriptPath = mongoRunConfiguration.getScriptPath();\n        commandLine.addParameter(scriptPath.getPath());\n\n\n        String shellWorkingDir = mongoRunConfiguration.getShellWorkingDir();\n        if (StringUtils.isNotEmpty(shellWorkingDir)) {\n            commandLine.setWorkDirectory(shellWorkingDir);\n        }\n        return commandLine;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/runner/MongoRunConfiguration.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.runner;\n\nimport com.intellij.execution.CantRunException;\nimport com.intellij.execution.ExecutionException;\nimport com.intellij.execution.Executor;\nimport com.intellij.execution.configurations.*;\nimport com.intellij.execution.filters.TextConsoleBuilderFactory;\nimport com.intellij.execution.runners.ExecutionEnvironment;\nimport com.intellij.openapi.components.PathMacroManager;\nimport com.intellij.openapi.module.Module;\nimport com.intellij.openapi.module.ModuleManager;\nimport com.intellij.openapi.options.SettingsEditor;\nimport com.intellij.openapi.util.InvalidDataException;\nimport com.intellij.openapi.util.JDOMExternalizer;\nimport com.intellij.openapi.util.WriteExternalException;\nimport com.intellij.openapi.util.io.FileUtil;\nimport com.intellij.openapi.vfs.LocalFileSystem;\nimport com.intellij.openapi.vfs.VirtualFile;\nimport org.codinjutsu.tools.nosql.DatabaseVendor;\nimport org.codinjutsu.tools.nosql.NoSqlConfiguration;\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.codinjutsu.tools.nosql.mongo.model.MongoDatabase;\nimport org.jdom.Element;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\nimport java.util.Arrays;\nimport java.util.Collection;\n\nclass MongoRunConfiguration extends ModuleBasedConfiguration<RunConfigurationModule> {\n\n    private final String mongoShell;\n    private String scriptPath;\n    private String shellParameters;\n    private ServerConfiguration serverConfiguration;\n    private MongoDatabase database;\n    private String shellWorkingDir;\n\n\n    MongoRunConfiguration(RunConfigurationModule runConfigurationModule, ConfigurationFactory factory) {\n        super(\"Mongo Script\", runConfigurationModule, factory);\n\n        mongoShell = NoSqlConfiguration.getInstance(getProject()).getShellPath(DatabaseVendor.MONGO);\n    }\n\n    @NotNull\n    @Override\n    public SettingsEditor<? extends RunConfiguration> getConfigurationEditor() {\n        return new MongoRunConfigurationEditor(getProject());\n    }\n\n\n    @Override\n    public Collection<Module> getValidModules() {\n        Module[] allModules = ModuleManager.getInstance(getProject()).getModules();\n        return Arrays.asList(allModules);\n    }\n\n    @Override\n    public void readExternal(Element element) throws InvalidDataException {\n        PathMacroManager.getInstance(getProject()).expandPaths(element);\n        super.readExternal(element);\n        scriptPath = JDOMExternalizer.readString(element, \"path\");\n        shellParameters = JDOMExternalizer.readString(element, \"shellParams\");\n//        serverConfiguration = JDOMExternalizer.readBoolean(element, \"serverConfiguration\");\n    }\n\n    @Override\n    public void writeExternal(Element element) throws WriteExternalException {\n        super.writeExternal(element);\n        JDOMExternalizer.write(element, \"path\", scriptPath);\n        JDOMExternalizer.write(element, \"shellParams\", shellParameters);\n//        JDOMExternalizer.write(element, \"serverConfiguration\", serverConfiguration);\n\n        PathMacroManager.getInstance(getProject()).collapsePathsRecursively(element);\n    }\n\n    @Override\n    protected MongoRunConfiguration createInstance() {\n        return new MongoRunConfiguration(getConfigurationModule(), getFactory());\n    }\n\n    @Nullable\n    @Override\n    public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment env) throws ExecutionException {\n        final VirtualFile script = getScriptPath();\n        if (script == null) {\n            throw new CantRunException(\"Cannot find script \" + scriptPath);\n        }\n\n        final MongoCommandLineState state = new MongoCommandLineState(this, env);\n        state.setConsoleBuilder(TextConsoleBuilderFactory.getInstance().createBuilder(getProject()));\n        return state;\n    }\n\n    @Override\n    public void checkConfiguration() throws RuntimeConfigurationException {\n        if (mongoShell == null) {\n            throw new RuntimeConfigurationError(\"Mongo shell path is not set.\");\n        }\n\n        if (scriptPath == null) {\n            throw new RuntimeConfigurationError(\"Script path is not set.\");\n        }\n\n        if (serverConfiguration == null) {\n            throw new RuntimeConfigurationError(\"Server is not set.\");\n        }\n\n        if (database == null) {\n            throw new RuntimeConfigurationError(\"Database is not set.\");\n        }\n    }\n\n    public VirtualFile getScriptPath() {\n        if (scriptPath == null) return null;\n        return LocalFileSystem.getInstance().findFileByPath(FileUtil.toSystemIndependentName(scriptPath));\n    }\n\n    public void setScriptPath(String scriptPath) {\n        this.scriptPath = scriptPath;\n    }\n\n    public ServerConfiguration getServerConfiguration() {\n        return serverConfiguration;\n    }\n\n    public void setServerConfiguration(ServerConfiguration serverConfiguration) {\n        this.serverConfiguration = serverConfiguration;\n    }\n\n    public String getShellParameters() {\n        return shellParameters;\n    }\n\n    public void setShellParameters(String shellParameters) {\n        this.shellParameters = shellParameters;\n    }\n\n    public String getMongoShell() {\n        return mongoShell;\n    }\n\n    public MongoDatabase getDatabase() {\n        return this.database;\n    }\n\n    public void setDatabase(MongoDatabase database) {\n        this.database = database;\n    }\n\n    public String getShellWorkingDir() {\n        return shellWorkingDir;\n    }\n\n    public void setShellWorkingDir(String shellWorkingDir) {\n        this.shellWorkingDir = shellWorkingDir;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/runner/MongoRunConfigurationEditor.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<form xmlns=\"http://www.intellij.com/uidesigner/form/\" version=\"1\" bind-to-class=\"org.codinjutsu.tools.nosql.mongo.runner.MongoRunConfigurationEditor\">\n  <grid id=\"27dc6\" binding=\"mainPanel\" layout-manager=\"GridLayoutManager\" row-count=\"5\" column-count=\"2\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n    <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n    <constraints>\n      <xy x=\"20\" y=\"20\" width=\"500\" height=\"400\"/>\n    </constraints>\n    <properties/>\n    <border type=\"none\"/>\n    <children>\n      <component id=\"19191\" class=\"javax.swing.JLabel\">\n        <constraints>\n          <grid row=\"0\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties>\n          <text value=\"Script path:\"/>\n        </properties>\n      </component>\n      <vspacer id=\"afdfc\">\n        <constraints>\n          <grid row=\"4\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"6\" hsize-policy=\"1\" anchor=\"0\" fill=\"2\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n      </vspacer>\n      <component id=\"fcf8a\" class=\"javax.swing.JTextField\" binding=\"scriptPathField\">\n        <constraints>\n          <grid row=\"0\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"6\" anchor=\"8\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\">\n            <preferred-size width=\"150\" height=\"-1\"/>\n          </grid>\n        </constraints>\n        <properties/>\n      </component>\n      <component id=\"94ddb\" class=\"com.intellij.openapi.ui.ComboBox\" binding=\"serverConfigurationCombobox\">\n        <constraints>\n          <grid row=\"1\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n      </component>\n      <component id=\"7352f\" class=\"javax.swing.JLabel\">\n        <constraints>\n          <grid row=\"1\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties>\n          <text value=\"Server:\"/>\n        </properties>\n      </component>\n      <component id=\"97a6a\" class=\"javax.swing.JLabel\">\n        <constraints>\n          <grid row=\"2\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties>\n          <text value=\"Database:\"/>\n        </properties>\n      </component>\n      <grid id=\"8e240\" binding=\"mongoShellOptionsPanel\" layout-manager=\"GridLayoutManager\" row-count=\"2\" column-count=\"2\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n        <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n        <constraints>\n          <grid row=\"3\" column=\"0\" row-span=\"1\" col-span=\"2\" vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n        <border type=\"none\" title=\"Mongo shell\"/>\n        <children>\n          <component id=\"52239\" class=\"javax.swing.JLabel\">\n            <constraints>\n              <grid row=\"0\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n            </constraints>\n            <properties>\n              <text value=\"Arguments:\"/>\n            </properties>\n          </component>\n          <component id=\"594ad\" class=\"com.intellij.ui.RawCommandLineEditor\" binding=\"shellParametersField\">\n            <constraints>\n              <grid row=\"0\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\"/>\n            </constraints>\n            <properties/>\n          </component>\n          <component id=\"32b18\" class=\"javax.swing.JLabel\">\n            <constraints>\n              <grid row=\"1\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n            </constraints>\n            <properties>\n              <text value=\"Working dir:\"/>\n            </properties>\n          </component>\n          <component id=\"21eef\" class=\"com.intellij.openapi.ui.TextFieldWithBrowseButton\" binding=\"shellWorkingDirField\" custom-create=\"true\">\n            <constraints>\n              <grid row=\"1\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\" indent=\"0\" use-parent-layout=\"false\"/>\n            </constraints>\n            <properties/>\n          </component>\n        </children>\n      </grid>\n      <component id=\"a97e2\" class=\"com.intellij.openapi.ui.ComboBox\" binding=\"databaseCombobox\">\n        <constraints>\n          <grid row=\"2\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n      </component>\n    </children>\n  </grid>\n</form>\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/runner/MongoRunConfigurationEditor.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.runner;\n\nimport com.intellij.openapi.fileChooser.FileChooserDescriptor;\nimport com.intellij.openapi.options.ConfigurationException;\nimport com.intellij.openapi.options.SettingsEditor;\nimport com.intellij.openapi.project.Project;\nimport com.intellij.openapi.ui.ComboBox;\nimport com.intellij.openapi.ui.TextFieldWithBrowseButton;\nimport com.intellij.ui.ColoredListCellRenderer;\nimport com.intellij.ui.IdeBorderFactory;\nimport com.intellij.ui.RawCommandLineEditor;\nimport org.apache.commons.lang.StringUtils;\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.codinjutsu.tools.nosql.commons.model.Database;\nimport org.codinjutsu.tools.nosql.commons.model.DatabaseServer;\nimport org.codinjutsu.tools.nosql.mongo.logic.MongoClient;\nimport org.codinjutsu.tools.nosql.mongo.model.MongoDatabase;\nimport org.jetbrains.annotations.NotNull;\n\nimport javax.swing.*;\nimport java.awt.event.ItemEvent;\nimport java.awt.event.ItemListener;\nimport java.util.LinkedList;\nimport java.util.List;\n\npublic class MongoRunConfigurationEditor extends SettingsEditor<MongoRunConfiguration> {\n\n    private JPanel mainPanel;\n\n    private JTextField scriptPathField;\n    private ComboBox serverConfigurationCombobox;\n    private ComboBox databaseCombobox;\n    private JPanel mongoShellOptionsPanel;\n    private RawCommandLineEditor shellParametersField;\n    private TextFieldWithBrowseButton shellWorkingDirField;\n\n\n    public MongoRunConfigurationEditor(Project project) {\n        mongoShellOptionsPanel.setBorder(IdeBorderFactory.createTitledBorder(\"Mongo shell options\", true));\n\n        shellParametersField.setDialogCaption(\"Mongo arguments\");\n\n        DatabaseServer[] mongoServers = getAvailableMongoServers(project);\n\n        if (mongoServers.length == 0) {\n            serverConfigurationCombobox.setEnabled(false);\n            databaseCombobox.setEnabled(false);\n            return;\n        }\n\n        serverConfigurationCombobox.setModel(new DefaultComboBoxModel(mongoServers));\n\n        serverConfigurationCombobox.setRenderer(new ColoredListCellRenderer() {\n            @Override\n            protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) {\n                DatabaseServer serverConfiguration = (DatabaseServer) value;\n                append(serverConfiguration.getLabel());\n            }\n        });\n\n\n        databaseCombobox.setRenderer(new ColoredListCellRenderer() {\n            @Override\n            protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) {\n                MongoDatabase mongoDatabase = (MongoDatabase) value;\n                if (value == null) {\n                    return;\n                }\n                append(mongoDatabase.getName());\n            }\n        });\n\n\n        serverConfigurationCombobox.addItemListener(new ItemListener() {\n\n            @Override\n            public void itemStateChanged(ItemEvent itemEvent) {\n                DatabaseServer selectedServer = (DatabaseServer) serverConfigurationCombobox.getSelectedItem();\n                if (selectedServer == null) {\n                    return;\n                }\n                databaseCombobox.removeAllItems();\n                for (Database mongoDatabase : selectedServer.getDatabases()) {\n                    databaseCombobox.addItem(mongoDatabase);\n                }\n            }\n        });\n\n        serverConfigurationCombobox.setSelectedIndex(-1);\n        serverConfigurationCombobox.setSelectedIndex(0);\n    }\n\n    private DatabaseServer[] getAvailableMongoServers(Project project) {\n        List<DatabaseServer> mongoServers = MongoClient.getInstance(project).getServers();\n        List<DatabaseServer> availableMongoServers = new LinkedList<DatabaseServer>();\n        for (DatabaseServer mongoServer : mongoServers) {\n            if (mongoServer.hasDatabases()) {\n                availableMongoServers.add(mongoServer);\n            }\n        }\n        return availableMongoServers.toArray(new DatabaseServer[availableMongoServers.size()]);\n    }\n\n    @Override\n    protected void resetEditorFrom(MongoRunConfiguration configuration) {\n        scriptPathField.setText(configuration.getScriptPath() != null ? configuration.getScriptPath().getPath() : null);\n        shellParametersField.setText(configuration.getShellParameters());\n        shellWorkingDirField.setText(configuration.getShellWorkingDir());\n    }\n\n    @Override\n    protected void applyEditorTo(MongoRunConfiguration configuration) throws ConfigurationException {\n        configuration.setScriptPath(getScriptPath());\n        configuration.setServerConfiguration(getSelectedConfiguration());\n        configuration.setDatabase(getSelectedDatabase());\n        configuration.setShellParameters(getShellParameters());\n        configuration.setShellWorkingDir(getShellWorkingDir());\n    }\n\n    private String getScriptPath() {\n        return scriptPathField.getText();\n    }\n\n    private String getShellParameters() {\n        return shellParametersField.getText();\n    }\n\n    private ServerConfiguration getSelectedConfiguration() {\n        DatabaseServer selectedServer = (DatabaseServer) serverConfigurationCombobox.getSelectedItem();\n        return selectedServer == null ? null : selectedServer.getConfiguration();\n    }\n\n    public MongoDatabase getSelectedDatabase() {\n        return (MongoDatabase) databaseCombobox.getSelectedItem();\n    }\n\n    private String getShellWorkingDir() {\n        String shellWorkingDir = shellWorkingDirField.getText();\n        if (StringUtils.isNotBlank(shellWorkingDir)) {\n            return shellWorkingDir;\n        }\n\n        return null;\n    }\n\n    @NotNull\n    @Override\n    protected JComponent createEditor() {\n        return mainPanel;\n    }\n\n    @Override\n    protected void disposeEditor() {\n\n    }\n\n    private void createUIComponents() {\n        shellWorkingDirField = new TextFieldWithBrowseButton();\n        shellWorkingDirField.addBrowseFolderListener(\"Mongo shell working directory\", \"\", null,\n                new FileChooserDescriptor(false, true, false, false, false, false));\n        shellWorkingDirField.setName(\"shellWorkingDirField\");\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/runner/MongoRunConfigurationType.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.runner;\n\nimport com.intellij.execution.configurations.*;\nimport com.intellij.openapi.project.Project;\nimport org.codinjutsu.tools.nosql.commons.utils.GuiUtils;\nimport org.jetbrains.annotations.NonNls;\nimport org.jetbrains.annotations.NotNull;\n\nimport javax.swing.*;\n\npublic class MongoRunConfigurationType implements ConfigurationType {\n    private final MongoFactory myConfigurationFactory;\n\n    public MongoRunConfigurationType() {\n        myConfigurationFactory = new MongoFactory(this);\n    }\n\n    public String getDisplayName() {\n        return \"Mongo\";\n    }\n\n    public String getConfigurationTypeDescription() {\n        return \"Mongo configuration\";\n    }\n\n    public Icon getIcon() {\n        return GuiUtils.loadIcon(\"mongo_logo.png\");\n    }\n\n    @NonNls\n    @NotNull\n    public String getId() {\n        return \"MongoRunConfiguration\";\n    }\n\n    public MongoFactory[] getConfigurationFactories() {\n        return new MongoFactory[]{myConfigurationFactory};\n    }\n\n    public static MongoRunConfigurationType getInstance() {\n        return ConfigurationTypeUtil.findConfigurationType(MongoRunConfigurationType.class);\n    }\n\n    private static class MongoFactory extends ConfigurationFactory {\n        public MongoFactory(ConfigurationType type) {\n            super(type);\n        }\n\n        public RunConfiguration createTemplateConfiguration(Project project) {\n            return new MongoRunConfiguration(new RunConfigurationModule(project), this);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/runner/MongoScriptRunConfigurationProducer.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.runner;\n\nimport com.intellij.execution.Location;\nimport com.intellij.execution.RunnerAndConfigurationSettings;\nimport com.intellij.execution.actions.ConfigurationContext;\nimport com.intellij.execution.junit.RuntimeConfigurationProducer;\nimport com.intellij.openapi.module.Module;\nimport com.intellij.openapi.module.ModuleUtil;\nimport com.intellij.openapi.project.Project;\nimport com.intellij.openapi.vfs.VirtualFile;\nimport com.intellij.psi.PsiElement;\nimport com.intellij.psi.PsiFile;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\npublic class MongoScriptRunConfigurationProducer extends RuntimeConfigurationProducer implements Cloneable {\n\n    private PsiFile sourceFile;\n\n    public MongoScriptRunConfigurationProducer() {\n        super(MongoRunConfigurationType.getInstance());\n    }\n\n    @Override\n    public PsiElement getSourceElement() {\n        return sourceFile;\n    }\n\n    @Nullable\n    @Override\n    protected RunnerAndConfigurationSettings createConfigurationByElement(Location location, ConfigurationContext configurationContext) {\n        sourceFile = location.getPsiElement().getContainingFile();\n        if (sourceFile != null && sourceFile.getFileType().getName().toLowerCase().contains(\"javascript\")) {\n            Project project = sourceFile.getProject();\n\n            VirtualFile file = sourceFile.getVirtualFile();\n\n            RunnerAndConfigurationSettings settings = cloneTemplateConfiguration(project, configurationContext);\n\n            MongoRunConfiguration runConfiguration = (MongoRunConfiguration) settings.getConfiguration();\n            runConfiguration.setName(file.getName());\n\n            runConfiguration.setScriptPath(file.getPath());\n\n            Module module = ModuleUtil.findModuleForPsiElement(location.getPsiElement());\n            if (module != null) {\n                runConfiguration.setModule(module);\n            }\n\n            return settings;\n        }\n        return null;\n    }\n\n\n    @Override\n    public int compareTo(@NotNull Object o) {\n        return 0;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/AbstractAddDialog.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view;\n\nimport com.intellij.openapi.ui.ComboBox;\nimport com.intellij.openapi.ui.DialogWrapper;\nimport com.intellij.ui.ColoredListCellRenderer;\nimport com.intellij.ui.components.JBCheckBox;\nimport com.mongodb.util.JSON;\nimport org.apache.commons.lang.StringUtils;\nimport org.codinjutsu.tools.nosql.commons.view.table.DateTimePicker;\nimport org.codinjutsu.tools.nosql.mongo.model.JsonDataType;\n\nimport javax.swing.*;\nimport java.awt.*;\nimport java.awt.event.ItemEvent;\nimport java.awt.event.ItemListener;\nimport java.util.Date;\nimport java.util.GregorianCalendar;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic abstract class AbstractAddDialog extends DialogWrapper {\n    private static final Map<JsonDataType, TextFieldWrapper> UI_COMPONENT_BY_JSON_DATATYPE = new HashMap<JsonDataType, TextFieldWrapper>();\n\n\n    static {\n\n        UI_COMPONENT_BY_JSON_DATATYPE.put(JsonDataType.STRING, new StringFieldWrapper());\n        UI_COMPONENT_BY_JSON_DATATYPE.put(JsonDataType.BOOLEAN, new BooleanFieldWrapper());\n        UI_COMPONENT_BY_JSON_DATATYPE.put(JsonDataType.NUMBER, new NumberFieldWrapper());\n        UI_COMPONENT_BY_JSON_DATATYPE.put(JsonDataType.NULL, new NullFieldWrapper());\n        UI_COMPONENT_BY_JSON_DATATYPE.put(JsonDataType.DATE, new DateTimeFieldWrapper());\n        UI_COMPONENT_BY_JSON_DATATYPE.put(JsonDataType.OBJECT, new JsonFieldWrapper());\n        UI_COMPONENT_BY_JSON_DATATYPE.put(JsonDataType.ARRAY, new JsonFieldWrapper());\n    }\n\n    final MongoEditionPanel mongoEditionPanel;\n    protected TextFieldWrapper currentEditor = null;\n\n\n    AbstractAddDialog(MongoEditionPanel mongoEditionPanel) {\n        super(mongoEditionPanel, true);\n        this.mongoEditionPanel = mongoEditionPanel;\n    }\n\n    void initCombo(final ComboBox combobox, final JPanel parentPanel) {\n        combobox.setModel(new DefaultComboBoxModel(JsonDataType.values()));\n        combobox.setRenderer(new ColoredListCellRenderer() {\n\n            @Override\n            protected void customizeCellRenderer(JList jList, Object o, int i, boolean b, boolean b2) {\n                append(((JsonDataType) o).type);\n            }\n        });\n\n        combobox.setSelectedItem(null);\n        combobox.addItemListener(new ItemListener() {\n\n            @Override\n            public void itemStateChanged(ItemEvent itemEvent) {\n                JsonDataType selectedType = (JsonDataType) combobox.getSelectedItem();\n                currentEditor = UI_COMPONENT_BY_JSON_DATATYPE.get(selectedType);\n                currentEditor.reset();\n\n                parentPanel.invalidate();\n                parentPanel.removeAll();\n                parentPanel.add(currentEditor.getComponent(), BorderLayout.CENTER);\n                parentPanel.validate();\n            }\n        });\n\n        combobox.setSelectedItem(JsonDataType.STRING);\n    }\n\n    public abstract Object getValue();\n\n    public static abstract class TextFieldWrapper<T extends JComponent, V> {\n\n        protected final T component;\n\n        private TextFieldWrapper(T component) {\n            this.component = component;\n        }\n\n        public abstract V getValue();\n\n        public abstract void reset();\n\n        public boolean isValueSet() {\n            return true;\n        }\n\n        public T getComponent() {\n            return component;\n        }\n\n        public void validate() {\n            if (!isValueSet()) {\n                throw new IllegalArgumentException(\"Value is not set\");\n            }\n        }\n    }\n\n    private static class StringFieldWrapper extends TextFieldWrapper<JTextField, String> {\n\n        private StringFieldWrapper() {\n            super(new JTextField());\n        }\n\n        @Override\n        public String getValue() {\n            return component.getText();\n        }\n\n        @Override\n        public boolean isValueSet() {\n            return StringUtils.isNotBlank(component.getText());\n        }\n\n        @Override\n        public void reset() {\n            component.setText(\"\");\n        }\n    }\n\n    private static class JsonFieldWrapper extends TextFieldWrapper<JTextField, Object> {\n\n        private JsonFieldWrapper() {\n            super(new JTextField());\n        }\n\n        @Override\n        public Object getValue() {\n            return JSON.parse(component.getText());\n        }\n\n        @Override\n        public boolean isValueSet() {\n            return StringUtils.isNotBlank(component.getText());\n        }\n\n        @Override\n        public void reset() {\n            component.setText(\"\");\n        }\n    }\n\n    private static class NumberFieldWrapper extends TextFieldWrapper<JTextField, Number> {\n\n        private NumberFieldWrapper() {\n            super(new JTextField());\n        }\n\n        @Override\n        public Number getValue() {\n            return org.codinjutsu.tools.nosql.commons.utils.StringUtils.parseNumber(component.getText());\n        }\n\n        @Override\n        public void reset() {\n            component.setText(\"\");\n        }\n\n        @Override\n        public boolean isValueSet() {\n            return StringUtils.isNotBlank(component.getText());\n        }\n\n        @Override\n        public void validate() {\n            super.validate();\n            getValue();\n        }\n    }\n\n    private static class BooleanFieldWrapper extends TextFieldWrapper<JBCheckBox, Boolean> {\n\n        private BooleanFieldWrapper() {\n            super(new JBCheckBox());\n        }\n\n        @Override\n        public Boolean getValue() {\n            return component.isSelected();\n        }\n\n        @Override\n        public void reset() {\n            component.setSelected(false);\n        }\n    }\n\n    private static class NullFieldWrapper extends TextFieldWrapper<JLabel, Object> {\n\n        private NullFieldWrapper() {\n            super(new JLabel(\"null\"));\n        }\n\n        @Override\n        public Object getValue() {\n            return null;\n        }\n\n        @Override\n        public void reset() {\n\n        }\n    }\n\n    private static class DateTimeFieldWrapper extends TextFieldWrapper<DateTimePicker, Date> {\n\n        private DateTimeFieldWrapper() {\n            super(DateTimePicker.create());\n            component.getEditor().setEditable(false);\n        }\n\n        @Override\n        public Date getValue() {\n            return component.getDate();\n        }\n\n        @Override\n        public boolean isValueSet() {\n            return component.getDate() != null;\n        }\n\n        @Override\n        public void reset() {\n            component.setDate(GregorianCalendar.getInstance().getTime());\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/AddKeyDialog.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<form xmlns=\"http://www.intellij.com/uidesigner/form/\" version=\"1\" bind-to-class=\"org.codinjutsu.tools.nosql.mongo.view.AddKeyDialog\">\n  <grid id=\"27dc6\" binding=\"mainPanel\" layout-manager=\"GridLayoutManager\" row-count=\"4\" column-count=\"2\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n    <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n    <constraints>\n      <xy x=\"20\" y=\"20\" width=\"500\" height=\"400\"/>\n    </constraints>\n    <properties/>\n    <border type=\"none\"/>\n    <children>\n      <component id=\"40aee\" class=\"javax.swing.JTextField\" binding=\"nameTextfield\">\n        <constraints>\n          <grid row=\"0\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"6\" anchor=\"8\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\">\n            <preferred-size width=\"150\" height=\"-1\"/>\n          </grid>\n        </constraints>\n        <properties/>\n      </component>\n      <vspacer id=\"a806\">\n        <constraints>\n          <grid row=\"3\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"6\" hsize-policy=\"1\" anchor=\"0\" fill=\"2\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n      </vspacer>\n      <component id=\"1c3f9\" class=\"javax.swing.JLabel\">\n        <constraints>\n          <grid row=\"0\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties>\n          <text value=\"Name:\"/>\n        </properties>\n      </component>\n      <component id=\"163c6\" class=\"javax.swing.JLabel\">\n        <constraints>\n          <grid row=\"1\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties>\n          <text value=\"Type:\"/>\n        </properties>\n      </component>\n      <component id=\"4ca52\" class=\"javax.swing.JLabel\">\n        <constraints>\n          <grid row=\"2\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties>\n          <text value=\"Value:\"/>\n        </properties>\n      </component>\n      <grid id=\"569af\" binding=\"valuePanel\" layout-manager=\"GridLayoutManager\" row-count=\"1\" column-count=\"1\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n        <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n        <constraints>\n          <grid row=\"2\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n        <border type=\"none\"/>\n        <children/>\n      </grid>\n      <component id=\"609e5\" class=\"com.intellij.openapi.ui.ComboBox\" binding=\"typeCombobox\">\n        <constraints>\n          <grid row=\"1\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n      </component>\n    </children>\n  </grid>\n</form>\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/AddKeyDialog.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view;\n\nimport com.intellij.openapi.ui.ComboBox;\nimport com.intellij.openapi.ui.ValidationInfo;\nimport org.apache.commons.lang.StringUtils;\nimport org.codinjutsu.tools.nosql.commons.utils.GuiUtils;\nimport org.jetbrains.annotations.Nullable;\n\nimport javax.swing.*;\nimport java.awt.*;\n\npublic class AddKeyDialog extends AbstractAddDialog {\n\n\n    private JTextField nameTextfield;\n    private ComboBox typeCombobox;\n    private JPanel valuePanel;\n    private JPanel mainPanel;\n\n    private AddKeyDialog(MongoEditionPanel mongoEditionPanel) {\n        super(mongoEditionPanel);\n        mainPanel.setPreferredSize(GuiUtils.enlargeWidth(mainPanel.getPreferredSize(), 1.5d));\n        valuePanel.setLayout(new BorderLayout());\n        nameTextfield.setName(\"keyName\");\n        typeCombobox.setName(\"valueType\");\n    }\n\n    @Nullable\n    @Override\n    protected JComponent createCenterPanel() {\n        return mainPanel;\n    }\n\n    public static AddKeyDialog createDialog(MongoEditionPanel parentPanel) {\n        AddKeyDialog dialog = new AddKeyDialog(parentPanel);\n        dialog.init();\n        dialog.setTitle(\"Add A Key\");\n\n        return dialog;\n    }\n\n    @Override\n    protected void init() {\n        super.init();\n        initCombo(typeCombobox, valuePanel);\n    }\n\n    @Nullable\n    @Override\n    protected ValidationInfo doValidate() {\n        String keyName = getKey();\n        if (StringUtils.isBlank(keyName)) {\n            return new ValidationInfo(\"Key name is not set\");\n        }\n\n        if (mongoEditionPanel.containsKey(keyName)) {\n            return new ValidationInfo(String.format(\"Key '%s' is already used\", keyName));\n        }\n\n        try {\n            currentEditor.validate();\n        } catch (Exception ex) {\n            return new ValidationInfo(ex.getMessage());\n        }\n\n        return null;\n    }\n\n    @Nullable\n    @Override\n    public JComponent getPreferredFocusedComponent() {\n        return nameTextfield;\n    }\n\n    public String getKey() {\n        return nameTextfield.getText();\n    }\n\n    @Override\n    public Object getValue() {\n        return currentEditor.getValue();\n    }\n}"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/AddValueDialog.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<form xmlns=\"http://www.intellij.com/uidesigner/form/\" version=\"1\" bind-to-class=\"org.codinjutsu.tools.nosql.mongo.view.AddValueDialog\">\n  <grid id=\"27dc6\" binding=\"mainPanel\" layout-manager=\"GridLayoutManager\" row-count=\"3\" column-count=\"2\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n    <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n    <constraints>\n      <xy x=\"20\" y=\"20\" width=\"500\" height=\"400\"/>\n    </constraints>\n    <properties/>\n    <border type=\"none\"/>\n    <children>\n      <vspacer id=\"a806\">\n        <constraints>\n          <grid row=\"2\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"6\" hsize-policy=\"1\" anchor=\"0\" fill=\"2\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n      </vspacer>\n      <component id=\"163c6\" class=\"javax.swing.JLabel\">\n        <constraints>\n          <grid row=\"0\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties>\n          <text value=\"Type:\"/>\n        </properties>\n      </component>\n      <component id=\"4ca52\" class=\"javax.swing.JLabel\">\n        <constraints>\n          <grid row=\"1\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties>\n          <text value=\"Value:\"/>\n        </properties>\n      </component>\n      <grid id=\"569af\" binding=\"valuePanel\" layout-manager=\"GridLayoutManager\" row-count=\"1\" column-count=\"1\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n        <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n        <constraints>\n          <grid row=\"1\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n        <border type=\"none\"/>\n        <children/>\n      </grid>\n      <component id=\"609e5\" class=\"com.intellij.openapi.ui.ComboBox\" binding=\"typeCombobox\">\n        <constraints>\n          <grid row=\"0\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n      </component>\n    </children>\n  </grid>\n</form>\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/AddValueDialog.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view;\n\nimport com.intellij.openapi.ui.ComboBox;\nimport com.intellij.openapi.ui.ValidationInfo;\nimport org.jetbrains.annotations.Nullable;\n\nimport javax.swing.*;\nimport java.awt.*;\n\npublic class AddValueDialog extends AbstractAddDialog {\n\n\n    private ComboBox typeCombobox;\n    private JPanel valuePanel;\n    private JPanel mainPanel;\n\n    private AddValueDialog(MongoEditionPanel mongoEditionPanel) {\n        super(mongoEditionPanel);\n        valuePanel.setLayout(new BorderLayout());\n        typeCombobox.setName(\"valueType\");\n        typeCombobox.requestFocus();\n    }\n\n    @Nullable\n    @Override\n    protected JComponent createCenterPanel() {\n        return mainPanel;\n    }\n\n    public static AddValueDialog createDialog(MongoEditionPanel parentPanel) {\n        AddValueDialog dialog = new AddValueDialog(parentPanel);\n        dialog.init();\n        dialog.setTitle(\"Add A Value\");\n        return dialog;\n    }\n\n    @Override\n    protected void init() {\n        super.init();\n\n        initCombo(typeCombobox, valuePanel);\n    }\n\n    @Nullable\n    @Override\n    protected ValidationInfo doValidate() {\n        try {\n            currentEditor.validate();\n        } catch (Exception ex) {\n            return new ValidationInfo(ex.getMessage());\n        }\n\n        return null;\n    }\n\n    @Override\n    public Object getValue() {\n        return currentEditor.getValue();\n    }\n\n    @Nullable\n    @Override\n    public JComponent getPreferredFocusedComponent() {\n        return typeCombobox;\n    }\n}"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/JsonTreeTableView.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view;\n\nimport com.intellij.ui.TreeTableSpeedSearch;\nimport com.intellij.ui.treeStructure.treetable.ListTreeTableModelOnColumns;\nimport com.intellij.ui.treeStructure.treetable.TreeTable;\nimport com.intellij.ui.treeStructure.treetable.TreeTableModel;\nimport com.intellij.ui.treeStructure.treetable.TreeTableTree;\nimport com.intellij.util.containers.Convertor;\nimport com.intellij.util.ui.ColumnInfo;\nimport com.intellij.util.ui.UIUtil;\nimport com.intellij.util.ui.tree.TreeUtil;\nimport com.mongodb.DBObject;\nimport org.bson.types.ObjectId;\nimport org.codinjutsu.tools.nosql.commons.view.NoSqlTreeNode;\nimport org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor;\nimport org.codinjutsu.tools.nosql.commons.view.renderer.KeyCellRenderer;\nimport org.codinjutsu.tools.nosql.commons.view.renderer.ValueCellRenderer;\nimport org.codinjutsu.tools.nosql.commons.view.table.CellEditor;\nimport org.codinjutsu.tools.nosql.mongo.view.table.MongoDatePickerCellEditor;\nimport org.jetbrains.annotations.Nullable;\n\nimport javax.swing.table.TableCellEditor;\nimport javax.swing.table.TableCellRenderer;\nimport javax.swing.tree.TreeNode;\nimport javax.swing.tree.TreePath;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.util.Date;\n\npublic class JsonTreeTableView extends TreeTable {\n\n    private static final ColumnInfo KEY = new ColumnInfo(\"Key\") {\n\n        public Object valueOf(Object obj) {\n            NoSqlTreeNode node = (NoSqlTreeNode) obj;\n            return node.getDescriptor();\n        }\n\n        @Override\n        public Class getColumnClass() {\n            return TreeTableModel.class;\n        }\n\n        @Override\n        public boolean isCellEditable(Object o) {\n            return false;\n        }\n    };\n\n    private static final ColumnInfo READONLY_VALUE = new ReadOnlyValueColumnInfo();\n\n    private static final ColumnInfo WRITABLE_VALUE = new WritableColumnInfo();\n\n    public static final ColumnInfo[] COLUMNS_FOR_READING = new ColumnInfo[]{KEY, READONLY_VALUE};\n    public static final ColumnInfo[] COLUMNS_FOR_WRITING = new ColumnInfo[]{KEY, WRITABLE_VALUE};\n\n    private final ColumnInfo[] columns;\n\n    public JsonTreeTableView(TreeNode rootNode, ColumnInfo[] columnInfos) {\n        super(new ListTreeTableModelOnColumns(rootNode, columnInfos));\n        this.columns = columnInfos;\n\n        final TreeTableTree tree = getTree();\n\n        tree.setShowsRootHandles(true);\n        tree.setRootVisible(false);\n        UIUtil.setLineStyleAngled(tree);\n        setTreeCellRenderer(new KeyCellRenderer());\n\n        TreeUtil.expand(tree, 2);\n\n        new TreeTableSpeedSearch(this, new Convertor<TreePath, String>() {\n            @Override\n            public String convert(final TreePath path) {\n                final NoSqlTreeNode node = (NoSqlTreeNode) path.getLastPathComponent();\n                NodeDescriptor descriptor = node.getDescriptor();\n                return descriptor.getFormattedKey();\n            }\n        });\n    }\n\n    @Override\n    public TableCellRenderer getCellRenderer(int row, int column) {\n        TreePath treePath = getTree().getPathForRow(row);\n        if (treePath == null) return super.getCellRenderer(row, column);\n\n        NoSqlTreeNode node = (NoSqlTreeNode) treePath.getLastPathComponent();\n\n        TableCellRenderer renderer = this.columns[column].getRenderer(node);\n        return renderer == null ? super.getCellRenderer(row, column) : renderer;\n    }\n\n    @Override\n    public TableCellEditor getCellEditor(int row, int column) {\n        TreePath treePath = getTree().getPathForRow(row);\n        if (treePath == null) return super.getCellEditor(row, column);\n\n        NoSqlTreeNode node = (NoSqlTreeNode) treePath.getLastPathComponent();\n        TableCellEditor editor = columns[column].getEditor(node);\n        return editor == null ? super.getCellEditor(row, column) : editor;\n    }\n\n    private static class ReadOnlyValueColumnInfo extends ColumnInfo<NoSqlTreeNode, NodeDescriptor> {\n        private final TableCellRenderer myRenderer = new ValueCellRenderer();\n\n        public ReadOnlyValueColumnInfo() {\n            super(\"Value\");\n        }\n\n        public NodeDescriptor valueOf(NoSqlTreeNode treeNode) {\n            return treeNode.getDescriptor();\n        }\n\n        @Override\n        public TableCellRenderer getRenderer(NoSqlTreeNode o) {\n            return myRenderer;\n        }\n\n        @Override\n        public boolean isCellEditable(NoSqlTreeNode o) {\n            return false;\n        }\n    }\n\n    private static class WritableColumnInfo extends ColumnInfo<NoSqlTreeNode, Object> {\n\n        private final TableCellRenderer myRenderer = new ValueCellRenderer();\n        private final TableCellEditor defaultEditor = new CellEditor();\n\n\n        public WritableColumnInfo() {\n            super(\"Value\");\n        }\n\n        @Override\n        public TableCellRenderer getRenderer(NoSqlTreeNode o) {\n            return myRenderer;\n        }\n\n\n        @Override\n        public boolean isCellEditable(NoSqlTreeNode treeNode) {\n            Object value = treeNode.getDescriptor().getValue();\n            if (value instanceof DBObject) {\n                return false;\n            }\n\n            if (value instanceof ObjectId) {\n                return false;\n            }\n\n            return true;\n        }\n\n        @Nullable\n        @Override\n        public TableCellEditor getEditor(final NoSqlTreeNode treeNode) {\n            Object value = treeNode.getDescriptor().getValue();\n            if (value instanceof Date) {\n                return buildDateCellEditor(treeNode);\n            }\n            return defaultEditor;\n        }\n\n        private static MongoDatePickerCellEditor buildDateCellEditor(final NoSqlTreeNode treeNode) {\n            final MongoDatePickerCellEditor dateEditor = new MongoDatePickerCellEditor();\n\n//  Note from dev: Quite ugly because when clicking on the button to open popup calendar, stopCellEdition is invoked.\n//                 From that point, impossible to set the selected data in the node description\n            dateEditor.addActionListener(new ActionListener() {\n                @Override\n                public void actionPerformed(ActionEvent actionEvent) {\n                    treeNode.getDescriptor().setValue(dateEditor.getCellEditorValue());\n                }\n            });\n            return dateEditor;\n        }\n\n        public Object valueOf(NoSqlTreeNode treeNode) {\n            return treeNode.getDescriptor().getValue();\n\n        }\n\n        @Override\n        public void setValue(NoSqlTreeNode treeNode, Object value) {\n            treeNode.getDescriptor().setValue(value);\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/MongoAuthenticationPanel.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<form xmlns=\"http://www.intellij.com/uidesigner/form/\" version=\"1\" bind-to-class=\"org.codinjutsu.tools.nosql.mongo.view.MongoAuthenticationPanel\">\n  <grid id=\"27dc6\" binding=\"mainPanel\" layout-manager=\"GridLayoutManager\" row-count=\"6\" column-count=\"2\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n    <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n    <constraints>\n      <xy x=\"20\" y=\"20\" width=\"554\" height=\"400\"/>\n    </constraints>\n    <properties/>\n    <border type=\"none\"/>\n    <children>\n      <vspacer id=\"601e4\">\n        <constraints>\n          <grid row=\"5\" column=\"0\" row-span=\"1\" col-span=\"2\" vsize-policy=\"6\" hsize-policy=\"1\" anchor=\"0\" fill=\"2\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n      </vspacer>\n      <component id=\"10762\" class=\"javax.swing.JLabel\">\n        <constraints>\n          <grid row=\"0\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties>\n          <text value=\"Username:\"/>\n        </properties>\n      </component>\n      <component id=\"ca620\" class=\"javax.swing.JTextField\" binding=\"usernameField\">\n        <constraints>\n          <grid row=\"0\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"6\" anchor=\"8\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties>\n          <editable value=\"true\"/>\n          <enabled value=\"true\"/>\n        </properties>\n      </component>\n      <component id=\"72296\" class=\"javax.swing.JLabel\">\n        <constraints>\n          <grid row=\"1\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties>\n          <text value=\"Password:\"/>\n        </properties>\n      </component>\n      <component id=\"64e8a\" class=\"javax.swing.JPasswordField\" binding=\"passwordField\">\n        <constraints>\n          <grid row=\"1\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"6\" anchor=\"8\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\">\n            <preferred-size width=\"150\" height=\"-1\"/>\n          </grid>\n        </constraints>\n        <properties/>\n      </component>\n      <component id=\"e152c\" class=\"javax.swing.JLabel\">\n        <constraints>\n          <grid row=\"2\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties>\n          <text value=\"Auth. database:\"/>\n        </properties>\n      </component>\n      <component id=\"17242\" class=\"javax.swing.JTextField\" binding=\"authenticationDatabaseField\">\n        <constraints>\n          <grid row=\"2\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"6\" anchor=\"8\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties>\n          <editable value=\"true\"/>\n          <enabled value=\"true\"/>\n        </properties>\n      </component>\n      <component id=\"c1e11\" class=\"javax.swing.JLabel\">\n        <constraints>\n          <grid row=\"3\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties>\n          <text value=\"Auth. mecanism:\"/>\n        </properties>\n      </component>\n      <grid id=\"d4fcd\" layout-manager=\"GridLayoutManager\" row-count=\"1\" column-count=\"4\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n        <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n        <constraints>\n          <grid row=\"3\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n        <border type=\"none\"/>\n        <children>\n          <hspacer id=\"134f5\">\n            <constraints>\n              <grid row=\"0\" column=\"3\" row-span=\"1\" col-span=\"1\" vsize-policy=\"1\" hsize-policy=\"6\" anchor=\"0\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\"/>\n            </constraints>\n          </hspacer>\n          <component id=\"ab945\" class=\"javax.swing.JRadioButton\" binding=\"scramSHA1AuthRadioButton\">\n            <constraints>\n              <grid row=\"0\" column=\"2\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"3\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n            </constraints>\n            <properties>\n              <text value=\"SCRAM-SHA-1\"/>\n            </properties>\n          </component>\n          <component id=\"57866\" class=\"javax.swing.JRadioButton\" binding=\"mongoCRAuthRadioButton\">\n            <constraints>\n              <grid row=\"0\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"3\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n            </constraints>\n            <properties>\n              <text value=\"MONGODB-CR\"/>\n            </properties>\n          </component>\n          <component id=\"6f1e7\" class=\"javax.swing.JRadioButton\" binding=\"defaultAuthMethodRadioButton\">\n            <constraints>\n              <grid row=\"0\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"3\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n            </constraints>\n            <properties>\n              <text value=\"Default\"/>\n            </properties>\n          </component>\n        </children>\n      </grid>\n      <component id=\"c3dc0\" class=\"javax.swing.JCheckBox\" binding=\"sslConnectionField\">\n        <constraints>\n          <grid row=\"4\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"3\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties>\n          <text value=\"SSL connection \"/>\n        </properties>\n      </component>\n    </children>\n  </grid>\n</form>\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/MongoAuthenticationPanel.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view;\n\nimport com.mongodb.AuthenticationMechanism;\nimport org.apache.commons.lang.StringUtils;\nimport org.codinjutsu.tools.nosql.commons.model.AuthenticationSettings;\nimport org.codinjutsu.tools.nosql.commons.view.AuthenticationView;\nimport org.codinjutsu.tools.nosql.mongo.logic.MongoExtraSettings;\n\nimport javax.swing.*;\n\npublic class MongoAuthenticationPanel implements AuthenticationView {\n    private JPanel mainPanel;\n    private JTextField usernameField;\n    private JPasswordField passwordField;\n    private JTextField authenticationDatabaseField;\n    private JRadioButton scramSHA1AuthRadioButton;\n    private JRadioButton mongoCRAuthRadioButton;\n    private JRadioButton defaultAuthMethodRadioButton;\n    private JCheckBox sslConnectionField;\n\n\n    public MongoAuthenticationPanel() {\n        usernameField.setName(\"usernameField\");\n        passwordField.setName(\"passwordField\");\n        authenticationDatabaseField.setName(\"authenticationDatabaseField\");\n        mongoCRAuthRadioButton.setName(\"mongoCRAuthField\");\n        scramSHA1AuthRadioButton.setName(\"scramSHA1AuthField\");\n        defaultAuthMethodRadioButton.setName(\"defaultAuthMethod\");\n        sslConnectionField.setName(\"sslConnectionField\");\n\n        ButtonGroup authMethodGroup = new ButtonGroup();\n        authMethodGroup.add(mongoCRAuthRadioButton);\n        authMethodGroup.add(scramSHA1AuthRadioButton);\n        authMethodGroup.add(defaultAuthMethodRadioButton);\n\n        defaultAuthMethodRadioButton.setSelected(true);\n        defaultAuthMethodRadioButton.setToolTipText(\"Let the driver resolves the auth. mecanism\");\n    }\n\n    @Override\n    public JPanel getComponent() {\n        return mainPanel;\n    }\n\n    @Override\n    public AuthenticationSettings create() {\n        AuthenticationSettings authenticationSettings = new AuthenticationSettings();\n        authenticationSettings.setUsername(getUsername());\n        authenticationSettings.setPassword(getPassword());\n\n        MongoExtraSettings mongoExtraSettings = new MongoExtraSettings();\n        mongoExtraSettings.setSsl(isSslConnection());\n        mongoExtraSettings.setAuthenticationDatabase(getAuthenticationDatabase());\n        mongoExtraSettings.setAuthenticationMechanism(getAuthenticationMechanism());\n        authenticationSettings.setExtras(mongoExtraSettings.get());\n\n        return authenticationSettings;\n    }\n\n    @Override\n    public void load(AuthenticationSettings settings) {\n        usernameField.setText(settings.getUsername());\n        passwordField.setText(settings.getPassword());\n        MongoExtraSettings mongoExtraSettings = new MongoExtraSettings(settings.getExtras());\n        authenticationDatabaseField.setText(mongoExtraSettings.getAuthenticationDatabase());\n        sslConnectionField.setSelected(mongoExtraSettings.isSsl());\n        AuthenticationMechanism authentificationMethod = mongoExtraSettings.getAuthenticationMechanism();\n        if (AuthenticationMechanism.MONGODB_CR.equals(authentificationMethod)) {\n            mongoCRAuthRadioButton.setSelected(true);\n        } else if (AuthenticationMechanism.SCRAM_SHA_1.equals(authentificationMethod)) {\n            scramSHA1AuthRadioButton.setSelected(true);\n        } else {\n            defaultAuthMethodRadioButton.setSelected(true);\n        }\n    }\n\n    private boolean isSslConnection() {\n        return sslConnectionField.isSelected();\n    }\n\n    private String getUsername() {\n        String username = usernameField.getText();\n        if (StringUtils.isNotBlank(username)) {\n            return username;\n        }\n        return null;\n    }\n\n    private String getPassword() {\n        char[] password = passwordField.getPassword();\n        if (password != null && password.length != 0) {\n            return String.valueOf(password);\n        }\n        return null;\n    }\n\n    private String getAuthenticationDatabase() {\n        String authenticationDatabase = authenticationDatabaseField.getText();\n        if (StringUtils.isNotBlank(authenticationDatabase)) {\n            return authenticationDatabase;\n        }\n        return null;\n    }\n\n    private AuthenticationMechanism getAuthenticationMechanism() {\n        if (mongoCRAuthRadioButton.isSelected()) {\n            return AuthenticationMechanism.MONGODB_CR;\n        } else if (scramSHA1AuthRadioButton.isSelected()) {\n            return AuthenticationMechanism.SCRAM_SHA_1;\n        }\n        return null;\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/MongoEditionPanel.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<form xmlns=\"http://www.intellij.com/uidesigner/form/\" version=\"1\" bind-to-class=\"org.codinjutsu.tools.nosql.mongo.view.MongoEditionPanel\">\n  <grid id=\"27dc6\" binding=\"mainPanel\" layout-manager=\"GridLayoutManager\" row-count=\"2\" column-count=\"1\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n    <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n    <constraints>\n      <xy x=\"20\" y=\"20\" width=\"500\" height=\"400\"/>\n    </constraints>\n    <properties/>\n    <border type=\"none\" title=\"Edition\">\n      <title-color color=\"-16777216\"/>\n    </border>\n    <children>\n      <grid id=\"b613a\" binding=\"editionTreePanel\" layout-manager=\"GridLayoutManager\" row-count=\"1\" column-count=\"1\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n        <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n        <constraints>\n          <grid row=\"0\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n        <border type=\"none\"/>\n        <children/>\n      </grid>\n      <grid id=\"83e3a\" layout-manager=\"GridLayoutManager\" row-count=\"1\" column-count=\"4\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n        <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n        <constraints>\n          <grid row=\"1\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"3\" anchor=\"2\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n        <border type=\"none\"/>\n        <children>\n          <component id=\"75efd\" class=\"javax.swing.JButton\" binding=\"saveButton\" default-binding=\"true\">\n            <constraints>\n              <grid row=\"0\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"3\" anchor=\"0\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\"/>\n            </constraints>\n            <properties>\n              <text value=\"Save\"/>\n            </properties>\n          </component>\n          <component id=\"737a5\" class=\"javax.swing.JButton\" binding=\"cancelButton\" default-binding=\"true\">\n            <constraints>\n              <grid row=\"0\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"3\" anchor=\"0\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\"/>\n            </constraints>\n            <properties>\n              <text value=\"Cancel\"/>\n            </properties>\n          </component>\n          <component id=\"84a16\" class=\"javax.swing.JButton\" binding=\"deleteButton\" default-binding=\"true\">\n            <constraints>\n              <grid row=\"0\" column=\"3\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"3\" anchor=\"0\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\"/>\n            </constraints>\n            <properties>\n              <text value=\"Delete Document\"/>\n            </properties>\n          </component>\n          <hspacer id=\"3f3cb\">\n            <constraints>\n              <grid row=\"0\" column=\"2\" row-span=\"1\" col-span=\"1\" vsize-policy=\"1\" hsize-policy=\"6\" anchor=\"0\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\"/>\n            </constraints>\n          </hspacer>\n        </children>\n      </grid>\n    </children>\n  </grid>\n</form>\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/MongoEditionPanel.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view;\n\nimport com.intellij.openapi.Disposable;\nimport com.intellij.openapi.actionSystem.ActionManager;\nimport com.intellij.openapi.actionSystem.DefaultActionGroup;\nimport com.intellij.openapi.application.ApplicationManager;\nimport com.intellij.ui.IdeBorderFactory;\nimport com.intellij.ui.PopupHandler;\nimport com.intellij.ui.components.JBScrollPane;\nimport com.intellij.util.ui.tree.TreeUtil;\nimport com.mongodb.DBObject;\nimport org.apache.commons.lang.StringUtils;\nimport org.codinjutsu.tools.nosql.commons.view.NoSqlTreeNode;\nimport org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor;\nimport org.codinjutsu.tools.nosql.mongo.view.action.edition.AddKeyAction;\nimport org.codinjutsu.tools.nosql.mongo.view.action.edition.AddValueAction;\nimport org.codinjutsu.tools.nosql.mongo.view.action.edition.DeleteKeyAction;\nimport org.codinjutsu.tools.nosql.mongo.view.model.JsonTreeModel;\nimport org.codinjutsu.tools.nosql.mongo.view.nodedescriptor.MongoKeyValueDescriptor;\nimport org.codinjutsu.tools.nosql.mongo.view.nodedescriptor.MongoValueDescriptor;\n\nimport javax.swing.*;\nimport javax.swing.tree.DefaultTreeModel;\nimport javax.swing.tree.TreeNode;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.util.Enumeration;\nimport java.util.LinkedList;\nimport java.util.List;\n\npublic class MongoEditionPanel extends JPanel implements Disposable {\n    private JButton saveButton;\n    private JButton cancelButton;\n    private JPanel editionTreePanel;\n    private JPanel mainPanel;\n    private JButton deleteButton;\n\n    private JsonTreeTableView editTableView;\n\n\n    public MongoEditionPanel() {\n        super(new BorderLayout());\n\n        add(mainPanel);\n        editionTreePanel.setLayout(new BorderLayout());\n\n        saveButton.setName(\"saveButton\");\n        cancelButton.setName(\"cancelButton\");\n        deleteButton.setName(\"deleteButton\");\n    }\n\n    public MongoEditionPanel init(final MongoPanel.MongoDocumentOperations mongoDocumentOperations, final MongoResultPanel.ActionCallback actionCallback) {\n\n        cancelButton.addActionListener(new AbstractAction() {\n            @Override\n            public void actionPerformed(ActionEvent actionEvent) {\n                actionCallback.onOperationCancelled(\"Modification canceled...\");\n            }\n        });\n\n        saveButton.addActionListener(new AbstractAction() {\n            @Override\n            public void actionPerformed(ActionEvent actionEvent) {\n                try {\n                    mongoDocumentOperations.updateMongoDocument(buildMongoDocument());\n                    actionCallback.onOperationSuccess(\"Document saved...\");\n                } catch (Exception exception) {\n                    actionCallback.onOperationFailure(exception);\n                }\n            }\n        });\n\n        deleteButton.addActionListener(new AbstractAction() {\n            @Override\n            public void actionPerformed(ActionEvent actionEvent) {\n                try {\n                    mongoDocumentOperations.deleteMongoDocument(getDocumentId());\n                    actionCallback.onOperationSuccess(\"Document deleted...\");\n                } catch (Exception exception) {\n                    actionCallback.onOperationFailure(exception);\n                }\n            }\n        });\n\n        return this;\n    }\n\n    public void updateEditionTree(DBObject mongoDocument) {\n        String panelTitle = \"New document\";\n        if (mongoDocument != null) {\n            panelTitle = \"Edition\";\n        }\n\n        mainPanel.setBorder(IdeBorderFactory.createTitledBorder(panelTitle, true));\n        editTableView = new JsonTreeTableView(JsonTreeModel.buildJsonTree(mongoDocument), JsonTreeTableView.COLUMNS_FOR_WRITING);\n        editTableView.setName(\"editionTreeTable\");\n\n        editionTreePanel.invalidate();\n        editionTreePanel.removeAll();\n        editionTreePanel.add(new JBScrollPane(editTableView));\n        editionTreePanel.validate();\n\n        buildPopupMenu();\n    }\n\n    void buildPopupMenu() {\n        DefaultActionGroup actionPopupGroup = new DefaultActionGroup(\"MongoEditorPopupGroup\", true);\n        if (ApplicationManager.getApplication() != null) {\n            actionPopupGroup.add(new AddKeyAction(this));\n            actionPopupGroup.add(new AddValueAction(this));\n            actionPopupGroup.add(new DeleteKeyAction(this));\n        }\n\n        PopupHandler.installPopupHandler(editTableView, actionPopupGroup, \"POPUP\", ActionManager.getInstance());\n    }\n\n    public boolean containsKey(String key) {\n        NoSqlTreeNode parentNode = getParentNode();\n        if (parentNode == null) {\n            return false;\n        }\n\n        Enumeration children = parentNode.children();\n        while (children.hasMoreElements()) {\n            NoSqlTreeNode childNode = (NoSqlTreeNode) children.nextElement();\n            NodeDescriptor descriptor = childNode.getDescriptor();\n            if (descriptor instanceof MongoKeyValueDescriptor) {\n                MongoKeyValueDescriptor keyValueDescriptor = (MongoKeyValueDescriptor) descriptor;\n                if (StringUtils.equals(key, keyValueDescriptor.getKey())) {\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n\n    public void addKey(String key, Object value) {\n\n        List<TreeNode> node = new LinkedList<TreeNode>();\n        NoSqlTreeNode treeNode = new NoSqlTreeNode(MongoKeyValueDescriptor.createDescriptor(key, value));\n\n        if (value instanceof DBObject) {\n            JsonTreeModel.processDbObject(treeNode, (DBObject) value);\n        }\n\n        node.add(treeNode);\n\n        DefaultTreeModel treeModel = (DefaultTreeModel) editTableView.getTree().getModel();\n        NoSqlTreeNode parentNode = getParentNode();\n        if (parentNode == null) {\n            parentNode = (NoSqlTreeNode) treeModel.getRoot();\n        }\n        TreeUtil.addChildrenTo(parentNode, node);\n        treeModel.reload(parentNode);\n    }\n\n    public void addValue(Object value) {\n        List<TreeNode> node = new LinkedList<TreeNode>();\n\n        NoSqlTreeNode parentNode = getParentNode();\n\n        NoSqlTreeNode treeNode = new NoSqlTreeNode(MongoValueDescriptor.createDescriptor(parentNode.getChildCount(), value));\n        if (value instanceof DBObject) {\n            JsonTreeModel.processDbObject(treeNode, (DBObject) value);\n        }\n\n        node.add(treeNode);\n\n        DefaultTreeModel treeModel = (DefaultTreeModel) editTableView.getTree().getModel();\n        TreeUtil.addChildrenTo(parentNode, node);\n        treeModel.reload(parentNode);\n    }\n\n    private NoSqlTreeNode getParentNode() {\n        NoSqlTreeNode lastPathComponent = getSelectedNode();\n        if (lastPathComponent == null) {\n            return null;\n        }\n        return (NoSqlTreeNode) lastPathComponent.getParent();\n    }\n\n    public NoSqlTreeNode getSelectedNode() {\n        return (NoSqlTreeNode) editTableView.getTree().getLastSelectedPathComponent();\n    }\n\n    public boolean canAddKey() {\n        NoSqlTreeNode selectedNode = getSelectedNode();\n        if (selectedNode == null) {\n            return false;\n        }\n        return selectedNode.getDescriptor() instanceof MongoKeyValueDescriptor;\n    }\n\n    public boolean canAddValue() {\n        NoSqlTreeNode selectedNode = getSelectedNode();\n        if (selectedNode == null) {\n            return false;\n        }\n        return selectedNode.getDescriptor() instanceof MongoValueDescriptor;\n    }\n\n    public void removeSelectedKey() {\n        NoSqlTreeNode selectedNode = getSelectedNode();\n        if (selectedNode == null) {\n            return;\n        }\n        TreeUtil.removeSelected(editTableView.getTree());\n\n    }\n\n    private DBObject buildMongoDocument() {\n        NoSqlTreeNode rootNode = (NoSqlTreeNode) editTableView.getTree().getModel().getRoot();\n        return JsonTreeModel.buildDBObject(rootNode);\n    }\n\n    @Override\n    public void dispose() {\n        editTableView = null;\n    }\n\n    private Object getDocumentId() {\n        NoSqlTreeNode rootNode = (NoSqlTreeNode) editTableView.getTree().getModel().getRoot();\n\n        return findObjectIdNodeDescriptor(rootNode).getDescriptor().getValue();\n    }\n\n    private NoSqlTreeNode findObjectIdNodeDescriptor(NoSqlTreeNode rootNode) {\n        return ((NoSqlTreeNode) rootNode.getChildAt(0));//TODO crappy\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/MongoPanel.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<form xmlns=\"http://www.intellij.com/uidesigner/form/\" version=\"1\" bind-to-class=\"org.codinjutsu.tools.nosql.mongo.view.MongoPanel\">\n  <grid id=\"27dc6\" binding=\"rootPanel\" layout-manager=\"GridLayoutManager\" row-count=\"3\" column-count=\"1\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n    <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n    <constraints>\n      <xy x=\"20\" y=\"20\" width=\"500\" height=\"400\"/>\n    </constraints>\n    <properties/>\n    <border type=\"none\"/>\n    <children>\n      <grid id=\"5b69b\" layout-manager=\"GridLayoutManager\" row-count=\"1\" column-count=\"1\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n        <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n        <constraints>\n          <grid row=\"1\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n        <border type=\"none\"/>\n        <children>\n          <component id=\"223ea\" class=\"com.intellij.openapi.ui.Splitter\" binding=\"splitter\">\n            <constraints>\n              <grid row=\"0\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\" indent=\"0\" use-parent-layout=\"false\"/>\n            </constraints>\n            <properties/>\n          </component>\n        </children>\n      </grid>\n      <grid id=\"e233e\" binding=\"toolBar\" layout-manager=\"GridLayoutManager\" row-count=\"1\" column-count=\"1\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n        <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n        <constraints>\n          <grid row=\"0\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n        <border type=\"none\"/>\n        <children/>\n      </grid>\n      <grid id=\"e3419\" binding=\"errorPanel\" layout-manager=\"GridLayoutManager\" row-count=\"1\" column-count=\"1\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n        <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n        <constraints>\n          <grid row=\"2\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n        <border type=\"none\"/>\n        <children/>\n      </grid>\n    </children>\n  </grid>\n</form>\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/MongoPanel.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view;\n\nimport com.intellij.ide.CommonActionsManager;\nimport com.intellij.ide.TreeExpander;\nimport com.intellij.openapi.Disposable;\nimport com.intellij.openapi.actionSystem.ActionManager;\nimport com.intellij.openapi.actionSystem.ActionToolbar;\nimport com.intellij.openapi.actionSystem.AnAction;\nimport com.intellij.openapi.actionSystem.DefaultActionGroup;\nimport com.intellij.openapi.application.ApplicationManager;\nimport com.intellij.openapi.progress.ProgressIndicator;\nimport com.intellij.openapi.progress.ProgressManager;\nimport com.intellij.openapi.progress.Task;\nimport com.intellij.openapi.project.Project;\nimport com.intellij.openapi.ui.LoadingDecorator;\nimport com.intellij.openapi.ui.Splitter;\nimport com.intellij.openapi.util.Disposer;\nimport com.intellij.ui.NumberDocument;\nimport com.intellij.ui.components.panels.NonOpaquePanel;\nimport com.mongodb.DBObject;\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.codinjutsu.tools.nosql.commons.utils.GuiUtils;\nimport org.codinjutsu.tools.nosql.commons.view.ErrorPanel;\nimport org.codinjutsu.tools.nosql.commons.view.NoSqlResultView;\nimport org.codinjutsu.tools.nosql.commons.view.action.ExecuteQuery;\nimport org.codinjutsu.tools.nosql.mongo.logic.MongoClient;\nimport org.codinjutsu.tools.nosql.mongo.model.MongoCollection;\nimport org.codinjutsu.tools.nosql.mongo.model.MongoResult;\nimport org.codinjutsu.tools.nosql.mongo.view.action.*;\nimport org.jetbrains.annotations.NotNull;\n\nimport javax.swing.*;\nimport java.awt.*;\n\npublic class MongoPanel extends NoSqlResultView<MongoCollection> {\n\n    private final LoadingDecorator loadingDecorator;\n    private JPanel rootPanel;\n    private Splitter splitter;\n    private JPanel toolBar;\n    private JPanel errorPanel;\n    private final JTextField rowLimitField = new JTextField(\"\");\n    private final MongoResultPanel resultPanel;\n    private final QueryPanel queryPanel;\n\n    private final Project project;\n    private final MongoClient mongoClient;\n    private final ServerConfiguration configuration;\n    private final MongoCollection mongoCollection;\n\n    public MongoPanel(Project project, final MongoClient mongoClient, final ServerConfiguration configuration, final MongoCollection mongoCollection) {\n        this.project = project;\n        this.mongoClient = mongoClient;\n        this.mongoCollection = mongoCollection;\n        this.configuration = configuration;\n\n        errorPanel.setLayout(new BorderLayout());\n\n        queryPanel = new QueryPanel(project);\n        queryPanel.setVisible(false);\n\n        resultPanel = createResultPanel(project, new MongoDocumentOperations() {\n\n            public DBObject getMongoDocument(Object _id) {\n                return mongoClient.findMongoDocument(configuration, mongoCollection, _id);\n            }\n\n            public void updateMongoDocument(DBObject mongoDocument) {\n                mongoClient.update(configuration, mongoCollection, mongoDocument);\n                executeQuery();\n            }\n\n            public void deleteMongoDocument(Object objectId) {\n                mongoClient.delete(configuration, mongoCollection, objectId);\n                executeQuery();\n            }\n        });\n\n        loadingDecorator = new LoadingDecorator(resultPanel, this, 0);\n\n\n        splitter.setOrientation(true);\n        splitter.setProportion(0.2f);\n        splitter.setSecondComponent(loadingDecorator.getComponent());\n\n        setLayout(new BorderLayout());\n        add(rootPanel);\n\n        initToolBar();\n    }\n\n    private void initToolBar() {\n        toolBar.setLayout(new BorderLayout());\n\n        rowLimitField.setColumns(5);\n        rowLimitField.setDocument(new NumberDocument());\n\n        JPanel rowLimitPanel = new NonOpaquePanel();\n        rowLimitPanel.add(new JLabel(\"Row limit:\"), BorderLayout.WEST);\n        rowLimitPanel.add(rowLimitField, BorderLayout.CENTER);\n        rowLimitPanel.add(Box.createHorizontalStrut(5), BorderLayout.EAST);\n        toolBar.add(rowLimitPanel, BorderLayout.WEST);\n\n        installResultPanelActions();\n    }\n\n    private MongoResultPanel createResultPanel(Project project, MongoDocumentOperations mongoDocumentOperations) {\n        return new MongoResultPanel(project, mongoDocumentOperations);\n    }\n\n\n    void installResultPanelActions() {\n        DefaultActionGroup actionResultGroup = new DefaultActionGroup(\"MongoResultGroup\", true);\n        if (ApplicationManager.getApplication() != null) {\n            actionResultGroup.add(new ExecuteQuery<MongoPanel>(this));\n            actionResultGroup.add(new OpenFindAction(this));\n            actionResultGroup.add(new EnableAggregateAction(queryPanel));\n            actionResultGroup.addSeparator();\n            actionResultGroup.add(new AddMongoDocumentAction(resultPanel));\n            actionResultGroup.add(new EditMongoDocumentAction(resultPanel));\n            actionResultGroup.add(new CopyResultAction(resultPanel));\n        }\n        final TreeExpander treeExpander = new TreeExpander() {\n            @Override\n            public void expandAll() {\n                resultPanel.expandAll();\n            }\n\n            @Override\n            public boolean canExpand() {\n                return true;\n            }\n\n            @Override\n            public void collapseAll() {\n                resultPanel.collapseAll();\n            }\n\n            @Override\n            public boolean canCollapse() {\n                return true;\n            }\n        };\n\n        CommonActionsManager actionsManager = CommonActionsManager.getInstance();\n\n        final AnAction expandAllAction = actionsManager.createExpandAllAction(treeExpander, resultPanel);\n        final AnAction collapseAllAction = actionsManager.createCollapseAllAction(treeExpander, resultPanel);\n\n        Disposer.register(this, new Disposable() {\n            @Override\n            public void dispose() {\n                collapseAllAction.unregisterCustomShortcutSet(resultPanel);\n                expandAllAction.unregisterCustomShortcutSet(resultPanel);\n            }\n        });\n\n        actionResultGroup.addSeparator();\n        actionResultGroup.add(expandAllAction);\n        actionResultGroup.add(collapseAllAction);\n        actionResultGroup.add(new CloseFindEditorAction(this));\n\n        ActionToolbar actionToolBar = ActionManager.getInstance().createActionToolbar(\"MongoResultGroupActions\", actionResultGroup, true);\n        actionToolBar.setLayoutPolicy(ActionToolbar.AUTO_LAYOUT_POLICY);\n        JComponent actionToolBarComponent = actionToolBar.getComponent();\n        actionToolBarComponent.setBorder(null);\n        actionToolBarComponent.setOpaque(false);\n\n        toolBar.add(actionToolBarComponent, BorderLayout.CENTER);\n    }\n\n    public MongoCollection getRecords() {\n        return mongoCollection;\n    }\n\n\n    public void showResults() {\n        executeQuery();\n    }\n\n    public void executeQuery() {\n        errorPanel.setVisible(false);\n        validateQuery();\n        ProgressManager.getInstance().run(new Task.Backgroundable(project, \"Executing query\", true)  {\n            @Override\n            public void run(@NotNull final ProgressIndicator indicator) {\n                try {\n                    GuiUtils.runInSwingThread(new Runnable() {\n                        @Override\n                        public void run() {\n                            loadingDecorator.startLoading(false);\n                        }\n                    });\n\n                    final MongoResult mongoResult = mongoClient.loadCollectionValues(configuration, mongoCollection, queryPanel.getQueryOptions(rowLimitField.getText()));\n                    GuiUtils.runInSwingThread(new Runnable() {\n                        @Override\n                        public void run() {\n                            resultPanel.updateResultTableTree(mongoResult);\n                        }\n                    });\n                } catch (final Exception ex) {\n                    GuiUtils.runInSwingThread(new Runnable() {\n                        @Override\n                        public void run() {\n                            errorPanel.invalidate();\n                            errorPanel.removeAll();\n                            errorPanel.add(new ErrorPanel(ex), BorderLayout.CENTER);\n                            errorPanel.validate();\n                            errorPanel.setVisible(true);\n                        }\n                    });\n                } finally {\n                    GuiUtils.runInSwingThread(new Runnable() {\n                        @Override\n                        public void run() {\n                            loadingDecorator.stopLoading();\n                        }\n                    });\n                }\n            }\n        });\n    }\n\n    private void validateQuery() {\n        queryPanel.validateQuery();\n    }\n\n    @Override\n    public void dispose() {\n        resultPanel.dispose();\n    }\n\n    public MongoResultPanel getResultPanel() {\n        return resultPanel;\n    }\n\n    public void openFindEditor() {\n        queryPanel.setVisible(true);\n        splitter.setFirstComponent(queryPanel);\n        GuiUtils.runInSwingThread(new Runnable() {\n            @Override\n            public void run() {\n                focusOnEditor();\n            }\n        });\n    }\n\n    public void closeFindEditor() {\n        splitter.setFirstComponent(null);\n        queryPanel.setVisible(false);\n    }\n\n    public void focusOnEditor() {\n        queryPanel.requestFocusOnEditor();\n    }\n\n    public boolean isFindEditorOpened() {\n        return splitter.getFirstComponent() == queryPanel;\n    }\n\n    interface MongoDocumentOperations {\n        DBObject getMongoDocument(Object _id);\n\n        void deleteMongoDocument(Object mongoDocument);\n\n        void updateMongoDocument(DBObject mongoDocument);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/MongoResultPanel.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<form xmlns=\"http://www.intellij.com/uidesigner/form/\" version=\"1\" bind-to-class=\"org.codinjutsu.tools.nosql.mongo.view.MongoResultPanel\">\n  <grid id=\"27dc6\" binding=\"mainPanel\" layout-manager=\"GridLayoutManager\" row-count=\"1\" column-count=\"1\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n    <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n    <constraints>\n      <xy x=\"20\" y=\"20\" width=\"500\" height=\"400\"/>\n    </constraints>\n    <properties/>\n    <border type=\"none\"/>\n    <children>\n      <grid id=\"96277\" binding=\"containerPanel\" layout-manager=\"GridLayoutManager\" row-count=\"1\" column-count=\"1\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n        <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n        <constraints>\n          <grid row=\"0\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n        <border type=\"none\"/>\n        <children/>\n      </grid>\n    </children>\n  </grid>\n</form>\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/MongoResultPanel.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view;\n\nimport com.intellij.openapi.Disposable;\nimport com.intellij.openapi.actionSystem.ActionManager;\nimport com.intellij.openapi.actionSystem.DefaultActionGroup;\nimport com.intellij.openapi.application.ApplicationManager;\nimport com.intellij.openapi.project.Project;\nimport com.intellij.openapi.ui.MessageType;\nimport com.intellij.openapi.ui.Splitter;\nimport com.intellij.openapi.ui.popup.Balloon;\nimport com.intellij.openapi.util.Disposer;\nimport com.intellij.ui.PopupHandler;\nimport com.intellij.ui.components.JBScrollPane;\nimport com.intellij.ui.treeStructure.treetable.TreeTableTree;\nimport com.intellij.util.ui.tree.TreeUtil;\nimport com.mongodb.DBObject;\nimport org.apache.commons.lang.StringUtils;\nimport org.codinjutsu.tools.nosql.commons.utils.GuiUtils;\nimport org.codinjutsu.tools.nosql.commons.view.NoSqlTreeNode;\nimport org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor;\nimport org.codinjutsu.tools.nosql.mongo.model.MongoResult;\nimport org.codinjutsu.tools.nosql.mongo.view.action.CopyResultAction;\nimport org.codinjutsu.tools.nosql.mongo.view.action.EditMongoDocumentAction;\nimport org.codinjutsu.tools.nosql.mongo.view.model.JsonTreeModel;\nimport org.codinjutsu.tools.nosql.mongo.view.nodedescriptor.MongoKeyValueDescriptor;\nimport org.codinjutsu.tools.nosql.mongo.view.nodedescriptor.MongoResultDescriptor;\n\nimport javax.swing.*;\nimport javax.swing.tree.DefaultMutableTreeNode;\nimport java.awt.*;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.util.LinkedList;\nimport java.util.List;\n\npublic class MongoResultPanel extends JPanel implements Disposable {\n\n    private final MongoPanel.MongoDocumentOperations mongoDocumentOperations;\n    private JPanel mainPanel;\n    private JPanel containerPanel;\n    private final Splitter splitter;\n    private final JPanel resultTreePanel;\n    private final MongoEditionPanel mongoEditionPanel;\n\n    JsonTreeTableView resultTableView;\n\n\n    public MongoResultPanel(Project project, MongoPanel.MongoDocumentOperations mongoDocumentOperations) {\n        this.mongoDocumentOperations = mongoDocumentOperations;\n        setLayout(new BorderLayout());\n        add(mainPanel, BorderLayout.CENTER);\n\n        splitter = new Splitter(true, 0.6f);\n\n        resultTreePanel = new JPanel(new BorderLayout());\n\n        splitter.setFirstComponent(resultTreePanel);\n\n        mongoEditionPanel = createMongoEditionPanel();\n\n        containerPanel.setLayout(new BorderLayout());\n        containerPanel.add(splitter);\n\n        Disposer.register(project, this);\n    }\n\n    private MongoEditionPanel createMongoEditionPanel() {\n        return new MongoEditionPanel().init(mongoDocumentOperations, new ActionCallback() {\n            public void onOperationSuccess(String message) {\n                hideEditionPanel();\n                GuiUtils.showNotification(MongoResultPanel.this.resultTreePanel, MessageType.INFO, message, Balloon.Position.above);\n            }\n\n            @Override\n            public void onOperationFailure(Exception exception) {\n                GuiUtils.showNotification(MongoResultPanel.this.resultTreePanel, MessageType.ERROR, exception.getMessage(), Balloon.Position.above);\n            }\n\n            @Override\n            public void onOperationCancelled(String message) {\n                hideEditionPanel();\n            }\n        });\n    }\n\n    public void updateResultTableTree(MongoResult mongoResult) {\n        resultTableView = new JsonTreeTableView(JsonTreeModel.buildJsonTree(mongoResult), JsonTreeTableView.COLUMNS_FOR_READING);\n        resultTableView.setName(\"resultTreeTable\");\n\n        resultTableView.addMouseListener(new MouseAdapter() {\n            @Override\n            public void mouseClicked(MouseEvent mouseEvent) {\n                if (mouseEvent.getClickCount() == 2 && MongoResultPanel.this.isSelectedNodeId()) {\n                    MongoResultPanel.this.editSelectedMongoDocument();\n                }\n            }\n        });\n\n        buildPopupMenu();\n\n        resultTreePanel.invalidate();\n        resultTreePanel.removeAll();\n        resultTreePanel.add(new JBScrollPane(resultTableView));\n        resultTreePanel.validate();\n    }\n\n    void buildPopupMenu() {\n        DefaultActionGroup actionPopupGroup = new DefaultActionGroup(\"MongoResultPopupGroup\", true);\n        if (ApplicationManager.getApplication() != null) {\n            actionPopupGroup.add(new EditMongoDocumentAction(this));\n            actionPopupGroup.add(new CopyResultAction(this));\n        }\n\n        PopupHandler.installPopupHandler(resultTableView, actionPopupGroup, \"POPUP\", ActionManager.getInstance());\n    }\n\n\n    public void editSelectedMongoDocument() {\n\n        DBObject mongoDocument = getSelectedMongoDocument();\n\n        if (mongoDocument == null) {\n            return;\n        }\n\n        mongoEditionPanel.updateEditionTree(mongoDocument);\n\n        splitter.setSecondComponent(mongoEditionPanel);\n    }\n\n\n    public void addMongoDocument() {\n        mongoEditionPanel.updateEditionTree(null);\n        splitter.setSecondComponent(mongoEditionPanel);\n    }\n\n    private DBObject getSelectedMongoDocument() {\n        TreeTableTree tree = resultTableView.getTree();\n        NoSqlTreeNode treeNode = (NoSqlTreeNode) tree.getLastSelectedPathComponent();\n        if (treeNode == null) {\n            return null;\n        }\n\n        NodeDescriptor descriptor = treeNode.getDescriptor();\n        if (descriptor instanceof MongoKeyValueDescriptor) {\n            MongoKeyValueDescriptor keyValueDescriptor = (MongoKeyValueDescriptor) descriptor;\n            if (StringUtils.equals(keyValueDescriptor.getKey(), \"_id\")) {\n                return mongoDocumentOperations.getMongoDocument(keyValueDescriptor.getValue());\n            }\n        }\n\n        return null;\n    }\n\n\n    public boolean isSelectedNodeId() {\n        if (resultTableView == null) {\n            return false;\n        }\n        TreeTableTree tree = resultTableView.getTree();\n        NoSqlTreeNode treeNode = (NoSqlTreeNode) tree.getLastSelectedPathComponent();\n        if (treeNode == null) {\n            return false;\n        }\n\n        NodeDescriptor descriptor = treeNode.getDescriptor();\n        if (descriptor instanceof MongoKeyValueDescriptor) {\n            MongoKeyValueDescriptor keyValueDescriptor = (MongoKeyValueDescriptor) descriptor;\n            return StringUtils.equals(keyValueDescriptor.getKey(), \"_id\");\n        }\n\n        return false;\n    }\n\n\n    void expandAll() {\n        TreeUtil.expandAll(resultTableView.getTree());\n    }\n\n    void collapseAll() {\n        TreeTableTree tree = resultTableView.getTree();\n        TreeUtil.collapseAll(tree, 1);\n    }\n\n    public String getSelectedNodeStringifiedValue() {\n        NoSqlTreeNode lastSelectedResultNode = (NoSqlTreeNode) resultTableView.getTree().getLastSelectedPathComponent();\n        if (lastSelectedResultNode == null) {\n            lastSelectedResultNode = (NoSqlTreeNode) resultTableView.getTree().getModel().getRoot();\n        }\n        NodeDescriptor userObject = lastSelectedResultNode.getDescriptor();\n        if (userObject instanceof MongoResultDescriptor) {\n            return stringifyResult(lastSelectedResultNode);\n        }\n\n        return userObject.toString();\n    }\n\n    private void hideEditionPanel() {\n        splitter.setSecondComponent(null);\n    }\n\n    private String stringifyResult(DefaultMutableTreeNode selectedResultNode) {\n        List<Object> stringifiedObjects = new LinkedList<Object>();\n        for (int i = 0; i < selectedResultNode.getChildCount(); i++) {\n            DefaultMutableTreeNode childNode = (DefaultMutableTreeNode) selectedResultNode.getChildAt(i);\n            stringifiedObjects.add(childNode.getUserObject());\n        }\n\n        return String.format(\"[ %s ]\", StringUtils.join(stringifiedObjects, \" , \"));\n    }\n\n    @Override\n    public void dispose() {\n        resultTableView = null;\n        mongoEditionPanel.dispose();\n    }\n\n    public interface ActionCallback {\n\n        void onOperationSuccess(String message);\n\n        void onOperationFailure(Exception exception);\n\n        void onOperationCancelled(String message);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/QueryPanel.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<form xmlns=\"http://www.intellij.com/uidesigner/form/\" version=\"1\" bind-to-class=\"org.codinjutsu.tools.nosql.mongo.view.QueryPanel\">\n  <grid id=\"27dc6\" binding=\"mainPanel\" layout-manager=\"GridLayoutManager\" row-count=\"1\" column-count=\"1\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n    <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n    <constraints>\n      <xy x=\"20\" y=\"20\" width=\"500\" height=\"400\"/>\n    </constraints>\n    <properties/>\n    <border type=\"none\"/>\n    <children>\n      <grid id=\"b7440\" binding=\"queryContainerPanel\" layout-manager=\"GridLayoutManager\" row-count=\"1\" column-count=\"1\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n        <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n        <constraints>\n          <grid row=\"0\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n        <border type=\"none\"/>\n        <children/>\n      </grid>\n    </children>\n  </grid>\n</form>\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/QueryPanel.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view;\n\nimport com.intellij.lang.Language;\nimport com.intellij.openapi.Disposable;\nimport com.intellij.openapi.editor.Document;\nimport com.intellij.openapi.editor.Editor;\nimport com.intellij.openapi.editor.EditorFactory;\nimport com.intellij.openapi.editor.EditorSettings;\nimport com.intellij.openapi.editor.colors.EditorColors;\nimport com.intellij.openapi.editor.colors.EditorColorsScheme;\nimport com.intellij.openapi.editor.ex.EditorEx;\nimport com.intellij.openapi.editor.ex.util.LexerEditorHighlighter;\nimport com.intellij.openapi.editor.highlighter.EditorHighlighter;\nimport com.intellij.openapi.fileTypes.PlainTextSyntaxHighlighterFactory;\nimport com.intellij.openapi.project.Project;\nimport com.intellij.openapi.ui.MessageType;\nimport com.intellij.openapi.ui.Messages;\nimport com.intellij.openapi.ui.popup.Balloon;\nimport com.intellij.openapi.ui.popup.JBPopupFactory;\nimport com.intellij.openapi.util.Disposer;\nimport com.intellij.openapi.wm.IdeFocusManager;\nimport com.intellij.ui.awt.RelativePoint;\nimport com.intellij.ui.components.panels.NonOpaquePanel;\nimport com.intellij.util.Alarm;\nimport com.intellij.util.ui.UIUtil;\nimport com.mongodb.util.JSON;\nimport com.mongodb.util.JSONParseException;\nimport org.apache.commons.lang.StringUtils;\nimport org.codinjutsu.tools.nosql.mongo.model.MongoQueryOptions;\nimport org.codinjutsu.tools.nosql.mongo.view.action.OperatorCompletionAction;\n\nimport javax.swing.*;\nimport java.awt.*;\n\npublic class QueryPanel extends JPanel implements Disposable {\n\n    private static final Font COURIER_FONT = new Font(\"Courier\", Font.PLAIN, UIUtil.getLabelFont().getSize());\n\n    private static final String FILTER_PANEL = \"FilterPanel\";\n    private static final String AGGREGATION_PANEL = \"AggregationPanel\";\n\n    private final Alarm myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);\n\n    private final Project project;\n\n    private JPanel mainPanel;\n    private final CardLayout queryCardLayout;\n\n    private JPanel queryContainerPanel;\n\n    private final OperatorPanel filterPanel;\n    private final OperatorPanel aggregationPanel;\n\n    public QueryPanel(Project project) {\n        this.project = project;\n\n        setLayout(new BorderLayout());\n        add(mainPanel);\n\n        queryCardLayout = new CardLayout();\n        queryContainerPanel.setLayout(queryCardLayout);\n\n        filterPanel = createFilterPanel();\n        queryContainerPanel.add(filterPanel, FILTER_PANEL);\n\n        aggregationPanel = createAggregationPanel();\n        queryContainerPanel.add(aggregationPanel, AGGREGATION_PANEL);\n\n        toggleToFind();\n\n        Disposer.register(project, this);\n    }\n\n    private OperatorPanel createAggregationPanel() {\n        return new AggregatorPanel();\n    }\n\n    private OperatorPanel createFilterPanel() {\n        return new FilterPanel();\n    }\n\n    public void requestFocusOnEditor() {// Code from requestFocus of EditorImpl\n        final IdeFocusManager focusManager = IdeFocusManager.getInstance(this.project);\n        JComponent editorContentComponent = getCurrentOperatorPanel().getRequestFocusComponent();\n        if (focusManager.getFocusOwner() != editorContentComponent) {\n            focusManager.requestFocus(editorContentComponent, true);\n        }\n    }\n\n    public OperatorPanel getCurrentOperatorPanel() {\n        return filterPanel.isVisible() ? filterPanel : aggregationPanel;\n    }\n\n\n    private static void fillEditorSettings(final EditorSettings editorSettings) {\n        editorSettings.setWhitespacesShown(true);\n        editorSettings.setLineMarkerAreaShown(false);\n        editorSettings.setIndentGuidesShown(false);\n        editorSettings.setLineNumbersShown(false);\n        editorSettings.setAllowSingleLogicalLineFolding(true);\n        editorSettings.setAdditionalColumnsCount(0);\n        editorSettings.setAdditionalLinesCount(1);\n        editorSettings.setUseSoftWraps(true);\n        editorSettings.setUseTabCharacter(false);\n        editorSettings.setCaretInsideTabs(false);\n        editorSettings.setVirtualSpace(false);\n    }\n\n    private void attachHighlighter(final EditorEx editor) {\n        EditorColorsScheme scheme = editor.getColorsScheme();\n        scheme.setColor(EditorColors.CARET_ROW_COLOR, null);\n        editor.setHighlighter(createHighlighter(scheme));\n    }\n\n    private EditorHighlighter createHighlighter(EditorColorsScheme settings) {\n        Language language = Language.findLanguageByID(\"JSON\");\n        if (language == null) {\n            language = Language.ANY;\n        }\n        return new LexerEditorHighlighter(PlainTextSyntaxHighlighterFactory.getSyntaxHighlighter(language, null, null), settings);\n    }\n\n    public MongoQueryOptions getQueryOptions(String rowLimit) {\n        return getCurrentOperatorPanel().buildQueryOptions(rowLimit);\n    }\n\n    @Override\n    public void dispose() {\n        myUpdateAlarm.cancelAllRequests();\n        filterPanel.dispose();\n        aggregationPanel.dispose();\n    }\n\n    public void toggleToAggregation() {\n        queryCardLayout.show(queryContainerPanel, AGGREGATION_PANEL);\n    }\n\n    public void toggleToFind() {\n        queryCardLayout.show(queryContainerPanel, FILTER_PANEL);\n    }\n\n    public void validateQuery() {\n        getCurrentOperatorPanel().validateQuery();\n    }\n\n    private class AggregatorPanel extends OperatorPanel {\n\n        private final Editor editor;\n        private final OperatorCompletionAction operatorCompletionAction;\n\n        private AggregatorPanel() {\n            this.editor = createEditor();\n\n            setLayout(new BorderLayout());\n            NonOpaquePanel headPanel = new NonOpaquePanel();\n            JLabel operatorLabel = new JLabel(\"Aggregation\");\n            headPanel.add(operatorLabel, BorderLayout.WEST);\n            add(headPanel, BorderLayout.NORTH);\n            add(this.editor.getComponent(), BorderLayout.CENTER);\n\n            this.operatorCompletionAction = new OperatorCompletionAction(project, editor);\n\n\n            myUpdateAlarm.setActivationComponent(this.editor.getComponent());\n        }\n\n        @Override\n        public void validateQuery() {\n            try {\n                String query = getQuery();\n                if (StringUtils.isEmpty(query)) {\n                    return;\n                }\n                JSON.parse(query);\n            } catch (JSONParseException ex) {\n                notifyOnErrorForOperator(editor.getComponent(), ex);\n            } catch (NumberFormatException ex) {\n                notifyOnErrorForOperator(editor.getComponent(), ex);\n            }\n        }\n\n        private String getQuery() {\n            return String.format(\"[%s]\", StringUtils.trim(this.editor.getDocument().getText()));\n        }\n\n        @Override\n        public MongoQueryOptions buildQueryOptions(String rowLimit) {\n            MongoQueryOptions mongoQueryOptions = new MongoQueryOptions();\n            try {\n                mongoQueryOptions.setOperations(getQuery());\n            } catch (JSONParseException ex) {\n                notifyOnErrorForOperator(editor.getComponent(), ex);\n            }\n\n            if (StringUtils.isNotBlank(rowLimit)) {\n                mongoQueryOptions.setResultLimit(Integer.parseInt(rowLimit));\n            }\n\n            return mongoQueryOptions;\n        }\n\n        @Override\n        public JComponent getRequestFocusComponent() {\n            return this.editor.getContentComponent();\n        }\n\n        @Override\n        public void dispose() {\n            operatorCompletionAction.dispose();\n            EditorFactory.getInstance().releaseEditor(this.editor);\n        }\n    }\n\n    private class FilterPanel extends OperatorPanel {\n\n        private final Editor selectEditor;\n        private final OperatorCompletionAction operatorCompletionAction;\n        private final Editor projectionEditor;\n        private final Editor sortEditor;\n\n        private FilterPanel() {\n            setLayout(new BoxLayout(this, BoxLayout.X_AXIS));\n\n            this.selectEditor = createEditor();\n            this.operatorCompletionAction = new OperatorCompletionAction(project, selectEditor);\n            add(createSubOperatorPanel(\"Filter\", this.selectEditor));\n\n            this.projectionEditor = createEditor();\n            add(createSubOperatorPanel(\"Projection\", this.projectionEditor));\n\n            this.sortEditor = createEditor();\n            add(createSubOperatorPanel(\"Sort\", this.sortEditor));\n        }\n\n        @Override\n        public JComponent getRequestFocusComponent() {\n            return this.selectEditor.getContentComponent();\n        }\n\n        @Override\n        public void validateQuery() {\n            validateEditorQuery(selectEditor);\n            validateEditorQuery(projectionEditor);\n            validateEditorQuery(sortEditor);\n        }\n\n        @Override\n        public MongoQueryOptions buildQueryOptions(String rowLimit) {\n            MongoQueryOptions mongoQueryOptions = new MongoQueryOptions();\n            try {\n                mongoQueryOptions.setFilter(getQueryFrom(selectEditor));\n                mongoQueryOptions.setProjection(getQueryFrom(projectionEditor));\n                mongoQueryOptions.setSort(getQueryFrom(sortEditor));\n            } catch (JSONParseException ex) {\n                notifyOnErrorForOperator(selectEditor.getComponent(), ex);\n            }\n\n            if (StringUtils.isNotBlank(rowLimit)) {\n                mongoQueryOptions.setResultLimit(Integer.parseInt(rowLimit));\n            }\n\n            return mongoQueryOptions;\n        }\n\n        @Override\n        public void dispose() {\n            operatorCompletionAction.dispose();\n            EditorFactory.getInstance().releaseEditor(this.selectEditor);\n            EditorFactory.getInstance().releaseEditor(this.projectionEditor);\n            EditorFactory.getInstance().releaseEditor(this.sortEditor);\n        }\n\n        private void validateEditorQuery(Editor editor) {\n            try {\n                String query = getQueryFrom(editor);\n                if (StringUtils.isEmpty(query)) {\n                    return;\n                }\n                JSON.parse(query);\n            } catch (JSONParseException ex) {\n                notifyOnErrorForOperator(editor.getComponent(), ex);\n            } catch (NumberFormatException ex) {\n                notifyOnErrorForOperator(editor.getComponent(), ex);\n            }\n        }\n\n        private String getQueryFrom(Editor editor) {\n            return StringUtils.trim(editor.getDocument().getText());\n        }\n\n        private JPanel createSubOperatorPanel(String title, Editor subOperatorEditor) {\n            JPanel selectPanel = new JPanel();\n            selectPanel.setLayout(new BorderLayout());\n            NonOpaquePanel headPanel = new NonOpaquePanel();\n            JLabel operatorLabel = new JLabel(title);\n            headPanel.add(operatorLabel, BorderLayout.WEST);\n            selectPanel.add(headPanel, BorderLayout.NORTH);\n            selectPanel.add(subOperatorEditor.getComponent(), BorderLayout.CENTER);\n\n            myUpdateAlarm.setActivationComponent(subOperatorEditor.getComponent());\n\n            return selectPanel;\n        }\n    }\n\n    private abstract class OperatorPanel extends JPanel implements Disposable {\n\n        public abstract JComponent getRequestFocusComponent();\n\n        public abstract void validateQuery();\n\n        public abstract MongoQueryOptions buildQueryOptions(String rowLimit);\n\n        void notifyOnErrorForOperator(JComponent component, Exception ex) {\n            String message;\n            if (ex instanceof JSONParseException) {\n                message = StringUtils.removeStart(ex.getMessage(), \"\\n\");\n            } else {\n                message = String.format(\"%s: %s\", ex.getClass().getSimpleName(), ex.getMessage());\n            }\n            NonOpaquePanel nonOpaquePanel = new NonOpaquePanel();\n            JTextPane textPane = Messages.configureMessagePaneUi(new JTextPane(), message);\n            textPane.setFont(COURIER_FONT);\n            textPane.setBackground(MessageType.ERROR.getPopupBackground());\n            nonOpaquePanel.add(textPane, BorderLayout.CENTER);\n            nonOpaquePanel.add(new JLabel(MessageType.ERROR.getDefaultIcon()), BorderLayout.WEST);\n\n            JBPopupFactory.getInstance().createBalloonBuilder(nonOpaquePanel)\n                    .setFillColor(MessageType.ERROR.getPopupBackground())\n                    .createBalloon()\n                    .show(new RelativePoint(component, new Point(0, 0)), Balloon.Position.above);\n        }\n\n        protected Editor createEditor() {\n            EditorFactory editorFactory = EditorFactory.getInstance();\n            Document editorDocument = editorFactory.createDocument(\"\");\n            Editor editor = editorFactory.createEditor(editorDocument, project);\n            fillEditorSettings(editor.getSettings());\n            EditorEx editorEx = (EditorEx) editor;\n            attachHighlighter(editorEx);\n\n            return editor;\n        }\n\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/action/AddMongoDocumentAction.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view.action;\n\nimport com.intellij.icons.AllIcons;\nimport com.intellij.openapi.actionSystem.AnAction;\nimport com.intellij.openapi.actionSystem.AnActionEvent;\nimport com.intellij.openapi.project.DumbAware;\nimport org.codinjutsu.tools.nosql.mongo.view.MongoResultPanel;\n\nimport java.awt.event.KeyEvent;\n\npublic class AddMongoDocumentAction extends AnAction implements DumbAware {\n\n    private final MongoResultPanel resultPanel;\n\n    public AddMongoDocumentAction(MongoResultPanel resultPanel) {\n        super(\"Add\", \"Add mongo document\", AllIcons.General.Add);\n        registerCustomShortcutSet(KeyEvent.VK_INSERT, KeyEvent.ALT_MASK, resultPanel);\n        this.resultPanel = resultPanel;\n    }\n\n    @Override\n    public void actionPerformed(AnActionEvent anActionEvent) {\n        resultPanel.addMongoDocument();\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/action/CloseFindEditorAction.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view.action;\n\nimport com.intellij.icons.AllIcons;\nimport com.intellij.ide.actions.CloseTabToolbarAction;\nimport com.intellij.openapi.actionSystem.AnActionEvent;\nimport org.codinjutsu.tools.nosql.mongo.view.MongoPanel;\n\nimport java.awt.event.KeyEvent;\n\npublic class CloseFindEditorAction extends CloseTabToolbarAction {\n    private final MongoPanel mongoPanel;\n\n    public CloseFindEditorAction(MongoPanel mongoPanel) {\n        getTemplatePresentation().setIcon(AllIcons.Actions.Close);\n        registerCustomShortcutSet(KeyEvent.VK_ESCAPE, 0, mongoPanel);\n        this.mongoPanel = mongoPanel;\n    }\n\n    @Override\n    public void actionPerformed(AnActionEvent e) {\n        mongoPanel.closeFindEditor();\n    }\n\n    @Override\n    public void update(AnActionEvent event) {\n        event.getPresentation().setVisible(false);\n    }\n}"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/action/CopyResultAction.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view.action;\n\nimport com.intellij.icons.AllIcons;\nimport com.intellij.openapi.actionSystem.AnAction;\nimport com.intellij.openapi.actionSystem.AnActionEvent;\nimport com.intellij.openapi.ide.CopyPasteManager;\nimport com.intellij.openapi.project.DumbAware;\nimport org.codinjutsu.tools.nosql.mongo.view.MongoResultPanel;\n\nimport java.awt.*;\nimport java.awt.datatransfer.StringSelection;\nimport java.awt.event.KeyEvent;\n\npublic class CopyResultAction extends AnAction implements DumbAware {\n\n    private final MongoResultPanel mongoResultPanel;\n\n    public CopyResultAction(MongoResultPanel mongoResultPanel) {\n        super(\"Copy\", \"Copy results to clipboard\", AllIcons.Actions.Copy);\n        this.mongoResultPanel = mongoResultPanel;\n\n        registerCustomShortcutSet(KeyEvent.VK_C, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), mongoResultPanel);\n    }\n\n    @Override\n    public void actionPerformed(AnActionEvent anActionEvent) {\n        CopyPasteManager.getInstance().setContents(new StringSelection(mongoResultPanel.getSelectedNodeStringifiedValue()));\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/action/DropCollectionAction.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view.action;\n\nimport com.intellij.icons.AllIcons;\nimport com.intellij.openapi.actionSystem.AnAction;\nimport com.intellij.openapi.actionSystem.AnActionEvent;\nimport com.intellij.openapi.project.DumbAware;\nimport org.codinjutsu.tools.nosql.NoSqlExplorerPanel;\n\nimport javax.swing.*;\n\npublic class DropCollectionAction extends AnAction implements DumbAware {\n\n    private static final Icon REMOVE_ICON = AllIcons.Actions.GC;\n\n    private final NoSqlExplorerPanel noSqlExplorerPanel;\n\n    public DropCollectionAction(NoSqlExplorerPanel noSqlExplorerPanel) {\n        super(\"Drop collection\", \"Drop the selected collection\", REMOVE_ICON);\n        this.noSqlExplorerPanel = noSqlExplorerPanel;\n    }\n\n    @Override\n    public void actionPerformed(AnActionEvent anActionEvent) {\n        int result = JOptionPane.showConfirmDialog(null, String.format(\"Do you REALLY want to drop the '%s' collection?\", noSqlExplorerPanel.getSelectedCollection().getName()), \"Warning\", JOptionPane.YES_NO_OPTION);\n\n        if (result == JOptionPane.YES_OPTION) {\n            noSqlExplorerPanel.dropCollection();\n        }\n    }\n\n\n    @Override\n    public void update(AnActionEvent event) {\n        event.getPresentation().setVisible(noSqlExplorerPanel.getSelectedCollection() != null);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/action/DropDatabaseAction.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view.action;\n\nimport com.intellij.icons.AllIcons;\nimport com.intellij.openapi.actionSystem.AnAction;\nimport com.intellij.openapi.actionSystem.AnActionEvent;\nimport com.intellij.openapi.project.DumbAware;\nimport org.codinjutsu.tools.nosql.NoSqlExplorerPanel;\n\nimport javax.swing.*;\n\n/**\n * Created by piddubnyi on 06.11.14 .\n */\npublic class DropDatabaseAction extends AnAction implements DumbAware {\n\n    private static final Icon REMOVE_ICON = AllIcons.Actions.GC;\n\n    private final NoSqlExplorerPanel noSqlExplorerPanel;\n\n    public DropDatabaseAction(NoSqlExplorerPanel noSqlExplorerPanel) {\n        super(\"Drop Database\", \"Drop the selected database\", REMOVE_ICON);\n        this.noSqlExplorerPanel = noSqlExplorerPanel;\n    }\n\n    @Override\n    public void actionPerformed(AnActionEvent anActionEvent) {\n        int result = JOptionPane.showConfirmDialog(null, String.format(\"Do you REALLY want to drop the '%s' database?\", noSqlExplorerPanel.getSelectedMongoDatabase().getName()), \"Warning\", JOptionPane.YES_NO_OPTION);\n\n        if (result == JOptionPane.YES_OPTION) {\n            noSqlExplorerPanel.dropDatabase();\n        }\n    }\n\n\n    @Override\n    public void update(AnActionEvent event) {\n        event.getPresentation().setVisible(noSqlExplorerPanel.getSelectedMongoDatabase() != null);\n    }\n}"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/action/EditMongoDocumentAction.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view.action;\n\nimport com.intellij.icons.AllIcons;\nimport com.intellij.openapi.actionSystem.AnAction;\nimport com.intellij.openapi.actionSystem.AnActionEvent;\nimport com.intellij.openapi.project.DumbAware;\nimport org.codinjutsu.tools.nosql.mongo.view.MongoResultPanel;\n\npublic class EditMongoDocumentAction extends AnAction implements DumbAware {\n\n    private final MongoResultPanel resultPanel;\n\n    public EditMongoDocumentAction(MongoResultPanel resultPanel) {\n        super(\"Edit\", \"Edit mongo document\", AllIcons.Actions.Edit);\n        this.resultPanel = resultPanel;\n    }\n\n    @Override\n    public void actionPerformed(AnActionEvent anActionEvent) {\n        resultPanel.editSelectedMongoDocument();\n    }\n\n    @Override\n    public void update(AnActionEvent event) {\n        super.update(event);\n        event.getPresentation().setVisible(resultPanel.isSelectedNodeId());\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/action/EnableAggregateAction.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view.action;\n\nimport com.intellij.openapi.actionSystem.AnActionEvent;\nimport com.intellij.openapi.actionSystem.ToggleAction;\nimport org.codinjutsu.tools.nosql.commons.utils.GuiUtils;\nimport org.codinjutsu.tools.nosql.mongo.view.QueryPanel;\n\nimport javax.swing.*;\n\npublic class EnableAggregateAction extends ToggleAction {\n\n    private static final String ENABLE_FIND_MODE = \"Toggle to Find Mode\";\n    private static final String ENABLE_AGGREGATION_MODE = \"Toggle to Aggregation Mode\";\n    private static final Icon AGGREGATION_ICON = GuiUtils.loadIcon(\"sqlGroupByType.png\");\n    private static final String QUERY_FIND_SAMPLE = \"ex: {'name': 'foo'}\";\n    private static final String QUERY_AGGREGATION_SAMPLE = \"ex: [{'$match': {'name': 'foo'}, {'$project': {'address': 1}}]\";\n\n    private final QueryPanel queryPanel;\n\n    private boolean enableAggregation = false;\n\n    public EnableAggregateAction(final QueryPanel queryPanel) {\n        super(ENABLE_AGGREGATION_MODE, QUERY_FIND_SAMPLE, AGGREGATION_ICON);\n        this.queryPanel = queryPanel;\n    }\n\n\n    @Override\n    public boolean isSelected(AnActionEvent anActionEvent) {\n        return enableAggregation;\n    }\n\n    @Override\n    public void setSelected(AnActionEvent event, boolean enableAggregation) {\n        this.enableAggregation = enableAggregation;\n        if (enableAggregation) {\n            queryPanel.toggleToAggregation();\n        } else {\n            queryPanel.toggleToFind();\n        }\n    }\n\n    @Override\n    public void update(AnActionEvent event) {\n        event.getPresentation().setText(isSelected(event) ? ENABLE_FIND_MODE : ENABLE_AGGREGATION_MODE);\n        event.getPresentation().setDescription(isSelected(event) ? QUERY_AGGREGATION_SAMPLE : QUERY_FIND_SAMPLE);\n        event.getPresentation().setVisible(queryPanel.isVisible());\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/action/OpenFindAction.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view.action;\n\nimport com.intellij.icons.AllIcons;\nimport com.intellij.openapi.actionSystem.AnAction;\nimport com.intellij.openapi.actionSystem.AnActionEvent;\nimport com.intellij.openapi.project.DumbAware;\nimport org.codinjutsu.tools.nosql.mongo.view.MongoPanel;\n\nimport java.awt.event.KeyEvent;\n\npublic class OpenFindAction extends AnAction implements DumbAware {\n    private final MongoPanel mongoPanel;\n\n    public OpenFindAction(MongoPanel mongoPanel) {\n        super(\"Find\", \"Open Find editor\", AllIcons.Actions.Find);\n        this.mongoPanel = mongoPanel;\n        registerCustomShortcutSet(KeyEvent.VK_F, KeyEvent.CTRL_MASK, mongoPanel);\n    }\n\n\n    @Override\n    public void actionPerformed(AnActionEvent e) {\n        if (!mongoPanel.isFindEditorOpened()) {\n            mongoPanel.openFindEditor();\n        } else {\n            mongoPanel.focusOnEditor();\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/action/OperatorCompletionAction.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view.action;\n\nimport com.intellij.openapi.Disposable;\nimport com.intellij.openapi.actionSystem.AnAction;\nimport com.intellij.openapi.actionSystem.AnActionEvent;\nimport com.intellij.openapi.application.Result;\nimport com.intellij.openapi.command.WriteCommandAction;\nimport com.intellij.openapi.editor.CaretModel;\nimport com.intellij.openapi.editor.Document;\nimport com.intellij.openapi.editor.Editor;\nimport com.intellij.openapi.project.Project;\nimport com.intellij.openapi.ui.popup.PopupChooserBuilder;\nimport com.intellij.ui.components.JBList;\nimport com.mongodb.QueryOperators;\nimport org.codinjutsu.tools.nosql.mongo.model.MongoAggregateOperator;\nimport org.jetbrains.annotations.NotNull;\n\nimport java.awt.event.KeyEvent;\nimport java.lang.reflect.Field;\nimport java.util.LinkedList;\nimport java.util.List;\n\npublic class OperatorCompletionAction extends AnAction implements Disposable {\n\n    private static final String MONGO_OPERATOR_COMPLETION = \"MONGO_OPERATOR_COMPLETION\";\n\n    private static final JBList QUERY_OPERATOR_LIST;\n\n\n    static {\n        List<String> operator = new LinkedList<String>();\n        for (MongoAggregateOperator aggregateOperator : MongoAggregateOperator.values()) {\n            operator.add(aggregateOperator.getLabel());\n        }\n\n        for (Field field : QueryOperators.class.getFields()) {\n            try {\n                operator.add((String) QueryOperators.class.getDeclaredField(field.getName()).get(String.class));\n            } catch (IllegalAccessException e) {\n\n            } catch (NoSuchFieldException e) {\n                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.\n            }\n        }\n\n        QUERY_OPERATOR_LIST = new JBList(operator);\n    }\n\n    private final Project project;\n    private final Editor editor;\n\n    public OperatorCompletionAction(Project project, Editor editor) {\n        this.project = project;\n        this.editor = editor;\n        registerCustomShortcutSet(KeyEvent.VK_SPACE, KeyEvent.CTRL_MASK, editor.getContentComponent());\n    }\n\n    @Override\n    public void actionPerformed(AnActionEvent anActionEvent) {\n        final Document document = editor.getDocument();\n        CaretModel caretModel = editor.getCaretModel();\n        final int offset = caretModel.getOffset();\n        new PopupChooserBuilder(QUERY_OPERATOR_LIST)\n                .setMovable(false)\n                .setCancelKeyEnabled(true)\n                .setItemChoosenCallback(new Runnable() {\n                    public void run() {\n                        final String selectedQueryOperator = (String) QUERY_OPERATOR_LIST.getSelectedValue();\n                        if (selectedQueryOperator == null) return;\n\n                        new WriteCommandAction(project, MONGO_OPERATOR_COMPLETION) {\n                            @Override\n                            protected void run(@NotNull Result result) throws Throwable {\n                                document.insertString(offset, selectedQueryOperator);\n                            }\n                        }.execute();\n                    }\n                })\n                .createPopup()\n                .showInBestPositionFor(editor);\n    }\n\n    @Override\n    public void dispose() {\n        unregisterCustomShortcutSet(editor.getContentComponent());\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/action/edition/AddKeyAction.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view.action.edition;\n\nimport com.intellij.icons.AllIcons;\nimport com.intellij.openapi.actionSystem.AnAction;\nimport com.intellij.openapi.actionSystem.AnActionEvent;\nimport org.codinjutsu.tools.nosql.mongo.view.AddKeyDialog;\nimport org.codinjutsu.tools.nosql.mongo.view.MongoEditionPanel;\n\nimport java.awt.event.KeyEvent;\n\npublic class AddKeyAction extends AnAction {\n\n    private final MongoEditionPanel mongoEditionPanel;\n\n    public AddKeyAction(MongoEditionPanel mongoEditionPanel) {\n        super(\"Add a key\", \"Add a key\", AllIcons.General.Add);\n        registerCustomShortcutSet(KeyEvent.VK_INSERT, KeyEvent.ALT_MASK, mongoEditionPanel);\n        this.mongoEditionPanel = mongoEditionPanel;\n    }\n\n    @Override\n    public void actionPerformed(AnActionEvent anActionEvent) {\n        AddKeyDialog dialog = AddKeyDialog.createDialog(mongoEditionPanel);\n        dialog.show();\n\n        if (!dialog.isOK()) {\n            return;\n        }\n\n        mongoEditionPanel.addKey(dialog.getKey(), dialog.getValue());\n    }\n\n    @Override\n    public void update(AnActionEvent event) {\n//        event.getPresentation().setVisible(mongoEditionPanel.canAddKey());\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/action/edition/AddValueAction.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view.action.edition;\n\nimport com.intellij.icons.AllIcons;\nimport com.intellij.openapi.actionSystem.AnAction;\nimport com.intellij.openapi.actionSystem.AnActionEvent;\nimport org.codinjutsu.tools.nosql.mongo.view.AddValueDialog;\nimport org.codinjutsu.tools.nosql.mongo.view.MongoEditionPanel;\n\npublic class AddValueAction extends AnAction {\n\n    private final MongoEditionPanel mongoEditionPanel;\n\n    public AddValueAction(MongoEditionPanel mongoEditionPanel) {\n        super(\"Add a value\", \"Add a value\", AllIcons.General.Add);\n        this.mongoEditionPanel = mongoEditionPanel;\n    }\n\n    @Override\n    public void actionPerformed(AnActionEvent anActionEvent) {\n        AddValueDialog dialog = AddValueDialog.createDialog(mongoEditionPanel);\n        dialog.show();\n\n        if (!dialog.isOK()) {\n            return;\n        }\n\n        mongoEditionPanel.addValue(dialog.getValue());\n    }\n\n    @Override\n    public void update(AnActionEvent event) {\n        event.getPresentation().setVisible(mongoEditionPanel.canAddValue());\n    }\n}"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/action/edition/DeleteKeyAction.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view.action.edition;\n\nimport com.intellij.icons.AllIcons;\nimport com.intellij.openapi.actionSystem.AnAction;\nimport com.intellij.openapi.actionSystem.AnActionEvent;\nimport org.codinjutsu.tools.nosql.mongo.view.MongoEditionPanel;\n\nimport java.awt.event.KeyEvent;\n\npublic class DeleteKeyAction extends AnAction {\n\n    private final MongoEditionPanel mongoEditionPanel;\n\n    public DeleteKeyAction(MongoEditionPanel mongoEditionPanel) {\n        super(\"Delete this\", \"Delete the selected node\", AllIcons.Actions.Delete);\n        registerCustomShortcutSet(KeyEvent.VK_DELETE, KeyEvent.ALT_MASK, mongoEditionPanel);\n        this.mongoEditionPanel = mongoEditionPanel;\n    }\n\n    @Override\n    public void actionPerformed(AnActionEvent anActionEvent) {\n        mongoEditionPanel.removeSelectedKey();\n    }\n\n    @Override\n    public void update(AnActionEvent event) {\n        event.getPresentation().setVisible(mongoEditionPanel.getSelectedNode() != null);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/console/MongoConsoleRunner.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view.console;\n\nimport com.intellij.execution.ExecutionException;\nimport com.intellij.execution.configurations.GeneralCommandLine;\nimport com.intellij.execution.console.ConsoleHistoryController;\nimport com.intellij.execution.console.ConsoleRootType;\nimport com.intellij.execution.console.ProcessBackedConsoleExecuteActionHandler;\nimport com.intellij.execution.process.OSProcessHandler;\nimport com.intellij.execution.runners.AbstractConsoleRunnerWithHistory;\nimport com.intellij.openapi.project.Project;\nimport com.intellij.openapi.util.Key;\nimport com.intellij.psi.PsiFile;\nimport com.mongodb.AuthenticationMechanism;\nimport org.apache.commons.lang.StringUtils;\nimport org.codinjutsu.tools.nosql.DatabaseVendor;\nimport org.codinjutsu.tools.nosql.NoSqlConfiguration;\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.codinjutsu.tools.nosql.commons.model.AuthenticationSettings;\nimport org.codinjutsu.tools.nosql.commons.view.console.NoSqlConsoleView;\nimport org.codinjutsu.tools.nosql.mongo.MongoUtils;\nimport org.codinjutsu.tools.nosql.mongo.logic.MongoExtraSettings;\nimport org.codinjutsu.tools.nosql.mongo.model.MongoDatabase;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\n\npublic class MongoConsoleRunner extends AbstractConsoleRunnerWithHistory<NoSqlConsoleView> {\n\n    private static final Key<Boolean> MONGO_SHELL_FILE = Key.create(\"MONGO_SHELL_FILE\");\n    private final ServerConfiguration serverConfiguration;\n    private final MongoDatabase database;\n\n\n    public MongoConsoleRunner(@NotNull Project project, ServerConfiguration serverConfiguration, MongoDatabase database) {\n        super(project, \"Mongo Shell\", \"/tmp\");\n\n        this.serverConfiguration = serverConfiguration;\n        this.database = database;\n    }\n\n    @Override\n    protected NoSqlConsoleView createConsoleView() {\n        NoSqlConsoleView res = new NoSqlConsoleView(getProject(), \"Mongo Console\", serverConfiguration);\n\n        PsiFile file = res.getFile();\n        assert file.getContext() == null;\n        file.putUserData(MONGO_SHELL_FILE, Boolean.TRUE);\n\n        return res;\n    }\n\n    @Nullable\n    @Override\n    protected Process createProcess() throws ExecutionException {\n\n        NoSqlConfiguration noSqlConfiguration = NoSqlConfiguration.getInstance(getProject());\n        String shellPath = noSqlConfiguration.getShellPath(DatabaseVendor.MONGO);\n        final GeneralCommandLine commandLine = new GeneralCommandLine();\n        commandLine.setExePath(shellPath);\n\n        commandLine.addParameter(MongoUtils.buildMongoUrl(serverConfiguration, database));\n\n        String shellWorkingDir = serverConfiguration.getShellWorkingDir();\n        if (StringUtils.isNotBlank(shellWorkingDir)) {\n            commandLine.withWorkDirectory(shellWorkingDir);\n        }\n\n        AuthenticationSettings authenticationSettings = serverConfiguration.getAuthenticationSettings();\n\n        String username = authenticationSettings.getUsername();\n        if (StringUtils.isNotBlank(username)) {\n            commandLine.addParameter(\"--username\");\n            commandLine.addParameter(username);\n        }\n\n        String password = authenticationSettings.getPassword();\n        if (StringUtils.isNotBlank(password)) {\n            commandLine.addParameter(\"--password\");\n            commandLine.addParameter(password);\n        }\n\n        MongoExtraSettings mongoExtraSettings = new MongoExtraSettings(authenticationSettings.getExtras());\n        String authenticationDatabase = mongoExtraSettings.getAuthenticationDatabase();\n        if (StringUtils.isNotBlank(authenticationDatabase)) {\n            commandLine.addParameter(\"--authenticationDatabase\");\n            commandLine.addParameter(authenticationDatabase);\n        }\n\n        AuthenticationMechanism authenticationMecanism = mongoExtraSettings.getAuthenticationMechanism();\n        if (authenticationMecanism != null) {\n            commandLine.addParameter(\"--authenticationMecanism\");\n            commandLine.addParameter(authenticationMecanism.getMechanismName());\n        }\n\n        String shellArgumentsLine = serverConfiguration.getShellArgumentsLine();\n        if (StringUtils.isNotBlank(shellArgumentsLine)) {\n            commandLine.addParameters(shellArgumentsLine.split(\" \"));\n        }\n\n        return commandLine.createProcess();\n    }\n\n    @Override\n    protected OSProcessHandler createProcessHandler(Process process) {\n        return new OSProcessHandler(process, null);\n    }\n\n    @NotNull\n    @Override\n    protected ProcessBackedConsoleExecuteActionHandler createExecuteActionHandler() {\n        ProcessBackedConsoleExecuteActionHandler handler = new ProcessBackedConsoleExecuteActionHandler(getProcessHandler(), false) {\n            @Override\n            public String getEmptyExecuteAction() {\n                return \"NoSql.Shell.Execute\";\n            }\n        };\n        new ConsoleHistoryController(new ConsoleRootType(\"Mongo Shell\", null) {\n        }, null, getConsoleView()).install();\n        return handler;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/editor/MongoFakeFileType.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view.editor;\n\nimport com.intellij.openapi.fileTypes.FileType;\nimport com.intellij.openapi.fileTypes.ex.FakeFileType;\nimport com.intellij.openapi.vfs.VirtualFile;\nimport org.codinjutsu.tools.nosql.commons.utils.GuiUtils;\nimport org.jetbrains.annotations.NotNull;\n\nimport javax.swing.*;\n\npublic class MongoFakeFileType extends FakeFileType {\n\n    public static final Icon MONGO_ICON = GuiUtils.loadIcon(\"mongodb.png\");\n\n    public static final FileType INSTANCE = new MongoFakeFileType();\n\n\n    @Override\n    public Icon getIcon() {\n        return MONGO_ICON;\n    }\n\n    @Override\n    public boolean isMyFileType(VirtualFile file) {\n        return false;\n    }\n\n    @NotNull\n    @Override\n    public String getDefaultExtension() {\n        return \"json\";\n    }\n\n    @NotNull\n    @Override\n    public String getName() {\n        return \"MONGO\";\n    }\n\n    @NotNull\n    @Override\n    public String getDescription() {\n        return \"MONGO\";\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/editor/MongoObjectFile.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view.editor;\n\nimport com.intellij.openapi.fileTypes.FileType;\nimport com.intellij.openapi.project.Project;\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.codinjutsu.tools.nosql.commons.view.editor.NoSqlDatabaseObjectFile;\nimport org.codinjutsu.tools.nosql.mongo.model.MongoCollection;\nimport org.jetbrains.annotations.NotNull;\n\npublic class MongoObjectFile extends NoSqlDatabaseObjectFile {\n\n    private MongoCollection collection;\n\n    public MongoObjectFile(Project project, ServerConfiguration configuration, MongoCollection collection) {\n        super(project, configuration, String.format(\"%s/%s/%s\", configuration.getLabel(), collection.getDatabaseName(), collection.getName()));\n        this.collection = collection;\n\n    }\n\n    @NotNull\n    public FileType getFileType() {\n        return MongoFakeFileType.INSTANCE;\n    }\n\n\n    public MongoCollection getCollection() {\n        return collection;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/model/JsonTreeModel.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view.model;\n\nimport com.mongodb.BasicDBList;\nimport com.mongodb.BasicDBObject;\nimport com.mongodb.DBObject;\nimport org.apache.commons.lang.StringUtils;\nimport org.codinjutsu.tools.nosql.commons.view.NoSqlTreeNode;\nimport org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor;\nimport org.codinjutsu.tools.nosql.mongo.model.MongoResult;\nimport org.codinjutsu.tools.nosql.mongo.view.nodedescriptor.MongoKeyValueDescriptor;\nimport org.codinjutsu.tools.nosql.mongo.view.nodedescriptor.MongoResultDescriptor;\nimport org.codinjutsu.tools.nosql.mongo.view.nodedescriptor.MongoValueDescriptor;\n\nimport javax.swing.tree.DefaultTreeModel;\nimport javax.swing.tree.TreeNode;\nimport java.util.Enumeration;\nimport java.util.List;\n\npublic class JsonTreeModel extends DefaultTreeModel {\n\n\n    public JsonTreeModel(MongoResult mongoResult) {\n        super(buildJsonTree(mongoResult));\n    }\n\n\n    public static TreeNode buildJsonTree(MongoResult mongoResult) {\n        NoSqlTreeNode rootNode = new NoSqlTreeNode(new MongoResultDescriptor(mongoResult.getCollectionName()));\n\n        List<DBObject> mongoObjects = mongoResult.getMongoObjects();\n        int i = 0;\n        for (DBObject mongoObject : mongoObjects) {\n            if (mongoObject instanceof BasicDBList) {\n                processDbObject(rootNode, mongoObject);\n            } else if (mongoObject instanceof BasicDBObject) {//dead code?\n                NoSqlTreeNode currentNode = new NoSqlTreeNode(MongoValueDescriptor.createDescriptor(i++, mongoObject));\n                processDbObject(currentNode, mongoObject);\n                rootNode.add(currentNode);\n            }\n        }\n        return rootNode;\n    }\n\n    public static TreeNode buildJsonTree(DBObject mongoObject) {\n        NoSqlTreeNode rootNode = new NoSqlTreeNode(new MongoResultDescriptor());//TODO crappy\n        processDbObject(rootNode, mongoObject);\n        return rootNode;\n    }\n\n    public static void processDbObject(NoSqlTreeNode parentNode, DBObject mongoObject) {\n        if (mongoObject instanceof BasicDBList) {\n            BasicDBList mongoObjectList = (BasicDBList) mongoObject;\n            for (int i = 0; i < mongoObjectList.size(); i++) {\n                Object mongoObjectOfList = mongoObjectList.get(i);\n                NoSqlTreeNode currentNode = new NoSqlTreeNode(MongoValueDescriptor.createDescriptor(i, mongoObjectOfList));\n                if (mongoObjectOfList instanceof DBObject) {\n                    processDbObject(currentNode, (DBObject) mongoObjectOfList);\n                }\n                parentNode.add(currentNode);\n            }\n        } else if (mongoObject instanceof BasicDBObject) {\n            BasicDBObject basicDBObject = (BasicDBObject) mongoObject;\n            for (String key : basicDBObject.keySet()) {\n                Object value = basicDBObject.get(key);\n                NoSqlTreeNode currentNode = new NoSqlTreeNode(MongoKeyValueDescriptor.createDescriptor(key, value));\n                if (value instanceof DBObject) {\n                    processDbObject(currentNode, (DBObject) value);\n                }\n                parentNode.add(currentNode);\n            }\n        }\n    }\n\n    public static DBObject buildDBObject(NoSqlTreeNode rootNode) {\n        BasicDBObject basicDBObject = new BasicDBObject();\n        Enumeration children = rootNode.children();\n        while (children.hasMoreElements()) {\n            NoSqlTreeNode node = (NoSqlTreeNode) children.nextElement();\n            MongoKeyValueDescriptor descriptor = (MongoKeyValueDescriptor) node.getDescriptor();\n            Object value = descriptor.getValue();\n            if (value instanceof DBObject) {\n                if (value instanceof BasicDBList) {\n                    basicDBObject.put(descriptor.getKey(), buildDBList(node));\n                } else {\n                    basicDBObject.put(descriptor.getKey(), buildDBObject(node));\n                }\n            } else {\n                basicDBObject.put(descriptor.getKey(), value);\n            }\n        }\n\n        return basicDBObject;\n    }\n\n    private static DBObject buildDBList(NoSqlTreeNode parentNode) {\n        BasicDBList basicDBList = new BasicDBList();\n        Enumeration children = parentNode.children();\n        while (children.hasMoreElements()) {\n            NoSqlTreeNode node = (NoSqlTreeNode) children.nextElement();\n            MongoValueDescriptor descriptor = (MongoValueDescriptor) node.getDescriptor();\n            Object value = descriptor.getValue();\n            if (value instanceof DBObject) {\n                if (value instanceof BasicDBList) {\n                    basicDBList.add(buildDBList(node));\n                } else {\n                    basicDBList.add(buildDBObject(node));\n                }\n            } else {\n                basicDBList.add(value);\n            }\n        }\n        return basicDBList;\n    }\n\n    public static NoSqlTreeNode findObjectIdNode(NoSqlTreeNode treeNode) {\n        NodeDescriptor descriptor = treeNode.getDescriptor();\n        if (descriptor instanceof MongoResultDescriptor) { //defensive prog?\n            return null;\n        }\n\n        if (descriptor instanceof MongoKeyValueDescriptor) {\n            MongoKeyValueDescriptor keyValueDescriptor = (MongoKeyValueDescriptor) descriptor;\n            if (StringUtils.equals(keyValueDescriptor.getKey(), \"_id\")) {\n                return treeNode;\n            }\n        }\n\n        NoSqlTreeNode parentTreeNode = (NoSqlTreeNode) treeNode.getParent();\n        if (parentTreeNode.getDescriptor() instanceof MongoValueDescriptor) {\n            if (((NoSqlTreeNode) parentTreeNode.getParent()).getDescriptor() instanceof MongoResultDescriptor) {\n                //find\n            }\n        }\n\n        return null;\n    }\n\n    public static Object findDocument(NoSqlTreeNode startingNode) {\n        if (startingNode.getDescriptor() instanceof MongoValueDescriptor) {\n            if (((NoSqlTreeNode) startingNode.getParent()).getDescriptor() instanceof MongoResultDescriptor) {\n                return startingNode.getDescriptor().getValue();\n            }\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/nodedescriptor/MongoKeyValueDescriptor.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view.nodedescriptor;\n\nimport com.intellij.ui.ColoredTableCellRenderer;\nimport com.intellij.ui.ColoredTreeCellRenderer;\nimport com.intellij.ui.SimpleTextAttributes;\nimport com.mongodb.DBObject;\nimport org.bson.types.ObjectId;\nimport org.codinjutsu.tools.nosql.commons.style.StyleAttributesProvider;\nimport org.codinjutsu.tools.nosql.commons.utils.DateUtils;\nimport org.codinjutsu.tools.nosql.commons.utils.StringUtils;\nimport org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor;\n\nimport java.text.DateFormat;\nimport java.util.Date;\nimport java.util.Locale;\n\npublic class MongoKeyValueDescriptor implements NodeDescriptor {\n\n    protected static final String TO_STRING_TEMPLATE = \"\\\"%s\\\" : %s\";\n\n    protected final String key;\n    protected Object value;\n\n    private final SimpleTextAttributes valueTextAttributes;\n\n    public static MongoKeyValueDescriptor createDescriptor(String key, Object value) {\n        if (value == null) {\n            return new MongoKeyNullValueDescriptor(key);\n        }\n\n        if (value instanceof Boolean) {\n            return new MongoKeyValueDescriptor(key, value, StyleAttributesProvider.getBooleanAttribute()) {\n                @Override\n                public void setValue(Object value) {\n                    this.value = Boolean.valueOf((String) value);\n                }\n            };\n        } else if (value instanceof Integer) {\n            return new MongoKeyValueDescriptor(key, value, StyleAttributesProvider.getNumberAttribute()) {\n                @Override\n                public void setValue(Object value) {\n                    this.value = Integer.valueOf((String) value);\n                }\n            };\n        } else if (value instanceof Double) {\n            return new MongoKeyValueDescriptor(key, value, StyleAttributesProvider.getNumberAttribute()) {\n                @Override\n                public void setValue(Object value) {\n                    this.value = Double.valueOf((String) value);\n                }\n            };\n        } else if (value instanceof Long) {\n            return new MongoKeyValueDescriptor(key, value, StyleAttributesProvider.getNumberAttribute()) {\n                @Override\n                public void setValue(Object value) {\n                    this.value = Long.valueOf((String) value);\n                }\n            };\n        } else if (value instanceof String) {\n            return new MongoKeyStringValueDescriptor(key, (String) value);\n        } else if (value instanceof Date) {\n            return new MongoKeyDateValueDescriptor(key, (Date) value);\n        } else if (value instanceof ObjectId) {\n            return new MongoKeyValueDescriptor(key, value, StyleAttributesProvider.getObjectIdAttribute());\n        } else if (value instanceof DBObject) {\n            return new MongoKeyValueDescriptor(key, value, StyleAttributesProvider.getObjectAttribute());\n        } else {\n            return new MongoKeyValueDescriptor(key, value, StyleAttributesProvider.getStringAttribute());\n        }\n    }\n\n    private MongoKeyValueDescriptor(String key, Object value, SimpleTextAttributes valueTextAttributes) {\n        this.key = key;\n        this.value = value;\n        this.valueTextAttributes = valueTextAttributes;\n    }\n\n    public void renderValue(ColoredTableCellRenderer cellRenderer, boolean isNodeExpanded) {\n        if (!isNodeExpanded) {\n            cellRenderer.append(getValueAndAbbreviateIfNecessary(), valueTextAttributes);\n        }\n    }\n\n    public void renderNode(ColoredTreeCellRenderer cellRenderer) {\n        cellRenderer.append(getFormattedKey(), StyleAttributesProvider.getKeyValueAttribute());\n    }\n\n    public String getFormattedKey() {\n        return key;\n    }\n\n    public String getFormattedValue() {\n        return getValueAndAbbreviateIfNecessary();\n    }\n\n    public String getKey() {\n        return key;\n    }\n\n    public Object getValue() {\n        return value;\n    }\n\n    public void setValue(Object value) {\n        this.value = value;\n    }\n\n    @Override\n    public String toString() {\n        return String.format(TO_STRING_TEMPLATE, key, value);\n    }\n\n    protected String getValueAndAbbreviateIfNecessary() {\n        String stringifiedValue = value.toString();\n        if (stringifiedValue.length() > MAX_LENGTH) {\n            return StringUtils.abbreviateInCenter(stringifiedValue, MAX_LENGTH);\n        }\n        return stringifiedValue;\n    }\n\n    private static class MongoKeyNullValueDescriptor extends MongoKeyValueDescriptor {\n\n        private MongoKeyNullValueDescriptor(String key) {\n            super(key, null, StyleAttributesProvider.getNullAttribute());\n        }\n\n        protected String getValueAndAbbreviateIfNecessary() {\n            return \"null\";\n        }\n    }\n\n    private static class MongoKeyStringValueDescriptor extends MongoKeyValueDescriptor {\n\n        private static final String STRING_SURROUNDED = \"\\\"%s\\\"\";\n        private static final String TO_STRING_FOR_STRING_VALUE_TEMPLATE = \"\\\"%s\\\" : \\\"%s\\\"\";\n\n        private MongoKeyStringValueDescriptor(String key, String value) {\n            super(key, value, StyleAttributesProvider.getStringAttribute());\n        }\n\n        @Override\n        protected String getValueAndAbbreviateIfNecessary() {\n            return String.format(STRING_SURROUNDED, value);\n        }\n\n        @Override\n        public String toString() {\n            return String.format(TO_STRING_FOR_STRING_VALUE_TEMPLATE, key, value);\n        }\n    }\n\n    private static class MongoKeyDateValueDescriptor extends MongoKeyValueDescriptor {\n\n        private static final DateFormat DATE_FORMAT = DateUtils.utcDateTime(Locale.getDefault());\n\n        private static final String TO_STRING_FOR_DATE_VALUE_TEMPLATE = \"\\\"%s\\\" : \\\"%s\\\"\";\n\n        private MongoKeyDateValueDescriptor(String key, Date value) {\n            super(key, value, StyleAttributesProvider.getStringAttribute());\n        }\n\n        @Override\n        protected String getValueAndAbbreviateIfNecessary() {\n            return getFormattedDate();\n        }\n\n        @Override\n        public String toString() {\n            return String.format(TO_STRING_FOR_DATE_VALUE_TEMPLATE, key, getFormattedDate());\n        }\n\n        private String getFormattedDate() {\n            return DATE_FORMAT.format(value);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/nodedescriptor/MongoResultDescriptor.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view.nodedescriptor;\n\nimport com.intellij.ui.ColoredTableCellRenderer;\nimport com.intellij.ui.ColoredTreeCellRenderer;\nimport org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor;\n\npublic class MongoResultDescriptor implements NodeDescriptor {\n\n    private final String formattedText;\n\n    public MongoResultDescriptor(String collectionName) {\n        formattedText = String.format(\"results of '%s'\", collectionName);\n    }\n\n    public MongoResultDescriptor() {\n        this(\"\");\n    }\n\n    public void renderValue(ColoredTableCellRenderer cellRenderer, boolean isNodeExpanded) {\n    }\n\n    public void renderNode(ColoredTreeCellRenderer cellRenderer) {\n\n    }\n\n    public String getFormattedKey() {\n        return formattedText;\n    }\n\n    @Override\n    public String getFormattedValue() {\n        return \"\";\n    }\n\n    @Override\n    public String getValue() {\n        return null;\n    }\n\n    @Override\n    public void setValue(Object value) {\n\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/nodedescriptor/MongoValueDescriptor.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view.nodedescriptor;\n\nimport com.intellij.ui.ColoredTableCellRenderer;\nimport com.intellij.ui.ColoredTreeCellRenderer;\nimport com.intellij.ui.SimpleTextAttributes;\nimport com.mongodb.DBObject;\nimport org.codinjutsu.tools.nosql.commons.style.StyleAttributesProvider;\nimport org.codinjutsu.tools.nosql.commons.utils.DateUtils;\nimport org.codinjutsu.tools.nosql.commons.utils.StringUtils;\nimport org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor;\n\nimport java.text.DateFormat;\nimport java.util.Date;\nimport java.util.Locale;\n\npublic class MongoValueDescriptor implements NodeDescriptor {\n\n    private final int index;\n    protected Object value;\n    private final SimpleTextAttributes valueTextAttributes;\n\n    public static MongoValueDescriptor createDescriptor(int index, Object value) {\n        if (value == null) {\n            return new MongoNullValueDescriptor(index);\n        }\n\n        if (value instanceof String) {\n            return new MongoStringValueDescriptor(index, (String) value);\n        } else if (value instanceof Boolean) {\n            return new MongoValueDescriptor(index, value, StyleAttributesProvider.getBooleanAttribute()) {\n                @Override\n                public void setValue(Object value) {\n                    this.value = Boolean.parseBoolean((String) value);\n                }\n            };\n        } else if (value instanceof Number) {\n            return new MongoValueDescriptor(index, value, StyleAttributesProvider.getNumberAttribute()) {\n                @Override\n                public void setValue(Object value) {\n                    this.value = Integer.parseInt((String) value);\n                }\n            };\n        } else if (value instanceof Date) {\n            return new MongoDateValueDescriptor(index, (Date) value);\n        } else if (value instanceof DBObject) {\n            return new MongoValueDescriptor(index, value, StyleAttributesProvider.getObjectAttribute());\n        } else {\n            return new MongoValueDescriptor(index, value, StyleAttributesProvider.getStringAttribute());\n        }\n    }\n\n    private MongoValueDescriptor(int index, Object value, SimpleTextAttributes valueTextAttributes) {\n        this.index = index;\n        this.value = value;\n        this.valueTextAttributes = valueTextAttributes;\n    }\n\n    public void renderValue(ColoredTableCellRenderer cellRenderer, boolean isNodeExpanded) {\n        if (!isNodeExpanded) {\n            cellRenderer.append(getFormattedValue(), valueTextAttributes);\n        }\n    }\n\n    public void renderNode(ColoredTreeCellRenderer cellRenderer) {\n        cellRenderer.append(getFormattedKey(), StyleAttributesProvider.getIndexAttribute());\n    }\n\n    public String getFormattedKey() {\n        return String.format(\"[%s]\", index);\n    }\n\n    public String getFormattedValue() {\n        return String.format(\"%s\", getValueAndAbbreviateIfNecessary());\n    }\n\n    protected String getValueAndAbbreviateIfNecessary() {\n        String stringifiedValue = value.toString();\n        if (stringifiedValue.length() > MAX_LENGTH) {\n            return StringUtils.abbreviateInCenter(stringifiedValue, MAX_LENGTH);\n        }\n        return stringifiedValue;\n    }\n\n    public Object getValue() {\n        return value;\n    }\n\n    public void setValue(Object value) {\n        this.value = value;\n    }\n\n    @Override\n    public String toString() {\n        return value.toString();\n    }\n\n    private static class MongoStringValueDescriptor extends MongoValueDescriptor {\n\n        private MongoStringValueDescriptor(int index, String value) {\n            super(index, value, StyleAttributesProvider.getStringAttribute());\n        }\n\n        @Override\n        public String getFormattedValue() {\n            return String.format(\"\\\"%s\\\"\", getValueAndAbbreviateIfNecessary());\n        }\n    }\n\n    private static class MongoNullValueDescriptor extends MongoValueDescriptor {\n\n        private MongoNullValueDescriptor(int index) {\n            super(index, null, StyleAttributesProvider.getNullAttribute());\n        }\n\n        @Override\n        public String getFormattedValue() {\n            return \"null\";\n        }\n\n        @Override\n        public String toString() {\n            return \"null\";\n        }\n    }\n\n    private static class MongoDateValueDescriptor extends MongoValueDescriptor {\n\n        private static final DateFormat DATE_FORMAT = DateUtils.utcDateTime(Locale.getDefault());\n\n        private static final String TO_STRING_FOR_DATE_VALUE_TEMPLATE = \"\\\"%s\\\"\";\n\n        private MongoDateValueDescriptor(int index, Date value) {\n            super(index, value, StyleAttributesProvider.getStringAttribute());\n        }\n\n        @Override\n        protected String getValueAndAbbreviateIfNecessary() {\n            return getFormattedDate();\n        }\n\n        @Override\n        public String toString() {\n            return String.format(TO_STRING_FOR_DATE_VALUE_TEMPLATE, getFormattedDate());\n        }\n\n        private String getFormattedDate() {\n            return DATE_FORMAT.format(value);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/mongo/view/table/MongoDatePickerCellEditor.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view.table;\n\nimport org.codinjutsu.tools.nosql.commons.utils.DateUtils;\nimport org.codinjutsu.tools.nosql.commons.view.table.DateTimePicker;\nimport org.jdesktop.swingx.table.DatePickerCellEditor;\n\nimport javax.swing.*;\nimport java.awt.event.ActionListener;\nimport java.util.Locale;\n\npublic class MongoDatePickerCellEditor extends DatePickerCellEditor {\n\n    public MongoDatePickerCellEditor() {\n        this.dateFormat = DateUtils.utcDateTime(Locale.getDefault());\n        datePicker = DateTimePicker.create();\n        datePicker.getEditor().setBorder(BorderFactory.createEmptyBorder(0, 1, 0, 1));\n        datePicker.getEditor().setEditable(false);\n    }\n\n    public void addActionListener(ActionListener actionListener) {\n        datePicker.addActionListener(actionListener);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/redis/RedisUI.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.redis;\n\nimport com.intellij.openapi.project.Project;\nimport org.codinjutsu.tools.nosql.commons.DatabaseUI;\nimport org.codinjutsu.tools.nosql.commons.view.AuthenticationView;\nimport org.codinjutsu.tools.nosql.commons.view.NoSqlResultView;\nimport org.codinjutsu.tools.nosql.commons.view.editor.NoSqlDatabaseObjectFile;\nimport org.codinjutsu.tools.nosql.redis.logic.RedisClient;\nimport org.codinjutsu.tools.nosql.redis.view.RedisAuthenticationPanel;\nimport org.codinjutsu.tools.nosql.redis.view.RedisPanel;\nimport org.codinjutsu.tools.nosql.redis.view.editor.RedisObjectFile;\n\npublic class RedisUI implements DatabaseUI {\n    @Override\n    public AuthenticationView createAythenticationView() {\n        return new RedisAuthenticationPanel();\n    }\n\n    @Override\n    public NoSqlResultView createResultPanel(Project project, NoSqlDatabaseObjectFile objectFile) {\n        RedisObjectFile redisObjectFile = (RedisObjectFile) objectFile;\n        return new RedisPanel(project, RedisClient.getInstance(project), redisObjectFile.getConfiguration(), redisObjectFile.getDatabase());\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/redis/RedisUtils.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.redis;\n\nimport org.apache.commons.lang.StringUtils;\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.codinjutsu.tools.nosql.redis.model.RedisDatabase;\nimport redis.clients.jedis.Tuple;\n\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Set;\n\npublic class RedisUtils {\n\n    public static String stringifySortedSet(Set<Tuple> sortedSet) {\n        List<String> stringifiedTuples = new LinkedList<String>();\n        for (Tuple tuple : sortedSet) {\n            stringifiedTuples.add(stringifyTuple(tuple));\n        }\n        return String.format(\"{%s}\", StringUtils.join(stringifiedTuples, \", \"));\n    }\n\n\n    public static String stringifySet(Set set) {\n        return String.format(\"{%s}\", StringUtils.join(set, \", \"));\n    }\n\n\n    public static String stringifyTuple(Tuple tuple) {\n        return String.format(\"(%s, %s)\", tuple.getElement(), tuple.getScore());\n    }\n\n    public static String buildUrl(ServerConfiguration serverConfiguration, RedisDatabase database) {\n        return String.format(\"-n %s\", database.getName());\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/redis/logic/RedisClient.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.redis.logic;\n\nimport com.intellij.openapi.components.ServiceManager;\nimport com.intellij.openapi.project.Project;\nimport org.apache.commons.lang.StringUtils;\nimport org.codinjutsu.tools.nosql.DatabaseVendor;\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.codinjutsu.tools.nosql.commons.logic.DatabaseClient;\nimport org.codinjutsu.tools.nosql.commons.model.AuthenticationSettings;\nimport org.codinjutsu.tools.nosql.commons.model.Database;\nimport org.codinjutsu.tools.nosql.commons.model.DatabaseServer;\nimport org.codinjutsu.tools.nosql.redis.model.RedisDatabase;\nimport org.codinjutsu.tools.nosql.redis.model.RedisKeyType;\nimport org.codinjutsu.tools.nosql.redis.model.RedisQuery;\nimport org.codinjutsu.tools.nosql.redis.model.RedisResult;\nimport redis.clients.jedis.Jedis;\nimport redis.clients.jedis.Tuple;\n\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\npublic class RedisClient implements DatabaseClient {\n\n    public static RedisClient getInstance(Project project) {\n        return ServiceManager.getService(project, RedisClient.class);\n    }\n\n\n    @Override\n    public void connect(ServerConfiguration serverConfiguration) {\n        Jedis jedis = createJedis(serverConfiguration);\n        jedis.connect();\n        String userDatabase = serverConfiguration.getUserDatabase();\n        int index = 0;\n        if (StringUtils.isNotEmpty(userDatabase)) {\n            index = Integer.parseInt(userDatabase);\n        }\n        jedis.select(index);\n    }\n\n    @Override\n    public void loadServer(DatabaseServer databaseServer) {\n        Jedis jedis = createJedis(databaseServer.getConfiguration());\n        List<String> databaseNumberTuple = jedis.configGet(\"databases\");\n        List<Database> databases = new LinkedList<>();\n        String userDatabase = databaseServer.getConfiguration().getUserDatabase();\n        if (StringUtils.isNotEmpty(userDatabase)) {\n            databases.add(new RedisDatabase(userDatabase));\n        } else {\n            int totalNumberOfDatabase = Integer.parseInt(databaseNumberTuple.get(1));\n            for (int databaseNumber = 0; databaseNumber < totalNumberOfDatabase; databaseNumber++) {\n                databases.add(new RedisDatabase(String.valueOf(databaseNumber)));\n            }\n        }\n        databaseServer.setDatabases(databases);\n    }\n\n    @Override\n    public void cleanUpServers() {\n\n    }\n\n    @Override\n    public void registerServer(DatabaseServer databaseServer) {\n\n    }\n\n    @Override\n    public ServerConfiguration defaultConfiguration() {\n        ServerConfiguration configuration = new ServerConfiguration();\n        configuration.setDatabaseVendor(DatabaseVendor.REDIS);\n        configuration.setServerUrl(DatabaseVendor.REDIS.defaultUrl);\n        configuration.setAuthenticationSettings(new AuthenticationSettings());\n        return configuration;\n    }\n\n\n    public RedisResult loadRecords(ServerConfiguration serverConfiguration, RedisDatabase database, RedisQuery query) {\n        Jedis jedis = createJedis(serverConfiguration);\n        jedis.connect();\n        RedisResult redisResult = new RedisResult();\n        int index = Integer.parseInt(database.getName());\n        jedis.select(index);\n\n        Set<String> keys = jedis.keys(query.getFilter());\n        for (String key : keys) {\n            RedisKeyType keyType = RedisKeyType.getKeyType(jedis.type(key));\n            if (RedisKeyType.LIST.equals(keyType)) {\n                List<String> values = jedis.lrange(key, 0, -1);\n                redisResult.addList(key, values);\n            } else if (RedisKeyType.SET.equals(keyType)) {\n                Set<String> values = jedis.smembers(key);\n                redisResult.addSet(key, values);\n            } else if (RedisKeyType.HASH.equals(keyType)) {\n                Map<String, String> values = jedis.hgetAll(key);\n                redisResult.addHash(key, values);\n            } else if (RedisKeyType.ZSET.equals(keyType)) {\n                Set<Tuple> valuesWithScores = jedis.zrangeByScoreWithScores(key, \"-inf\", \"+inf\");\n                redisResult.addSortedSet(key, valuesWithScores);\n            } else if (RedisKeyType.STRING.equals(keyType)) {\n                String value = jedis.get(key);\n                redisResult.addString(key, value);\n            }\n        }\n        return redisResult;\n    }\n\n    private Jedis createJedis(ServerConfiguration serverConfiguration) {\n        String redisUri = \"redis://\";\n        String password = serverConfiguration.getAuthenticationSettings().getPassword();\n        if (StringUtils.isNotEmpty(password)) {\n            redisUri += \":\" + password + \"@\";\n        }\n        redisUri += serverConfiguration.getServerUrl();\n        return new Jedis(redisUri);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/redis/model/RedisDatabase.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.redis.model;\n\nimport org.codinjutsu.tools.nosql.commons.model.Database;\n\npublic class RedisDatabase extends Database {\n\n\n    public RedisDatabase(String name) {\n        super(name);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/redis/model/RedisKeyType.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.redis.model;\n\nimport org.apache.commons.lang.StringUtils;\n\npublic enum RedisKeyType {\n\n    LIST(\"list\"), SET(\"set\"), ZSET(\"zset\"), HASH(\"hash\"), STRING(\"string\");\n    public final String label;\n\n    RedisKeyType(String label) {\n        this.label = label;\n    }\n\n    public static RedisKeyType getKeyType(String type) {\n        for (RedisKeyType keyType : RedisKeyType.values()) {\n            if (StringUtils.equals(type, keyType.label)) {\n                return keyType;\n            }\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/redis/model/RedisQuery.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.redis.model;\n\npublic class RedisQuery {\n\n    private String filter;\n\n    public RedisQuery(String filter) {\n        this.filter = filter;\n    }\n\n    public String getFilter() {\n        return filter;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/redis/model/RedisRecord.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.redis.model;\n\npublic class RedisRecord<T> {\n    private final RedisKeyType keyType;\n    private final String keyName;\n    private final T keyValue;\n\n    public RedisRecord(RedisKeyType keyType, String keyName, T keyValue) {\n        this.keyType = keyType;\n        this.keyName = keyName;\n        this.keyValue = keyValue;\n    }\n\n    public RedisKeyType getKeyType() {\n        return keyType;\n    }\n\n    public String getKey() {\n        return keyName;\n    }\n\n    public T getValue() {\n        return keyValue;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/redis/model/RedisResult.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.redis.model;\n\nimport redis.clients.jedis.Tuple;\n\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\npublic class RedisResult {\n\n    private final List<RedisRecord> redisRecords = new LinkedList<RedisRecord>();\n\n\n    public void addString(String key, String value) {\n        redisRecords.add(new RedisRecord<String>(RedisKeyType.STRING, key, value));\n    }\n\n    public void addList(String key, List values) {\n        redisRecords.add(new RedisRecord<List>(RedisKeyType.LIST, key, values));\n    }\n\n    public void addSet(String key, Set values) {\n        redisRecords.add(new RedisRecord<Set>(RedisKeyType.SET, key, values));\n    }\n\n    public void addHash(String key, Map values) {\n        redisRecords.add(new RedisRecord<Map>(RedisKeyType.HASH, key, values));\n    }\n\n    public void addSortedSet(String key, Set<Tuple> values) {\n        redisRecords.add(new RedisRecord<Set<Tuple>>(RedisKeyType.ZSET, key, values));\n    }\n\n    public List<RedisRecord> getResults() {\n        return redisRecords;\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/redis/view/RedisAuthenticationPanel.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<form xmlns=\"http://www.intellij.com/uidesigner/form/\" version=\"1\" bind-to-class=\"org.codinjutsu.tools.nosql.redis.view.RedisAuthenticationPanel\">\n  <grid id=\"27dc6\" binding=\"mainPanel\" layout-manager=\"GridLayoutManager\" row-count=\"2\" column-count=\"2\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n    <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n    <constraints>\n      <xy x=\"20\" y=\"20\" width=\"554\" height=\"400\"/>\n    </constraints>\n    <properties/>\n    <border type=\"none\"/>\n    <children>\n      <component id=\"3d63b\" class=\"javax.swing.JLabel\">\n        <constraints>\n          <grid row=\"0\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties>\n          <text value=\"Password:\"/>\n        </properties>\n      </component>\n      <component id=\"ca1e9\" class=\"javax.swing.JPasswordField\" binding=\"passwordField\">\n        <constraints>\n          <grid row=\"0\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"6\" anchor=\"8\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\">\n            <preferred-size width=\"150\" height=\"-1\"/>\n          </grid>\n        </constraints>\n        <properties/>\n      </component>\n      <vspacer id=\"498d2\">\n        <constraints>\n          <grid row=\"1\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"6\" hsize-policy=\"1\" anchor=\"0\" fill=\"2\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n      </vspacer>\n    </children>\n  </grid>\n</form>\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/redis/view/RedisAuthenticationPanel.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.redis.view;\n\nimport org.codinjutsu.tools.nosql.commons.model.AuthenticationSettings;\nimport org.codinjutsu.tools.nosql.commons.view.AuthenticationView;\n\nimport javax.swing.*;\n\npublic class RedisAuthenticationPanel implements AuthenticationView {\n\n    private JPasswordField passwordField;\n    private JPanel mainPanel;\n\n    public RedisAuthenticationPanel() {\n        passwordField.setName(\"passwordField\");\n    }\n\n    @Override\n    public JPanel getComponent() {\n        return mainPanel;\n    }\n\n    @Override\n    public AuthenticationSettings create() {\n        AuthenticationSettings authenticationSettings = new AuthenticationSettings();\n        authenticationSettings.setPassword(getPassword());\n        return authenticationSettings;\n    }\n\n    @Override\n    public void load(AuthenticationSettings settings) {\n        passwordField.setText(settings.getPassword());\n    }\n\n    private String getPassword() {\n        char[] password = passwordField.getPassword();\n        if (password != null && password.length != 0) {\n            return String.valueOf(password);\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/redis/view/RedisFragmentedKeyTreeModel.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.redis.view;\n\nimport org.codinjutsu.tools.nosql.commons.utils.StringUtils;\nimport org.codinjutsu.tools.nosql.commons.view.NoSqlTreeNode;\nimport org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor;\nimport org.codinjutsu.tools.nosql.redis.view.nodedescriptor.FragmentedKeyNodeDescriptor;\nimport org.codinjutsu.tools.nosql.redis.view.nodedescriptor.RedisKeyValueDescriptor;\n\nimport javax.swing.event.TreeModelListener;\nimport javax.swing.tree.DefaultMutableTreeNode;\nimport javax.swing.tree.DefaultTreeModel;\nimport javax.swing.tree.MutableTreeNode;\nimport java.util.Arrays;\nimport java.util.Enumeration;\n\nimport static org.apache.commons.lang.StringUtils.isEmpty;\n\npublic class RedisFragmentedKeyTreeModel extends DefaultTreeModel {\n\n    private String separator;\n    private DefaultTreeModel fragmentedKeyModel;\n\n    private boolean needsUpdate = true;\n\n    public RedisFragmentedKeyTreeModel(NoSqlTreeNode root) {\n        super(root);\n        this.separator = \"\";\n    }\n\n    public void setSeparator(String separator) {\n        this.separator = separator;\n        needsUpdate = true;\n        fireSeparatorChanged();\n    }\n\n    public void resetSeparator() {\n        this.separator = \"\";\n        needsUpdate = true;\n        fireSeparatorChanged();\n    }\n\n    @Override\n    public DefaultMutableTreeNode getRoot() {\n        return (DefaultMutableTreeNode) getFragmentedKeyModel().getRoot();\n    }\n\n    @Override\n    public void reload() {\n        super.reload();\n        getFragmentedKeyModel().reload();\n        needsUpdate = true;\n        fireSeparatorChanged();\n    }\n\n    @Override\n    public int getChildCount(Object parent) {\n        return getFragmentedKeyModel().getChildCount(parent);\n    }\n\n    @Override\n    public Object getChild(Object parent, int index) {\n        return getFragmentedKeyModel().getChild(parent, index);\n    }\n\n    @Override\n    public int getIndexOfChild(Object parent, Object child) {\n        return getFragmentedKeyModel().getIndexOfChild(parent, child);\n    }\n\n    @Override\n    public void addTreeModelListener(TreeModelListener listener) {\n        super.addTreeModelListener(listener);\n        getFragmentedKeyModel().addTreeModelListener(listener);\n    }\n\n    @Override\n    public void removeTreeModelListener(TreeModelListener listener) {\n        super.removeTreeModelListener(listener);\n        getFragmentedKeyModel().removeTreeModelListener(listener);\n    }\n\n    @Override\n    public boolean isLeaf(Object node) {\n        return getFragmentedKeyModel().isLeaf(node);\n    }\n\n    private DefaultTreeModel getFragmentedKeyModel() {\n        if (needsUpdate) {\n            needsUpdate = false;\n            updateFilteredModel();\n        }\n        return fragmentedKeyModel;\n    }\n\n    private void updateFilteredModel() {\n        DefaultMutableTreeNode sourceRoot = (DefaultMutableTreeNode) super.getRoot();\n        DefaultMutableTreeNode targetRoot = (DefaultMutableTreeNode) sourceRoot.clone();\n        wrapNodes(sourceRoot, separator);\n        fragmentedKeyModel = new DefaultTreeModel(targetRoot);\n        Object[] listeners = listenerList.getListenerList();\n        for (int i = listeners.length - 2; i >= 0; i -= 2) {\n            if (listeners[i] == TreeModelListener.class) {\n                fragmentedKeyModel.addTreeModelListener((TreeModelListener) listeners[i + 1]);\n            }\n        }\n        fireSeparatorChanged();\n    }\n\n    private void fireSeparatorChanged() {\n        getFragmentedKeyModel().reload();\n    }\n\n    public static DefaultMutableTreeNode wrapNodes(DefaultMutableTreeNode source, String separator) {\n        if (isEmpty(separator)) {\n            return source;\n        }\n        DefaultMutableTreeNode targetRootNode = (DefaultMutableTreeNode) source.clone();\n        for (int i = 0; i < source.getChildCount(); i++) {\n            DefaultMutableTreeNode originalChildNode = (DefaultMutableTreeNode) source.getChildAt(i);\n            NoSqlTreeNode clonedChildNode = (NoSqlTreeNode) originalChildNode.clone();\n            RedisKeyValueDescriptor descriptor = (RedisKeyValueDescriptor) clonedChildNode.getDescriptor();\n            String[] explodedKey = StringUtils.explode(descriptor.getKey(), separator);\n            if (explodedKey.length == 1) {\n                addChildren(clonedChildNode, originalChildNode);\n                targetRootNode.add(clonedChildNode);\n            } else {\n                updateTree(targetRootNode, originalChildNode, explodedKey, descriptor);\n            }\n        }\n        return targetRootNode;\n    }\n\n    private static void updateTree(DefaultMutableTreeNode parentTargetNode, DefaultMutableTreeNode originalChildNode, String[] explodedKey, RedisKeyValueDescriptor sourceDescriptor) {\n        if (explodedKey.length == 0) {\n            addChildren(parentTargetNode, originalChildNode);\n            return;\n        }\n        String keyFragment = explodedKey[0];\n        NoSqlTreeNode node = findNodeByKey(parentTargetNode, keyFragment);\n        if (node == null) {\n            if (explodedKey.length == 1) {\n                node = new NoSqlTreeNode(RedisKeyValueDescriptor.createDescriptor(sourceDescriptor.getKeyType(), keyFragment, sourceDescriptor.getValue()));\n            } else {\n                node = new NoSqlTreeNode(FragmentedKeyNodeDescriptor.createDescriptor(keyFragment));\n            }\n        }\n        updateTree(node, originalChildNode, Arrays.copyOfRange(explodedKey, 1, explodedKey.length), sourceDescriptor);\n\n        parentTargetNode.add(node);\n    }\n\n    private static NoSqlTreeNode findNodeByKey(DefaultMutableTreeNode parentTargetNode, String keyFragment) {\n        for (int i = 0; i < parentTargetNode.getChildCount(); i++) {\n            NoSqlTreeNode currentChild = (NoSqlTreeNode) parentTargetNode.getChildAt(i);\n            NodeDescriptor descriptor = currentChild.getDescriptor();\n            String nodeKey;\n            if (descriptor instanceof FragmentedKeyNodeDescriptor) {\n                nodeKey = ((FragmentedKeyNodeDescriptor) descriptor).getKeyFragment();\n            } else if (descriptor instanceof RedisKeyValueDescriptor) {\n                nodeKey = ((RedisKeyValueDescriptor) descriptor).getKey();\n            } else {\n                return null;\n            }\n            if (keyFragment.equals(nodeKey)) {\n                return currentChild;\n            }\n        }\n        return null;\n    }\n\n    private static void addChildren(DefaultMutableTreeNode parentNode, DefaultMutableTreeNode originalChildNode) {\n        Enumeration children = originalChildNode.children();\n        while (children.hasMoreElements()) {\n            DefaultMutableTreeNode childNode = (DefaultMutableTreeNode) children.nextElement();\n            parentNode.add((MutableTreeNode) childNode.clone());\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/redis/view/RedisPanel.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<form xmlns=\"http://www.intellij.com/uidesigner/form/\" version=\"1\" bind-to-class=\"org.codinjutsu.tools.nosql.redis.view.RedisPanel\">\n  <grid id=\"27dc6\" binding=\"mainPanel\" layout-manager=\"GridLayoutManager\" row-count=\"3\" column-count=\"1\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n    <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n    <constraints>\n      <xy x=\"20\" y=\"20\" width=\"500\" height=\"400\"/>\n    </constraints>\n    <properties/>\n    <border type=\"none\"/>\n    <children>\n      <grid id=\"38b52\" binding=\"toolBarPanel\" layout-manager=\"GridLayoutManager\" row-count=\"1\" column-count=\"1\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n        <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n        <constraints>\n          <grid row=\"0\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n        <border type=\"none\"/>\n        <children/>\n      </grid>\n      <grid id=\"48d00\" binding=\"containerPanel\" layout-manager=\"BorderLayout\" hgap=\"0\" vgap=\"0\">\n        <constraints>\n          <grid row=\"1\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n        <border type=\"none\"/>\n        <children/>\n      </grid>\n      <grid id=\"1b5c1\" binding=\"errorPanel\" layout-manager=\"GridLayoutManager\" row-count=\"1\" column-count=\"1\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n        <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n        <constraints>\n          <grid row=\"2\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n        <border type=\"none\"/>\n        <children/>\n      </grid>\n    </children>\n  </grid>\n</form>\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/redis/view/RedisPanel.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.redis.view;\n\nimport com.intellij.ide.CommonActionsManager;\nimport com.intellij.ide.TreeExpander;\nimport com.intellij.openapi.Disposable;\nimport com.intellij.openapi.actionSystem.ActionManager;\nimport com.intellij.openapi.actionSystem.ActionToolbar;\nimport com.intellij.openapi.actionSystem.AnAction;\nimport com.intellij.openapi.actionSystem.DefaultActionGroup;\nimport com.intellij.openapi.progress.ProgressIndicator;\nimport com.intellij.openapi.progress.ProgressManager;\nimport com.intellij.openapi.progress.Task;\nimport com.intellij.openapi.project.Project;\nimport com.intellij.openapi.ui.LoadingDecorator;\nimport com.intellij.openapi.util.Disposer;\nimport com.intellij.ui.components.JBScrollPane;\nimport com.intellij.ui.components.JBTextField;\nimport com.intellij.ui.components.panels.NonOpaquePanel;\nimport com.intellij.ui.treeStructure.treetable.TreeTableTree;\nimport com.intellij.util.ui.tree.TreeUtil;\nimport org.apache.commons.lang.StringUtils;\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.codinjutsu.tools.nosql.commons.utils.GuiUtils;\nimport org.codinjutsu.tools.nosql.commons.view.ErrorPanel;\nimport org.codinjutsu.tools.nosql.commons.view.NoSqlResultView;\nimport org.codinjutsu.tools.nosql.commons.view.action.ExecuteQuery;\nimport org.codinjutsu.tools.nosql.mongo.view.JsonTreeTableView;\nimport org.codinjutsu.tools.nosql.redis.logic.RedisClient;\nimport org.codinjutsu.tools.nosql.redis.model.RedisDatabase;\nimport org.codinjutsu.tools.nosql.redis.model.RedisQuery;\nimport org.codinjutsu.tools.nosql.redis.model.RedisResult;\nimport org.codinjutsu.tools.nosql.redis.view.action.EnableGroupingAction;\nimport org.codinjutsu.tools.nosql.redis.view.action.SetSeparatorAction;\n\nimport javax.swing.*;\nimport javax.swing.tree.DefaultMutableTreeNode;\nimport java.awt.*;\n\npublic class RedisPanel extends NoSqlResultView<RedisResult> {\n\n    private JPanel toolBarPanel;\n    private JPanel containerPanel;\n    private JPanel errorPanel;\n    private JPanel resultPanel;\n    private JPanel mainPanel;\n    private final LoadingDecorator loadingDecorator;\n\n\n    private JsonTreeTableView resultTableView;\n\n    private final Project project;\n    private final RedisClient redisClient;\n    private final ServerConfiguration configuration;\n    private final RedisDatabase database;\n    private JBTextField filterField;\n    private RedisResult redisResult;\n    private boolean groupData;\n    private String groupSeparator;\n\n    public RedisPanel(Project project, RedisClient redisClient, ServerConfiguration configuration, RedisDatabase database) {\n        this.project = project;\n        this.redisClient = redisClient;\n        this.configuration = configuration;\n        this.database = database;\n        this.resultPanel = new JPanel(new BorderLayout());\n\n\n        buildQueryToolBar();\n\n        loadingDecorator = new LoadingDecorator(resultPanel, this, 0);\n\n        containerPanel.add(loadingDecorator.getComponent());\n        loadAndDisplayResults(getFilter(), this.groupData, this.groupSeparator);\n\n        setLayout(new BorderLayout());\n        add(mainPanel);\n    }\n\n    private void loadAndDisplayResults(final String filter, final boolean groupByPrefix, final String separator) {\n        redisResult = redisClient.loadRecords(configuration, database, new RedisQuery(filter));\n        updateResultTableTree(redisResult, groupByPrefix, separator);\n    }\n\n    protected void buildQueryToolBar() {\n        toolBarPanel.setLayout(new BorderLayout());\n\n        filterField = new JBTextField(\"*\");\n        filterField.setColumns(10);\n\n        NonOpaquePanel westPanel = new NonOpaquePanel();\n\n        NonOpaquePanel filterPanel = new NonOpaquePanel();\n        filterPanel.add(new JLabel(\"Filter: \"), BorderLayout.WEST);\n        filterPanel.add(filterField, BorderLayout.CENTER);\n        filterPanel.add(Box.createHorizontalStrut(5), BorderLayout.EAST);\n        westPanel.add(filterPanel, BorderLayout.WEST);\n\n        toolBarPanel.add(westPanel, BorderLayout.WEST);\n\n        addCommonsActions();\n    }\n\n    protected void addCommonsActions() {\n        final TreeExpander treeExpander = new TreeExpander() {\n            @Override\n            public void expandAll() {\n                RedisPanel.this.expandAll();\n            }\n\n            @Override\n            public boolean canExpand() {\n                return true;\n            }\n\n            @Override\n            public void collapseAll() {\n                RedisPanel.this.collapseAll();\n            }\n\n            @Override\n            public boolean canCollapse() {\n                return true;\n            }\n        };\n\n        CommonActionsManager actionsManager = CommonActionsManager.getInstance();\n\n        final AnAction expandAllAction = actionsManager.createExpandAllAction(treeExpander, resultPanel);\n        final AnAction collapseAllAction = actionsManager.createCollapseAllAction(treeExpander, resultPanel);\n\n        Disposer.register(this, new Disposable() {\n            @Override\n            public void dispose() {\n                collapseAllAction.unregisterCustomShortcutSet(resultPanel);\n                expandAllAction.unregisterCustomShortcutSet(resultPanel);\n            }\n        });\n\n        DefaultActionGroup actionResultGroup = new DefaultActionGroup(\"RedisResultGroup\", true);\n        actionResultGroup.add(new ExecuteQuery<>(this));\n        actionResultGroup.addSeparator();\n        actionResultGroup.add(new EnableGroupingAction(this));\n        actionResultGroup.add(new SetSeparatorAction(this));\n        actionResultGroup.addSeparator();\n        actionResultGroup.add(expandAllAction);\n        actionResultGroup.add(collapseAllAction);\n\n        ActionToolbar actionToolBar = ActionManager.getInstance().createActionToolbar(\"MongoResultGroupActions\", actionResultGroup, true);\n        actionToolBar.setLayoutPolicy(ActionToolbar.AUTO_LAYOUT_POLICY);\n        JComponent actionToolBarComponent = actionToolBar.getComponent();\n        actionToolBarComponent.setBorder(null);\n        actionToolBarComponent.setOpaque(false);\n\n        toolBarPanel.add(actionToolBarComponent, BorderLayout.CENTER);\n    }\n\n    private String getFilter() {\n        String filter = filterField.getText();\n        if (StringUtils.isNotBlank(filter)) {\n            return filter;\n        }\n        return \"*\";\n    }\n\n    void expandAll() {\n        TreeUtil.expandAll(resultTableView.getTree());\n    }\n\n    void collapseAll() {\n        TreeTableTree tree = resultTableView.getTree();\n        TreeUtil.collapseAll(tree, 1);\n    }\n\n    public void updateResultTableTree(RedisResult redisResult, boolean groupByPrefix, String separator) {\n        DefaultMutableTreeNode rootNode = RedisTreeModel.buildTree(redisResult);\n        DefaultMutableTreeNode renderedNode = rootNode;\n        if (groupByPrefix && StringUtils.isNotBlank(separator)) {\n            renderedNode = RedisFragmentedKeyTreeModel.wrapNodes(rootNode, separator);\n        }\n        resultTableView = new JsonTreeTableView(renderedNode, JsonTreeTableView.COLUMNS_FOR_READING);\n        resultTableView.setName(\"resultTreeTable\");\n\n        resultPanel.invalidate();\n        resultPanel.removeAll();\n        resultPanel.add(new JBScrollPane(resultTableView));\n        resultPanel.validate();\n    }\n\n    @Override\n    public void showResults() {\n        executeQuery();\n    }\n\n    @Override\n    public JPanel getResultPanel() {\n        return resultPanel;\n    }\n\n    @Override\n    public RedisResult getRecords() {\n        return redisResult;\n    }\n\n    @Override\n    public void executeQuery() {\n        errorPanel.setVisible(false);\n        ProgressManager.getInstance().run(new Task.Backgroundable(project, \"Executing query\", true)  {\n            @Override\n            public void run(ProgressIndicator indicator) {\n                try {\n                    GuiUtils.runInSwingThread(new Runnable() {\n                        @Override\n                        public void run() {\n                            loadingDecorator.startLoading(false);\n                        }\n                    });\n\n\n                    loadAndDisplayResults(getFilter(), isGroupDataEnabled(), getGroupSeparator());\n                } catch (final Exception ex) {\n                    GuiUtils.runInSwingThread(new Runnable() {\n                        @Override\n                        public void run() {\n                            errorPanel.invalidate();\n                            errorPanel.removeAll();\n                            errorPanel.add(new ErrorPanel(ex), BorderLayout.CENTER);\n                            errorPanel.validate();\n                            errorPanel.setVisible(true);\n                        }\n                    });\n                } finally {\n                    GuiUtils.runInSwingThread(new Runnable() {\n                        @Override\n                        public void run() {\n                            loadingDecorator.stopLoading();\n                        }\n                    });\n                }\n            }\n        });\n\n    }\n\n    @Override\n    public void dispose() {\n\n    }\n\n    public boolean isGroupDataEnabled() {\n        return this.groupData;\n    }\n\n    public void toggleGroupData(boolean enabled) {\n        this.groupData = enabled;\n        updateResultTableTree(redisResult, this.groupData, this.groupSeparator);\n    }\n\n    public String getGroupSeparator() {\n        return groupSeparator;\n    }\n\n    public void setGroupSeparator(String groupSeparator) {\n        this.groupSeparator = groupSeparator;\n        updateResultTableTree(redisResult, this.groupData, this.groupSeparator);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/redis/view/RedisTreeModel.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.redis.view;\n\nimport org.codinjutsu.tools.nosql.commons.view.NoSqlTreeNode;\nimport org.codinjutsu.tools.nosql.redis.model.RedisKeyType;\nimport org.codinjutsu.tools.nosql.redis.model.RedisRecord;\nimport org.codinjutsu.tools.nosql.redis.model.RedisResult;\nimport org.codinjutsu.tools.nosql.redis.view.nodedescriptor.RedisKeyValueDescriptor;\nimport org.codinjutsu.tools.nosql.redis.view.nodedescriptor.RedisResultDescriptor;\nimport org.codinjutsu.tools.nosql.redis.view.nodedescriptor.RedisValueDescriptor;\n\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\npublic class RedisTreeModel {\n    public static NoSqlTreeNode buildTree(RedisResult redisResult) {\n        NoSqlTreeNode rootNode = new NoSqlTreeNode(new RedisResultDescriptor());\n\n        List<RedisRecord> redisRecords = redisResult.getResults();\n        for (RedisRecord redisRecord : redisRecords) {\n            processRecord(rootNode, redisRecord);\n        }\n\n        return rootNode;\n    }\n\n    private static void processRecord(NoSqlTreeNode rootNode, RedisRecord redisRecord) {\n        RedisKeyType keyType = redisRecord.getKeyType();\n        NoSqlTreeNode treeNode = new NoSqlTreeNode(RedisKeyValueDescriptor.createDescriptor(keyType, redisRecord.getKey(), redisRecord.getValue()));\n        if (RedisKeyType.LIST.equals(keyType)) {\n            List<String> valuesFromList = (List<String>) redisRecord.getValue();\n            for (int index = 0; index < valuesFromList.size(); index++) {\n                String value = valuesFromList.get(index);\n                treeNode.add(new NoSqlTreeNode(RedisValueDescriptor.createDescriptor(index, value)));\n            }\n        } else if (RedisKeyType.SET.equals(keyType) || RedisKeyType.ZSET.equals(keyType)) {\n            Set valuesFromSet = (Set) redisRecord.getValue();\n            for (Object value : valuesFromSet) {\n                treeNode.add(new NoSqlTreeNode(RedisValueDescriptor.createUnindexedDescriptor(value)));\n            }\n        } else if (RedisKeyType.HASH.equals(keyType)) {\n            Map<String, String> valuesFromMap = (Map<String, String>) redisRecord.getValue();\n            for (Map.Entry<String, String> entry : valuesFromMap.entrySet()) {\n                treeNode.add(new NoSqlTreeNode(RedisKeyValueDescriptor.createDescriptor(entry.getKey(), entry.getValue())));\n            }\n        }\n        rootNode.add(treeNode);\n\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/redis/view/action/EnableGroupingAction.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.redis.view.action;\n\nimport com.intellij.icons.AllIcons;\nimport com.intellij.openapi.actionSystem.AnActionEvent;\nimport com.intellij.openapi.actionSystem.ToggleAction;\nimport org.codinjutsu.tools.nosql.redis.view.RedisPanel;\n\npublic class EnableGroupingAction extends ToggleAction {\n\n\n    private final RedisPanel redisPanel;\n\n    private boolean isGroupData = false;\n\n    public EnableGroupingAction(RedisPanel redisPanel) {\n        super(\"Group by prefix\", \"Group by prefix\", AllIcons.Actions.GroupByPrefix);\n        this.redisPanel = redisPanel;\n    }\n\n    @Override\n    public boolean isSelected(AnActionEvent event) {\n        return isGroupData;\n    }\n\n    @Override\n    public void setSelected(AnActionEvent event, boolean state) {\n        redisPanel.toggleGroupData(state);\n        isGroupData = state;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/redis/view/action/SetSeparatorAction.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.redis.view.action;\n\nimport com.intellij.icons.AllIcons;\nimport com.intellij.openapi.actionSystem.AnAction;\nimport com.intellij.openapi.actionSystem.AnActionEvent;\nimport com.intellij.openapi.ui.Messages;\nimport com.intellij.util.ArrayUtil;\nimport org.apache.commons.lang.StringUtils;\nimport org.codinjutsu.tools.nosql.redis.view.RedisPanel;\n\nimport java.util.LinkedHashSet;\nimport java.util.Set;\n\npublic class SetSeparatorAction extends AnAction {\n\n    private final RedisPanel redisPanel;\n\n    private static final Set<String> myPredefinedSeparators = new LinkedHashSet<>();\n\n\n    public SetSeparatorAction(RedisPanel redisPanel) {\n        super(AllIcons.General.Ellipsis);\n        this.redisPanel = redisPanel;\n        myPredefinedSeparators.add(\".\");\n        myPredefinedSeparators.add(\":\");\n    }\n\n    @Override\n    public void actionPerformed(AnActionEvent event) {\n        String[] strings = ArrayUtil.toStringArray(myPredefinedSeparators);\n        String current = redisPanel.getGroupSeparator();\n        String separator = Messages.showEditableChooseDialog(\"Redis Keys Separator\",\n                \"Select Separator\",\n                Messages.getQuestionIcon(),\n                strings, current, null);\n        if (separator == null) {\n            return;\n        }\n\n        if (StringUtils.equals(redisPanel.getGroupSeparator(), separator)) {\n            return;\n        }\n\n        redisPanel.setGroupSeparator(separator);\n\n        myPredefinedSeparators.add(separator);\n        update(event);\n    }\n\n    @Override\n    public void update(AnActionEvent event) {\n        String currentSeparator = redisPanel.getGroupSeparator();\n        String textToDisplay = String.format(\"Group by '%s'\", (currentSeparator == null ? \"Nothing\" : currentSeparator));\n        event.getPresentation().setText(textToDisplay);\n        event.getPresentation().setDescription(textToDisplay);\n        event.getPresentation().setEnabled(redisPanel.isGroupDataEnabled());\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/redis/view/console/RedisConsoleRunner.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.redis.view.console;\n\nimport com.intellij.execution.ExecutionException;\nimport com.intellij.execution.configurations.GeneralCommandLine;\nimport com.intellij.execution.console.ConsoleHistoryController;\nimport com.intellij.execution.console.ConsoleRootType;\nimport com.intellij.execution.console.ProcessBackedConsoleExecuteActionHandler;\nimport com.intellij.execution.process.OSProcessHandler;\nimport com.intellij.execution.runners.AbstractConsoleRunnerWithHistory;\nimport com.intellij.openapi.project.Project;\nimport com.intellij.openapi.util.Key;\nimport com.intellij.psi.PsiFile;\nimport org.apache.commons.lang.StringUtils;\nimport org.codinjutsu.tools.nosql.DatabaseVendor;\nimport org.codinjutsu.tools.nosql.NoSqlConfiguration;\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.codinjutsu.tools.nosql.commons.view.console.NoSqlConsoleView;\nimport org.codinjutsu.tools.nosql.redis.model.RedisDatabase;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\n\npublic class RedisConsoleRunner extends AbstractConsoleRunnerWithHistory<NoSqlConsoleView> {\n\n    private static final Key<Boolean> SHELL_FILE = Key.create(\"REDIS_SHELL_FILE\");\n    private final ServerConfiguration serverConfiguration;\n    private final RedisDatabase database;\n\n\n    public RedisConsoleRunner(@NotNull Project project, ServerConfiguration serverConfiguration, RedisDatabase database) {\n        super(project, \"Redis Shell\", \"/tmp\");\n\n        this.serverConfiguration = serverConfiguration;\n        this.database = database;\n    }\n\n    @Override\n    protected NoSqlConsoleView createConsoleView() {\n        NoSqlConsoleView res = new NoSqlConsoleView(getProject(), \"Redis Console\", serverConfiguration);\n\n        PsiFile file = res.getFile();\n        assert file.getContext() == null;\n        file.putUserData(SHELL_FILE, Boolean.TRUE);\n\n        return res;\n    }\n\n    @Nullable\n    @Override\n    protected Process createProcess() throws ExecutionException {\n\n        NoSqlConfiguration noSqlConfiguration = NoSqlConfiguration.getInstance(getProject());\n        String shellPath = noSqlConfiguration.getShellPath(DatabaseVendor.REDIS);\n        final GeneralCommandLine commandLine = new GeneralCommandLine();\n        commandLine.setExePath(shellPath);\n\n        commandLine.addParameter(\"-n\");\n        commandLine.addParameter(database.getName());\n\n        String shellWorkingDir = serverConfiguration.getShellWorkingDir();\n        if (StringUtils.isNotBlank(shellWorkingDir)) {\n            commandLine.setWorkDirectory(shellWorkingDir);\n        }\n\n        String shellArgumentsLine = serverConfiguration.getShellArgumentsLine();\n        if (StringUtils.isNotBlank(shellArgumentsLine)) {\n            commandLine.addParameters(shellArgumentsLine.split(\" \"));\n        }\n\n        return commandLine.createProcess();\n    }\n\n    @Override\n    protected OSProcessHandler createProcessHandler(Process process) {\n        return new OSProcessHandler(process, null);\n    }\n\n    @NotNull\n    @Override\n    protected ProcessBackedConsoleExecuteActionHandler createExecuteActionHandler() {\n        ProcessBackedConsoleExecuteActionHandler handler = new ProcessBackedConsoleExecuteActionHandler(getProcessHandler(), false) {\n            @Override\n            public String getEmptyExecuteAction() {\n                return \"NoSql.Shell.Execute\";\n            }\n        };\n        new ConsoleHistoryController(new ConsoleRootType(\"Redis Shell\", null) {\n        }, null, getConsoleView()).install();\n        return handler;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/redis/view/editor/RedisFakeFileType.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.redis.view.editor;\n\nimport com.intellij.openapi.fileTypes.FileType;\nimport com.intellij.openapi.fileTypes.ex.FakeFileType;\nimport com.intellij.openapi.vfs.VirtualFile;\nimport org.codinjutsu.tools.nosql.commons.utils.GuiUtils;\nimport org.jetbrains.annotations.NotNull;\n\nimport javax.swing.*;\n\npublic class RedisFakeFileType extends FakeFileType {\n\n    public static final Icon REDIS_ICON = GuiUtils.loadIcon(\"redis.png\");\n\n    public static final FileType INSTANCE = new RedisFakeFileType();\n\n    @Override\n    public Icon getIcon() {\n        return REDIS_ICON;\n    }\n\n    @Override\n    public boolean isMyFileType(VirtualFile file) {\n        return false;\n    }\n\n    @NotNull\n    @Override\n    public String getDefaultExtension() {\n        return \"json\";\n    }\n\n    @NotNull\n    @Override\n    public String getName() {\n        return \"REDIS\";\n    }\n\n    @NotNull\n    @Override\n    public String getDescription() {\n        return \"REDIS\";\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/redis/view/editor/RedisObjectFile.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.redis.view.editor;\n\nimport com.intellij.openapi.fileTypes.FileType;\nimport com.intellij.openapi.project.Project;\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.codinjutsu.tools.nosql.commons.view.editor.NoSqlDatabaseObjectFile;\nimport org.codinjutsu.tools.nosql.redis.model.RedisDatabase;\nimport org.jetbrains.annotations.NotNull;\n\npublic class RedisObjectFile extends NoSqlDatabaseObjectFile {\n    private RedisDatabase database;\n\n    public RedisObjectFile(Project project, ServerConfiguration configuration, RedisDatabase redisDatabase) {\n        super(project, configuration, String.format(\"%s/%s\", configuration.getLabel(), redisDatabase.getName()));\n        this.database = redisDatabase;\n    }\n\n    @NotNull\n    public FileType getFileType() {\n        return RedisFakeFileType.INSTANCE;\n    }\n\n    public RedisDatabase getDatabase() {\n        return database;\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/redis/view/nodedescriptor/FragmentedKeyNodeDescriptor.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.redis.view.nodedescriptor;\n\nimport com.intellij.icons.AllIcons;\nimport com.intellij.ui.ColoredTableCellRenderer;\nimport com.intellij.ui.ColoredTreeCellRenderer;\nimport com.intellij.ui.SimpleTextAttributes;\nimport org.codinjutsu.tools.nosql.commons.style.StyleAttributesProvider;\nimport org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor;\n\npublic class FragmentedKeyNodeDescriptor implements NodeDescriptor {\n\n    private final String keyFragment;\n    private final SimpleTextAttributes keyAttribute;\n\n    public FragmentedKeyNodeDescriptor(String keyFragment, SimpleTextAttributes keyAttribute) {\n        this.keyFragment = keyFragment;\n        this.keyAttribute = keyAttribute;\n    }\n\n    public static FragmentedKeyNodeDescriptor createDescriptor(String key) {\n        return new FragmentedKeyNodeDescriptor(key, StyleAttributesProvider.getKeyValueAttribute());\n    }\n\n    public String getKeyFragment() {\n        return keyFragment;\n    }\n\n    @Override\n    public void renderValue(ColoredTableCellRenderer cellRenderer, boolean isNodeExpanded) {\n\n    }\n\n    @Override\n    public void renderNode(ColoredTreeCellRenderer cellRenderer) {\n        cellRenderer.append(keyFragment, keyAttribute);\n        cellRenderer.setIcon(AllIcons.Nodes.Advice);\n    }\n\n    @Override\n    public String getFormattedKey() {\n        return keyFragment;\n    }\n\n    @Override\n    public String getFormattedValue() {\n        return \"\";\n    }\n\n    @Override\n    public Object getValue() {\n        return null;\n    }\n\n    @Override\n    public void setValue(Object value) {\n\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/redis/view/nodedescriptor/RedisKeyValueDescriptor.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.redis.view.nodedescriptor;\n\nimport com.intellij.icons.AllIcons;\nimport com.intellij.ui.ColoredTableCellRenderer;\nimport com.intellij.ui.ColoredTreeCellRenderer;\nimport com.intellij.ui.SimpleTextAttributes;\nimport org.codinjutsu.tools.nosql.commons.style.StyleAttributesProvider;\nimport org.codinjutsu.tools.nosql.commons.utils.StringUtils;\nimport org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor;\nimport org.codinjutsu.tools.nosql.redis.RedisUtils;\nimport org.codinjutsu.tools.nosql.redis.model.RedisKeyType;\nimport redis.clients.jedis.Tuple;\n\nimport javax.swing.*;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\npublic class RedisKeyValueDescriptor implements NodeDescriptor {\n\n\n    private final RedisKeyType keyType;\n    private final String key;\n    private final Object value;\n\n    private final SimpleTextAttributes valueTextAttributes;\n    private final Icon icon;\n\n    public static RedisKeyValueDescriptor createDescriptor(RedisKeyType keyType, String key, Object value) {\n        return new RedisKeyValueDescriptor(keyType, key, value, StyleAttributesProvider.getStringAttribute());\n    }\n\n    public static NodeDescriptor createDescriptor(String key, String value) {\n        return createDescriptor(null, key, value);\n    }\n\n    public RedisKeyValueDescriptor(RedisKeyType keyType, String key, Object value, SimpleTextAttributes valueTextAttributes) {\n        this.keyType = keyType;\n        this.key = key;\n        this.value = value;\n        this.icon = findIcon(value);\n        this.valueTextAttributes = valueTextAttributes;\n    }\n\n    private Icon findIcon(Object object) {\n        if (object instanceof List) {\n            return AllIcons.Json.Property_brackets;\n        } else if (object instanceof Set || object instanceof Map) {\n            return AllIcons.Json.Property_braces;\n        }\n        return null;\n    }\n\n\n    @Override\n    public void renderValue(ColoredTableCellRenderer cellRenderer, boolean isNodeExpanded) {\n        if (!isNodeExpanded) {\n            cellRenderer.append(getFormattedValue(), valueTextAttributes);\n        }\n    }\n\n    public void renderNode(ColoredTreeCellRenderer cellRenderer) {\n        cellRenderer.setIcon(this.icon);\n        if (this.keyType != null) {\n            cellRenderer.append(this.keyType.name(), StyleAttributesProvider.getIndexAttribute());\n            cellRenderer.append(\" \");\n        }\n        cellRenderer.append(getFormattedKey(), StyleAttributesProvider.getKeyValueAttribute());\n    }\n\n    @Override\n    public String getFormattedKey() {\n        return key;\n    }\n\n    @Override\n    public String getFormattedValue() {\n        if (RedisKeyType.ZSET.equals(keyType)) {\n            return getValueAndAbbreviateIfNecessary(RedisUtils.stringifySortedSet((Set<Tuple>) getValue()));\n        } else if (RedisKeyType.SET.equals(keyType)) {\n            return getValueAndAbbreviateIfNecessary(RedisUtils.stringifySet((Set) getValue()));\n        }\n        return getValueAndAbbreviateIfNecessary(getValue().toString());\n    }\n\n    @Override\n    public Object getValue() {\n        return value;\n    }\n\n    @Override\n    public void setValue(Object value) {\n\n    }\n\n    public String getKey() {\n        return key;\n    }\n\n    public RedisKeyType getKeyType() {\n        return keyType;\n    }\n\n    protected String getValueAndAbbreviateIfNecessary(String stringifiedValue) {\n        if (stringifiedValue.length() > MAX_LENGTH) {\n            return StringUtils.abbreviateInCenter(stringifiedValue, MAX_LENGTH);\n        }\n        return stringifiedValue;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/redis/view/nodedescriptor/RedisResultDescriptor.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.redis.view.nodedescriptor;\n\nimport com.intellij.ui.ColoredTableCellRenderer;\nimport com.intellij.ui.ColoredTreeCellRenderer;\nimport org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor;\n\n\npublic class RedisResultDescriptor implements NodeDescriptor {\n    @Override\n    public void renderValue(ColoredTableCellRenderer cellRenderer, boolean isNodeExpanded) {\n\n    }\n\n    @Override\n    public void renderNode(ColoredTreeCellRenderer cellRenderer) {\n\n    }\n\n    @Override\n    public String getFormattedKey() {\n        return null;\n    }\n\n    @Override\n    public String getFormattedValue() {\n        return null;\n    }\n\n    @Override\n    public Object getValue() {\n        return null;\n    }\n\n    @Override\n    public void setValue(Object value) {\n\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/codinjutsu/tools/nosql/redis/view/nodedescriptor/RedisValueDescriptor.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.redis.view.nodedescriptor;\n\nimport com.intellij.ui.ColoredTableCellRenderer;\nimport com.intellij.ui.ColoredTreeCellRenderer;\nimport com.intellij.ui.SimpleTextAttributes;\nimport org.codinjutsu.tools.nosql.commons.style.StyleAttributesProvider;\nimport org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor;\nimport redis.clients.jedis.Tuple;\n\npublic class RedisValueDescriptor implements NodeDescriptor {\n\n    private final int index;\n    protected Object value;\n    private final SimpleTextAttributes valueTextAttributes;\n\n    public static RedisValueDescriptor createDescriptor(int index, Object value) {\n        return new RedisValueDescriptor(index, value, StyleAttributesProvider.getStringAttribute());\n    }\n\n    public static RedisValueDescriptor createUnindexedDescriptor(Object value) {\n        return new RedisUnindexedValueDescriptor(value, StyleAttributesProvider.getStringAttribute());\n    }\n\n    private RedisValueDescriptor(int index, Object value, SimpleTextAttributes valueTextAttributes) {\n\n        this.index = index;\n        this.value = value;\n        this.valueTextAttributes = valueTextAttributes;\n    }\n\n    @Override\n    public void renderValue(ColoredTableCellRenderer cellRenderer, boolean isNodeExpanded) {\n        if (!isNodeExpanded) {\n            cellRenderer.append(getFormattedValue(), valueTextAttributes);\n        }\n    }\n\n    @Override\n    public void renderNode(ColoredTreeCellRenderer cellRenderer) {\n        cellRenderer.append(getFormattedKey(), StyleAttributesProvider.getIndexAttribute());\n    }\n\n    @Override\n    public String getFormattedKey() {\n        return String.format(\"[%s]\", index);\n    }\n\n    @Override\n    public String getFormattedValue() {\n        if (getValue() instanceof Tuple) {\n            Tuple tupleValue = (Tuple) getValue();\n            return String.format(\"(%s, %s)\", tupleValue.getElement(), tupleValue.getScore());\n        }\n        return String.valueOf(getValue());\n    }\n\n    @Override\n    public Object getValue() {\n        return value;\n    }\n\n    @Override\n    public void setValue(Object value) {\n\n    }\n\n    private static class RedisUnindexedValueDescriptor extends RedisValueDescriptor {\n\n        private RedisUnindexedValueDescriptor(Object value, SimpleTextAttributes valueTextAttributes) {\n            super(0, value, valueTextAttributes);\n        }\n\n        @Override\n        public String getFormattedKey() {\n            return \"-\";\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/resources/META-INF/plugin.xml",
    "content": "<!--\n  ~ Copyright (c) 2015 David Boissier\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<idea-plugin version=\"2\">\n    <name>NoSql Plugin</name>\n    <description>NoSql database integration for Intellij</description>\n    <version>0.1.0</version>\n    <vendor email=\"david.boissier [at] gmail [dot] com\" url=\"http://codinjutsu.blogspot.com\">David Boissier</vendor>\n\n    <idea-version since-build=\"140.0\" until-build=\"141.999999\"/>\n    <!--<idea-version since-build=\"143.0\"/>-->\n\n    <depends>com.intellij.modules.lang</depends>\n\n    <extensions defaultExtensionNs=\"com.intellij\">\n        <projectService serviceInterface=\"org.codinjutsu.tools.nosql.NoSqlConfiguration\"\n                        serviceImplementation=\"org.codinjutsu.tools.nosql.NoSqlConfiguration\"/>\n        <projectService serviceInterface=\"org.codinjutsu.tools.nosql.NoSqlWindowManager\"\n                        serviceImplementation=\"org.codinjutsu.tools.nosql.NoSqlWindowManager\"/>\n        <projectService serviceInterface=\"org.codinjutsu.tools.nosql.DatabaseVendorUIManager\"\n                        serviceImplementation=\"org.codinjutsu.tools.nosql.DatabaseVendorUIManager\"/>\n        <projectService serviceInterface=\"org.codinjutsu.tools.nosql.DatabaseVendorClientManager\"\n                        serviceImplementation=\"org.codinjutsu.tools.nosql.DatabaseVendorClientManager\"/>\n\n        <!-- Mongo components -->\n        <projectService serviceInterface=\"org.codinjutsu.tools.nosql.mongo.logic.MongoClient\"\n                        serviceImplementation=\"org.codinjutsu.tools.nosql.mongo.logic.MongoClient\"/>\n        <projectService serviceInterface=\"org.codinjutsu.tools.nosql.mongo.MongoUI\"\n                        serviceImplementation=\"org.codinjutsu.tools.nosql.mongo.MongoUI\"/>\n\n        <!-- Redis components -->\n        <projectService serviceInterface=\"org.codinjutsu.tools.nosql.redis.logic.RedisClient\"\n                        serviceImplementation=\"org.codinjutsu.tools.nosql.redis.logic.RedisClient\"/>\n        <projectService serviceInterface=\"org.codinjutsu.tools.nosql.redis.RedisUI\"\n                        serviceImplementation=\"org.codinjutsu.tools.nosql.redis.RedisUI\"/>\n\n        <!-- Couchbase components -->\n        <projectService serviceInterface=\"org.codinjutsu.tools.nosql.couchbase.logic.CouchbaseClient\"\n                        serviceImplementation=\"org.codinjutsu.tools.nosql.couchbase.logic.CouchbaseClient\"/>\n        <projectService serviceInterface=\"org.codinjutsu.tools.nosql.couchbase.CouchbaseUI\"\n                        serviceImplementation=\"org.codinjutsu.tools.nosql.couchbase.CouchbaseUI\"/>\n\n        <projectConfigurable instance=\"org.codinjutsu.tools.nosql.NoSqlConfigurable\"\n                             id=\"preferences.mongoOptions\"/>\n        <configurationType implementation=\"org.codinjutsu.tools.nosql.mongo.runner.MongoRunConfigurationType\"/>\n        <configurationProducer implementation=\"org.codinjutsu.tools.nosql.mongo.runner.MongoScriptRunConfigurationProducer\"/>\n    </extensions>\n\n    <extensionPoints>\n        <extensionPoint name=\"configurationProducer\"\n                        interface=\"com.intellij.execution.junit.RuntimeConfigurationProducer\"/>\n    </extensionPoints>\n\n    <project-components>\n        <component>\n            <implementation-class>org.codinjutsu.tools.nosql.NoSqlComponent</implementation-class>\n        </component>\n    </project-components>\n\n    <application-components>\n        <component>\n            <implementation-class>org.codinjutsu.tools.nosql.commons.view.editor.NoSqlDatabaseDataEditorProvider</implementation-class>\n        </component>\n        <component>\n            <implementation-class>org.codinjutsu.tools.nosql.commons.view.editor.NoSqlDatabaseFileSystem</implementation-class>\n        </component>\n    </application-components>\n\n    <actions>\n        <action id=\"NoSql.Shell.Execute\" class=\"com.intellij.openapi.actionSystem.EmptyAction\"\n                text=\"Execute DB Command\"\n                description=\"Execute DB command in console\">\n            <keyboard-shortcut first-keystroke=\"control ENTER\" keymap=\"$default\"/>\n        </action>\n    </actions>\n\n    <description><![CDATA[\n    <p>\n        This tool allows accessing to NoSql databases and provides CRUD operations.<br>\n        Documentation is available on the <a href=\"https://github.com/dboissier/nosql4idea/\">GitHub project</a>\n    </p>\n            <br>\n            <br>\n    <p>\n        This tool is free for personal and commercial usage.<br>\n        <a href=\"https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4S464JTADXFMJ\">Donations</a> are welcomed.\n    </p>\n]]> </description>\n\n    <change-notes><![CDATA[\n<a href=\"https://github.com/dboissier/nosql4idea/blob/master/CHANGELOG.txt\">Changelog</a>\n]]> </change-notes>\n</idea-plugin>"
  },
  {
    "path": "src/main/resources/assemblies/plugin-assembly.xml",
    "content": "<!--\n  ~ Copyright (c) 2013 David Boissier\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<assembly xmlns=\"http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2\"\n          xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n          xsi:schemaLocation=\"http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd\">\n    <id>distribution</id>\n    <formats>\n        <format>zip</format>\n    </formats>\n    <dependencySets>\n        <dependencySet>\n            <outputDirectory>/lib</outputDirectory>\n            <excludes>\n                <exclude>com.intellij:forms_rt</exclude>\n                <exclude>com.intellij:openapi</exclude>\n                <exclude>com.intellij:util</exclude>\n                <exclude>commons-lang:commons-lang</exclude>\n                <exclude>log4j:log4j</exclude>\n            </excludes>\n        </dependencySet>\n    </dependencySets>\n    <files>\n        <file>\n            <source>README.md</source>\n            <outputDirectory>/</outputDirectory>\n        </file>\n        <file>\n            <source>CHANGELOG.txt</source>\n            <outputDirectory>/</outputDirectory>\n        </file>\n        <file>\n            <source>LICENSE.txt</source>\n            <outputDirectory>/</outputDirectory>\n        </file>\n    </files>\n</assembly>\n"
  },
  {
    "path": "src/test/java/org/codinjutsu/tools/nosql/commons/utils/DateUtilsTest.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.utils;\n\nimport org.junit.Test;\n\nimport java.util.Calendar;\nimport java.util.Date;\nimport java.util.GregorianCalendar;\nimport java.util.Locale;\n\nimport static org.junit.Assert.*;\n\npublic class DateUtilsTest {\n\n    @Test\n    public void testUtcDateTime() throws Exception {\n        Calendar calendar = GregorianCalendar.getInstance();\n        calendar.set(Calendar.YEAR, 2015);\n        calendar.set(Calendar.MONTH, 1);\n        calendar.set(Calendar.DAY_OF_YEAR, 1);\n        calendar.set(Calendar.HOUR_OF_DAY, 0);\n        calendar.set(Calendar.MINUTE, 0);\n        calendar.set(Calendar.SECOND, 0);\n\n        Date time = calendar.getTime();\n        assertEquals(\"Thu Jan 01 00:00:00 CET 2015\", time.toString());\n        assertEquals(\"31/12/14 23:00:00 UTC\", DateUtils.utcDateTime(Locale.FRANCE).format(time));\n    }\n\n    @Test\n    public void testUtcTime() throws Exception {\n        Calendar calendar = GregorianCalendar.getInstance();\n        calendar.set(Calendar.YEAR, 2015);\n        calendar.set(Calendar.MONTH, 1);\n        calendar.set(Calendar.DAY_OF_YEAR, 1);\n        calendar.set(Calendar.HOUR_OF_DAY, 0);\n        calendar.set(Calendar.MINUTE, 0);\n        calendar.set(Calendar.SECOND, 0);\n\n        Date time = calendar.getTime();\n        assertEquals(\"Thu Jan 01 00:00:00 CET 2015\", time.toString());\n        assertEquals(\"23:00:00\", DateUtils.utcTime(Locale.FRANCE).format(time));\n    }\n}"
  },
  {
    "path": "src/test/java/org/codinjutsu/tools/nosql/commons/utils/StringUtilsTest.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.utils;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.assertEquals;\n\npublic class StringUtilsTest {\n\n    @Test\n    public void abbreviateInCenter() throws Exception {\n        String value = \"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\";\n        assertEquals(\"abcdefghijklmnopq...ghijklmnopqrstuvwxyz\", StringUtils.abbreviateInCenter(value, 40));\n\n    }\n\n    @Test\n    public void parseNumber() throws Exception {\n        assertEquals(1, StringUtils.parseNumber(\"1\"));\n        assertEquals(1.000000000001d, StringUtils.parseNumber(\"1.000000000001\"));\n        assertEquals(1000000000000000L, StringUtils.parseNumber(\"1000000000000000\"));\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/codinjutsu/tools/nosql/commons/view/TableCellReader.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.commons.view;\n\nimport org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor;\nimport org.fest.swing.driver.BasicJTableCellReader;\n\nimport javax.swing.*;\n\npublic class TableCellReader extends BasicJTableCellReader {\n\n    @Override\n    public String valueAt(JTable table, int row, int column) {\n        NodeDescriptor nodeDescriptor = (NodeDescriptor) table.getValueAt(row, column);\n        if (column == 0) {\n            return nodeDescriptor.getFormattedKey();\n        }\n        return nodeDescriptor.getFormattedValue();\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/codinjutsu/tools/nosql/couchbase/CouchbaseClientTest.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.couchbase;\n\nimport com.couchbase.client.java.Bucket;\nimport com.couchbase.client.java.Cluster;\nimport com.couchbase.client.java.CouchbaseCluster;\nimport com.couchbase.client.java.document.JsonDocument;\nimport com.couchbase.client.java.document.json.JsonArray;\nimport com.couchbase.client.java.document.json.JsonObject;\nimport com.couchbase.client.java.env.DefaultCouchbaseEnvironment;\nimport com.couchbase.client.java.query.N1qlQuery;\nimport com.couchbase.client.java.query.N1qlQueryResult;\nimport com.couchbase.client.java.query.N1qlQueryRow;\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.codinjutsu.tools.nosql.commons.model.AuthenticationSettings;\nimport org.codinjutsu.tools.nosql.commons.model.DatabaseServer;\nimport org.codinjutsu.tools.nosql.couchbase.logic.CouchbaseClient;\nimport org.junit.Test;\n\nimport static com.couchbase.client.java.query.Select.select;\nimport static com.couchbase.client.java.query.dsl.Expression.i;\n\npublic class CouchbaseClientTest {\n    @Test\n    public void loadServers() throws Exception {\n        CouchbaseClient couchbaseClient = new CouchbaseClient();\n        ServerConfiguration configuration = new ServerConfiguration();\n        configuration.setServerUrl(\"localhost\");\n        AuthenticationSettings authenticationSettings = new AuthenticationSettings();\n        authenticationSettings.setUsername(\"Administrator\");\n        authenticationSettings.setPassword(\"helloworld2015\");\n        configuration.setAuthenticationSettings(authenticationSettings);\n        couchbaseClient.loadServer(new DatabaseServer(configuration));\n    }\n\n\n    public static void main(String[] args) {\n        Cluster cluster = CouchbaseCluster.create(DefaultCouchbaseEnvironment\n                .builder()\n                .queryEnabled(true)\n                .build());\n\n        Bucket defaultBucket = cluster.openBucket(\"default\");\n        defaultBucket.remove(\"user:walter\");\n\n        JsonArray friends = JsonArray.empty()\n                .add(JsonObject.empty().put(\"name\", \"Mike Ehrmantraut\"))\n                .add(JsonObject.empty().put(\"name\", \"Jesse Pinkman\"));\n\n        JsonObject content = JsonObject.empty()\n                .put(\"firstname\", \"Walter\")\n                .put(\"lastname\", \"White\")\n                .put(\"age\", 52)\n                .put(\"aliases\", JsonArray.from(\"Walt Jackson\", \"Mr. Mayhew\", \"David Lynn\"))\n                .put(\"friends\", friends);\n        JsonDocument walter = JsonDocument.create(\"user:walter\", content);\n        JsonDocument inserted = defaultBucket.insert(walter);\n\n        JsonDocument foundGuy = defaultBucket.get(\"user:walter\");\n        System.out.println(foundGuy.content().toMap());\n\n\n        Bucket beerBucket = cluster.openBucket(\"beer-sample\");\n        N1qlQueryResult result = beerBucket.query(N1qlQuery.simple(select(\"*\").from(i(\"beer-sample\")).limit(10)));\n\n        System.out.println(\"Errors found: \" + result.errors());\n\n        for (N1qlQueryRow row : result.allRows()) {\n            JsonObject jsonObject = row.value();\n            System.out.println(jsonObject.toMap());\n        }\n\n        cluster.disconnect();\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/codinjutsu/tools/nosql/couchbase/view/CouchbasePanelTest.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.couchbase.view;\n\nimport com.couchbase.client.java.document.json.JsonObject;\nimport com.intellij.openapi.command.impl.DummyProject;\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.codinjutsu.tools.nosql.commons.view.TableCellReader;\nimport org.codinjutsu.tools.nosql.couchbase.logic.CouchbaseClient;\nimport org.codinjutsu.tools.nosql.couchbase.model.CouchbaseDatabase;\nimport org.codinjutsu.tools.nosql.couchbase.model.CouchbaseQuery;\nimport org.codinjutsu.tools.nosql.couchbase.model.CouchbaseResult;\nimport org.fest.swing.edt.GuiActionRunner;\nimport org.fest.swing.edt.GuiQuery;\nimport org.fest.swing.fixture.Containers;\nimport org.fest.swing.fixture.FrameFixture;\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.mockito.Mockito;\n\nimport java.util.Arrays;\n\nimport static org.mockito.Matchers.any;\nimport static org.mockito.Mockito.when;\n\npublic class CouchbasePanelTest {\n\n    private FrameFixture frameFixture;\n\n    private CouchbaseClient couchbaseClientMock = Mockito.mock(CouchbaseClient.class);\n    private CouchbasePanel couchbasePanelWrapper;\n\n    @Before\n    public void setUp() throws Exception {\n        when(couchbaseClientMock.loadRecords(any(ServerConfiguration.class), any(CouchbaseDatabase.class), any(CouchbaseQuery.class))).thenReturn(new CouchbaseResult(\"dummy\"));\n\n\n        couchbasePanelWrapper = GuiActionRunner.execute(new GuiQuery<CouchbasePanel>() {\n            protected CouchbasePanel executeInEDT() {\n                return new CouchbasePanel(DummyProject.getInstance(),\n                        couchbaseClientMock,\n                        new ServerConfiguration(),\n                        new CouchbaseDatabase(\"default\")) {\n                    @Override\n                    protected void addCommonsActions() {\n                    }\n                };\n            }\n        });\n\n        frameFixture = Containers.showInFrame(couchbasePanelWrapper);\n    }\n\n    @After\n    public void tearDown() {\n        frameFixture.cleanUp();\n    }\n\n    @Test\n    public void displayJsonObjects() throws Exception {\n        couchbasePanelWrapper.updateResultTableTree(createResults());\n        couchbasePanelWrapper.expandAll();\n\n        frameFixture.table(\"resultTreeTable\").cellReader(new TableCellReader())\n                .requireColumnCount(2)\n                .requireContents(new String[][]{\n                        {\"amount\", \"123456764\"},\n                        {\"mad\", \"true\"},\n                        {\"address\", \"{\\\"City\\\":\\\"Paris\\\",\\\"ZIP Code\\\":75016,\\\"Street\\\":\\\"Av. Champs Elysées\\\"}\"},\n                        {\"Street\", \"\\\"Av. Champs Elysées\\\"\"},\n                        {\"ZIP Code\", \"75016\"},\n                        {\"City\", \"\\\"Paris\\\"\"},\n                        {\"interests\", \"[\\\"programming\\\",\\\"XP\\\",\\\"TDD\\\"]\"},\n                        {\"[0]\", \"\\\"programming\\\"\"},\n                        {\"[1]\", \"\\\"XP\\\"\"},\n                        {\"[2]\", \"\\\"TDD\\\"\"},\n                        {\"movies\", \"[{\\\"title\\\":\\\"Fight Club\\\",\\\"critic\\\":8.2},{\\\"title\\\":\\\"Blade Runner\\\",\\\"critic\\\":9.3},{\\\"title\\\":\\\"Toys Story\\\",\\\"critic\\\":8.7}]\"},\n                        {\"[0]\", \"{\\\"title\\\":\\\"Fight Club\\\",\\\"critic\\\":8.2}\"},\n                        {\"title\", \"\\\"Fight Club\\\"\"},\n                        {\"critic\", \"8.2\"},\n                        {\"[1]\", \"{\\\"title\\\":\\\"Blade Runner\\\",\\\"critic\\\":9.3}\"},\n                        {\"title\", \"\\\"Blade Runner\\\"\"},\n                        {\"critic\", \"9.3\"},\n                        {\"[2]\", \"{\\\"title\\\":\\\"Toys Story\\\",\\\"critic\\\":8.7}\"},\n                        {\"title\", \"\\\"Toys Story\\\"\"},\n                        {\"critic\", \"8.7\"},\n                        {\"age\", \"25\"},\n                        {\"score\", \"12345.12121\"},\n                        {\"firstname\", \"\\\"Jojo\\\"\"},\n                });\n    }\n\n    private CouchbaseResult createResults() {\n        CouchbaseResult result = new CouchbaseResult(\"test\");\n        result.add(JsonObject.create().put(\"firstname\", \"Jojo\")\n                .put(\"age\", 25)\n                .put(\"mad\", true)\n                .put(\"interests\", Arrays.asList(\"programming\", \"XP\", \"TDD\"))\n                .put(\"amount\", 123456764L)\n                .put(\"score\", 12345.12121d)\n                .put(\"address\", JsonObject.create()\n                        .put(\"Street\", \"Av. Champs Elysées\")\n                        .put(\"City\", \"Paris\")\n                        .put(\"ZIP Code\", 75016))\n                .put(\"movies\", Arrays.asList(\n                        JsonObject.create()\n                                .put(\"title\", \"Fight Club\")\n                                .put(\"critic\", 8.2),\n                        JsonObject.create()\n                                .put(\"title\", \"Blade Runner\")\n                                .put(\"critic\", 9.3),\n                        JsonObject.create()\n                                .put(\"title\", \"Toys Story\")\n                                .put(\"critic\", 8.7)\n                )));\n        return result;\n    }\n}"
  },
  {
    "path": "src/test/java/org/codinjutsu/tools/nosql/couchbase/view/ServerConfigurationPanelTest.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.couchbase.view;\n\nimport com.intellij.openapi.command.impl.DummyProject;\nimport org.codinjutsu.tools.nosql.DatabaseVendor;\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.codinjutsu.tools.nosql.commons.logic.DatabaseClient;\nimport org.codinjutsu.tools.nosql.commons.model.AuthenticationSettings;\nimport org.codinjutsu.tools.nosql.commons.view.ServerConfigurationPanel;\nimport org.fest.swing.edt.GuiActionRunner;\nimport org.fest.swing.edt.GuiQuery;\nimport org.fest.swing.fixture.Containers;\nimport org.fest.swing.fixture.FrameFixture;\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.rules.ExpectedException;\nimport org.mockito.Mockito;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertTrue;\n\npublic class ServerConfigurationPanelTest {\n\n    @Rule\n    public ExpectedException thrown = ExpectedException.none();\n\n    private ServerConfigurationPanel configurationPanel;\n    private DatabaseClient databaseClientMock;\n\n    private FrameFixture frameFixture;\n\n    @Before\n    public void setUp() throws Exception {\n        databaseClientMock = Mockito.mock(DatabaseClient.class);\n        configurationPanel = GuiActionRunner.execute(new GuiQuery<ServerConfigurationPanel>() {\n            protected ServerConfigurationPanel executeInEDT() {\n                return new ServerConfigurationPanel(DummyProject.getInstance(),\n                        DatabaseVendor.COUCHBASE,\n                        databaseClientMock,\n                        new CouchbaseAuthenticationPanel()\n                );\n            }\n        });\n\n        frameFixture = Containers.showInFrame(configurationPanel);\n    }\n\n    @After\n    public void tearDown() {\n        frameFixture.cleanUp();\n    }\n\n    @Test\n    public void createCouchbaseConfiguration() throws Exception {\n        frameFixture.textBox(\"labelField\").setText(\"Localhost\");\n\n        frameFixture.label(\"databaseVendorLabel\").requireText(\"Couchbase\");\n        frameFixture.label(\"databaseTipsLabel\").requireText(\"format: host:port. If cluster: host:port1,host:port2,...\");\n\n        frameFixture.textBox(\"serverUrlField\").setText(\"localhost:25\");\n        frameFixture.textBox(\"usernameField\").setText(\"john\");\n        frameFixture.textBox(\"passwordField\").setText(\"johnpassword\");\n\n        frameFixture.textBox(\"userDatabaseField\").setText(\"mybucket\");\n        frameFixture.checkBox(\"autoConnectField\").check();\n\n        ServerConfiguration configuration = new ServerConfiguration();\n\n        configurationPanel.applyConfigurationData(configuration);\n\n        assertEquals(\"Localhost\", configuration.getLabel());\n        assertEquals(DatabaseVendor.COUCHBASE, configuration.getDatabaseVendor());\n        assertEquals(\"localhost:25\", configuration.getServerUrl());\n\n        AuthenticationSettings authenticationSettings = configuration.getAuthenticationSettings();\n        assertEquals(\"john\", authenticationSettings.getUsername());\n        assertEquals(\"johnpassword\", authenticationSettings.getPassword());\n\n        assertEquals(\"mybucket\", configuration.getUserDatabase());\n        assertTrue(configuration.isConnectOnIdeStartup());\n    }\n\n    @Test\n    public void loadCouchbaseConfiguration() throws Exception {\n        ServerConfiguration configuration = new ServerConfiguration();\n        configuration.setLabel(\"Localhost\");\n        configuration.setDatabaseVendor(DatabaseVendor.COUCHBASE);\n        configuration.setServerUrl(\"localhost:25\");\n\n        AuthenticationSettings authenticationSettings = new AuthenticationSettings();\n        authenticationSettings.setUsername(\"john\");\n        authenticationSettings.setPassword(\"johnpassword\");\n        configuration.setAuthenticationSettings(authenticationSettings);\n\n        configurationPanel.loadConfigurationData(configuration);\n\n        frameFixture.textBox(\"labelField\").requireText(\"Localhost\");\n        frameFixture.label(\"databaseVendorLabel\").requireText(\"Couchbase\");\n        frameFixture.label(\"databaseTipsLabel\").requireText(\"format: host:port. If cluster: host:port1,host:port2,...\");\n        frameFixture.textBox(\"serverUrlField\").requireText(\"localhost:25\");\n        frameFixture.textBox(\"usernameField\").requireText(\"john\");\n        frameFixture.textBox(\"passwordField\").requireText(\"johnpassword\");\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/codinjutsu/tools/nosql/mongo/logic/MongoClientTest.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.logic;\n\nimport com.mongodb.BasicDBList;\nimport com.mongodb.BasicDBObject;\nimport com.mongodb.DBObject;\nimport com.mongodb.client.MongoDatabase;\nimport com.mongodb.util.JSON;\nimport org.apache.commons.io.IOUtils;\nimport org.bson.Document;\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.codinjutsu.tools.nosql.mongo.model.MongoCollection;\nimport org.codinjutsu.tools.nosql.mongo.model.MongoResult;\nimport org.codinjutsu.tools.nosql.mongo.model.MongoQueryOptions;\nimport org.junit.Before;\nimport org.junit.Test;\n\nimport java.io.IOException;\nimport java.util.List;\n\nimport static junit.framework.Assert.assertEquals;\nimport static junit.framework.Assert.assertNotNull;\n\npublic class MongoClientTest {\n\n    private MongoClient mongoClient;\n    private ServerConfiguration serverConfiguration;\n\n\n    @Test\n    public void loadCollectionsWithEmptyFilter() throws Exception {\n        MongoQueryOptions mongoQueryOptions = new MongoQueryOptions();\n        mongoQueryOptions.setResultLimit(3);\n        MongoResult mongoResult = mongoClient.loadCollectionValues(serverConfiguration, new MongoCollection(\"dummyCollection\", \"test\"), mongoQueryOptions);\n        assertNotNull(mongoResult);\n        assertEquals(3, mongoResult.getMongoObjects().size());\n    }\n\n    @Test\n    public void loadCollectionsWithFilterAndProjection() throws Exception {\n        MongoQueryOptions mongoQueryOptions = new MongoQueryOptions();\n        mongoQueryOptions.setFilter(\"{\\\"label\\\":\\\"tata\\\"}\");\n        mongoQueryOptions.setProjection(\"{\\\"label\\\":1, \\\"_id\\\": 0}\");\n        mongoQueryOptions.setResultLimit(3);\n        MongoResult mongoResult = mongoClient.loadCollectionValues(serverConfiguration, new MongoCollection(\"dummyCollection\", \"test\"), mongoQueryOptions);\n        assertNotNull(mongoResult);\n        assertEquals(2, mongoResult.getMongoObjects().size());\n        assertEquals(\"[{ \\\"label\\\" : \\\"tata\\\"}, { \\\"label\\\" : \\\"tata\\\"}]\", mongoResult.getMongoObjects().toString());\n    }\n\n    @Test\n    public void loadCollectionsWithFilterAndProjectionAndSortByPrice() throws Exception {\n        MongoQueryOptions mongoQueryOptions = new MongoQueryOptions();\n        mongoQueryOptions.setFilter(\"{\\\"label\\\":\\\"tata\\\"}\");\n        mongoQueryOptions.setProjection(\"{\\\"label\\\": 1, \\\"_id\\\": 0, \\\"price\\\": 1}\");\n        mongoQueryOptions.setSort(\"{\\\"price\\\": 1}\");\n        mongoQueryOptions.setResultLimit(3);\n        MongoResult mongoResult = mongoClient.loadCollectionValues(serverConfiguration, new MongoCollection(\"dummyCollection\", \"test\"), mongoQueryOptions);\n        assertNotNull(mongoResult);\n        assertEquals(2, mongoResult.getMongoObjects().size());\n        assertEquals(\"[{ \\\"label\\\" : \\\"tata\\\" , \\\"price\\\" : 10}, { \\\"label\\\" : \\\"tata\\\" , \\\"price\\\" : 15}]\", mongoResult.getMongoObjects().toString());\n    }\n\n    @Test\n    public void updateMongoDocument() throws Exception {\n        MongoQueryOptions mongoQueryOptions = new MongoQueryOptions();\n        mongoQueryOptions.setFilter(\"{'label': 'tete'}\");\n        MongoCollection mongoCollection = new MongoCollection(\"dummyCollection\", \"test\");\n        MongoResult initialData = mongoClient.loadCollectionValues(serverConfiguration, mongoCollection, mongoQueryOptions);\n        assertEquals(1, initialData.getMongoObjects().size());\n        DBObject initialMongoDocument = initialData.getMongoObjects().get(0);\n\n        initialMongoDocument.put(\"price\", 25);\n        mongoClient.update(serverConfiguration, mongoCollection, initialMongoDocument);\n\n        MongoResult updatedResult = mongoClient.loadCollectionValues(serverConfiguration, mongoCollection, mongoQueryOptions);\n        List<DBObject> updatedMongoDocuments = updatedResult.getMongoObjects();\n        assertEquals(1, updatedMongoDocuments.size());\n        DBObject updatedMongoDocument = updatedMongoDocuments.get(0);\n\n        assertEquals(25, updatedMongoDocument.get(\"price\"));\n    }\n\n\n    @Test\n    public void deleteMongoDocument() throws Exception {\n        MongoQueryOptions mongoQueryOptions = new MongoQueryOptions();\n        mongoQueryOptions.setFilter(\"{'label': 'tete'}\");\n        MongoCollection mongoCollection = new MongoCollection(\"dummyCollection\", \"test\");\n        MongoResult initialData = mongoClient.loadCollectionValues(serverConfiguration, mongoCollection, mongoQueryOptions);\n        assertEquals(1, initialData.getMongoObjects().size());\n        DBObject initialMongoDocument = initialData.getMongoObjects().get(0);\n\n        mongoClient.delete(serverConfiguration, mongoCollection, initialMongoDocument.get(\"_id\"));\n\n        MongoResult deleteResult = mongoClient.loadCollectionValues(serverConfiguration, mongoCollection, mongoQueryOptions);\n        List<DBObject> updatedMongoDocuments = deleteResult.getMongoObjects();\n        assertEquals(0, updatedMongoDocuments.size());\n    }\n\n\n    @Test\n    public void loadCollectionsWithAggregateOperators() throws Exception {\n        MongoQueryOptions mongoQueryOptions = new MongoQueryOptions();\n        mongoQueryOptions.setOperations(\"[{'$match': {'price': 15}}, {'$project': {'label': 1, 'price': 1}}, {'$group': {'_id': '$label', 'total': {'$sum': '$price'}}}]\");\n        MongoResult mongoResult = mongoClient.loadCollectionValues(serverConfiguration, new MongoCollection(\"dummyCollection\", \"test\"), mongoQueryOptions);\n        assertNotNull(mongoResult);\n\n        List<DBObject> mongoObjects = mongoResult.getMongoObjects();\n\n        assertEquals(2, mongoObjects.size());\n        assertEquals(\"{ \\\"_id\\\" : \\\"tutu\\\" , \\\"total\\\" : 15}\", mongoObjects.get(0).toString());\n        assertEquals(\"{ \\\"_id\\\" : \\\"tata\\\" , \\\"total\\\" : 15}\", mongoObjects.get(1).toString());\n    }\n\n    @Before\n    public void setUp() throws Exception {\n        com.mongodb.MongoClient mongo = new com.mongodb.MongoClient(\"localhost:27017\");\n        MongoDatabase db = mongo.getDatabase(\"test\");\n\n        com.mongodb.client.MongoCollection<Document> dummyCollection = db.getCollection(\"dummyCollection\");\n        dummyCollection.deleteMany(new BasicDBObject());\n        fillCollectionWithJsonData(dummyCollection, IOUtils.toString(getClass().getResourceAsStream(\"dummyCollection.json\")));\n\n        mongoClient = new MongoClient();\n        serverConfiguration = mongoClient.defaultConfiguration();\n        serverConfiguration.setServerUrl(\"localhost:27017\");\n    }\n\n    private static void fillCollectionWithJsonData(com.mongodb.client.MongoCollection<Document> collection, String jsonResource) throws IOException {\n        Object jsonParsed = JSON.parse(jsonResource);\n        if (jsonParsed instanceof BasicDBList) {\n            BasicDBList jsonObject = (BasicDBList) jsonParsed;\n            for (Object o : jsonObject) {\n                DBObject dbObject = (DBObject) o;\n                Document document = new Document();\n                for (String key : dbObject.keySet()) {\n                    document.append(key, dbObject.get(key));\n                }\n                collection.insertOne(document);\n            }\n        } else {\n            DBObject dbObject = (DBObject) jsonParsed;\n            Document document = new Document();\n            for (String key : dbObject.keySet()) {\n                document.append(key, dbObject.get(key));\n            }\n            collection.insertOne(document);\n        }\n    }\n}\n\n"
  },
  {
    "path": "src/test/java/org/codinjutsu/tools/nosql/mongo/logic/MongoClientURIBuilderTest.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.logic;\n\nimport com.mongodb.AuthenticationMechanism;\nimport org.codinjutsu.tools.nosql.mongo.logic.MongoClientURIBuilder;\nimport org.junit.Test;\n\nimport static org.junit.Assert.assertEquals;\n\npublic class MongoClientURIBuilderTest {\n\n    @Test\n    public void withoutAuthentication() throws Exception {\n        assertEquals(\n                \"mongodb://localhost:27017,localhost:27018/\",\n                MongoClientURIBuilder.builder()\n                        .setServerAddresses(\"localhost:27017,localhost:27018\")\n                        .build());\n    }\n\n    @Test\n    public void withSimpleAuthentication() throws Exception {\n        assertEquals(\n                \"mongodb://toto:pass@localhost:27018/?authSource=userdb\",\n                MongoClientURIBuilder.builder()\n                        .setServerAddresses(\"localhost:27018\")\n                        .setCredential(\"toto\", \"pass\", \"userdb\")\n                        .build());\n    }\n\n    @Test\n    public void withSpecificAuthentication() throws Exception {\n        assertEquals(\n                \"mongodb://toto:pass@localhost:27018/?authMechanism=MONGODB-CR&authSource=userdb\",\n                MongoClientURIBuilder.builder()\n                        .setServerAddresses(\"localhost:27018\")\n                        .setCredential(\"toto\", \"pass\", \"userdb\")\n                        .setAuthenticationMecanism(AuthenticationMechanism.MONGODB_CR)\n                        .build());\n    }\n\n    @Test\n    public void addSslOption() throws Exception {\n        assertEquals(\n                \"mongodb://localhost:27018/?ssl=true\",\n                MongoClientURIBuilder.builder()\n                        .setServerAddresses(\"localhost:27018\")\n                        .sslEnabled()\n                        .build());\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/codinjutsu/tools/nosql/mongo/view/MongoEditionPanelTest.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view;\n\nimport com.mongodb.DBObject;\nimport com.mongodb.util.JSON;\nimport org.apache.commons.io.IOUtils;\nimport org.bson.types.ObjectId;\nimport org.codinjutsu.tools.nosql.commons.view.nodedescriptor.NodeDescriptor;\nimport org.fest.swing.data.TableCell;\nimport org.fest.swing.driver.BasicJTableCellReader;\nimport org.fest.swing.edt.GuiActionRunner;\nimport org.fest.swing.edt.GuiQuery;\nimport org.fest.swing.fixture.Containers;\nimport org.fest.swing.fixture.FrameFixture;\nimport org.fest.swing.fixture.JTableFixture;\nimport org.junit.After;\nimport org.junit.Assert;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.mockito.ArgumentCaptor;\n\nimport javax.swing.*;\nimport java.io.IOException;\n\nimport static org.mockito.Matchers.any;\nimport static org.mockito.Mockito.*;\n\npublic class MongoEditionPanelTest {\n\n    private MongoEditionPanel mongoEditionPanel;\n\n    private FrameFixture frameFixture;\n    private MongoPanel.MongoDocumentOperations mockMongoOperations = mock(MongoPanel.MongoDocumentOperations.class);\n    private MongoResultPanel.ActionCallback mockActionCallback = mock(MongoResultPanel.ActionCallback.class);\n\n    @After\n    public void tearDown() {\n        frameFixture.cleanUp();\n    }\n\n    @Before\n    public void setUp() throws Exception {\n\n        mongoEditionPanel = GuiActionRunner.execute(new GuiQuery<MongoEditionPanel>() {\n            protected MongoEditionPanel executeInEDT() {\n                MongoEditionPanel panel = new MongoEditionPanel() {\n                    @Override\n                    void buildPopupMenu() {\n                    }\n                };\n                return panel.init(mockMongoOperations, mockActionCallback);\n            }\n        });\n\n        mongoEditionPanel.updateEditionTree(buildDocument(\"simpleDocument.json\"));\n\n        frameFixture = Containers.showInFrame(mongoEditionPanel);\n    }\n\n    @Test\n    public void displayMongoDocumentInTheTreeTable() throws Exception {\n        frameFixture.table(\"editionTreeTable\").cellReader(new JsonTableCellReader())\n                .requireColumnCount(2)\n                .requireContents(new String[][]{\n                        {\"_id\", \"50b8d63414f85401b9268b99\"},\n                        {\"label\", \"toto\"},\n                        {\"visible\", \"false\"},\n                        {\"image\", \"null\"}\n                });\n    }\n\n    @Test\n    public void editKeyWithStringValue() throws Exception {\n        JTableFixture editionTreeTable = frameFixture.table(\"editionTreeTable\").cellReader(new JsonTableCellReader());\n\n//        edit 'label' key\n        editionTreeTable.enterValue(TableCell.row(1).column(1), \"Hello\");\n\n        frameFixture.button(\"saveButton\").click();\n\n        ArgumentCaptor<DBObject> argument = ArgumentCaptor.forClass(DBObject.class);\n        verify(mockMongoOperations).updateMongoDocument(argument.capture());\n\n        Assert.assertEquals(\"{ \\\"_id\\\" : { \\\"$oid\\\" : \\\"50b8d63414f85401b9268b99\\\"} , \\\"label\\\" : \\\"Hello\\\" , \\\"visible\\\" : false , \\\"image\\\" :  null }\",\n                argument.getValue().toString());\n\n        verify(mockActionCallback, times(1)).onOperationSuccess(any(String.class));\n    }\n\n    @Test\n    public void cancelEdition() throws Exception {\n        JTableFixture editionTreeTable = frameFixture.table(\"editionTreeTable\").cellReader(new JsonTableCellReader());\n\n//        edit 'label' key\n        editionTreeTable.enterValue(TableCell.row(1).column(1), \"Hello\");\n\n        frameFixture.button(\"cancelButton\").click();\n        verify(mockMongoOperations, times(0)).updateMongoDocument(any(DBObject.class));\n\n        verify(mockActionCallback, times(1)).onOperationCancelled(any(String.class));\n    }\n\n    @Test\n    public void addKeyWithSomeValue() throws Exception {\n        JTableFixture editionTreeTable = frameFixture.table(\"editionTreeTable\").cellReader(new JsonTableCellReader());\n\n\n        editionTreeTable.selectCell(TableCell.row(1).column(1));\n        mongoEditionPanel.addKey(\"stringKey\", \"pouet\");\n\n        editionTreeTable.selectCell(TableCell.row(1).column(1));\n        mongoEditionPanel.addKey(\"numberKey\", \"1.1\");\n\n        editionTreeTable.requireContents(new String[][]{\n                {\"_id\", \"50b8d63414f85401b9268b99\"},\n                {\"label\", \"toto\"},\n                {\"visible\", \"false\"},\n                {\"image\", \"null\"},\n                {\"stringKey\", \"pouet\"},\n                {\"numberKey\", \"1.1\"},\n        });\n    }\n\n    @Test\n    public void addValueInAList() throws Exception {\n\n        mongoEditionPanel.updateEditionTree(buildDocument(\"simpleDocumentWithSubList.json\"));\n        JTableFixture editionTreeTable = frameFixture.table(\"editionTreeTable\").cellReader(new JsonTableCellReader());\n\n        editionTreeTable.requireContents(new String[][]{\n                {\"_id\", \"50b8d63414f85401b9268b99\"},\n                {\"title\", \"XP by example\"},\n                {\"tags\", \"[ \\\"pair programming\\\" , \\\"tdd\\\" , \\\"agile\\\"]\"},\n                {\"[0]\", \"pair programming\"},\n                {\"[1]\", \"tdd\"},\n                {\"[2]\", \"agile\"},\n                {\"innerList\", \"[ [ 1 , 2 , 3 , 4] , [ false , true] , [ { \\\"tagName\\\" : \\\"pouet\\\"} , { \\\"tagName\\\" : \\\"paf\\\"}]]\"},\n                {\"[0]\", \"[ 1 , 2 , 3 , 4]\"},\n                {\"[1]\", \"[ false , true]\"},\n                {\"[2]\", \"[ { \\\"tagName\\\" : \\\"pouet\\\"} , { \\\"tagName\\\" : \\\"paf\\\"}]\"}});\n\n        editionTreeTable.selectCell(TableCell.row(3).column(1));\n        mongoEditionPanel.addValue(\"refactor\");\n\n        editionTreeTable.requireContents(new String[][]{\n                {\"_id\", \"50b8d63414f85401b9268b99\"},\n                {\"title\", \"XP by example\"},\n                {\"tags\", \"[ \\\"pair programming\\\" , \\\"tdd\\\" , \\\"agile\\\"]\"},\n                {\"[0]\", \"pair programming\"},\n                {\"[1]\", \"tdd\"},\n                {\"[2]\", \"agile\"},\n                {\"[3]\", \"refactor\"},\n                {\"innerList\", \"[ [ 1 , 2 , 3 , 4] , [ false , true] , [ { \\\"tagName\\\" : \\\"pouet\\\"} , { \\\"tagName\\\" : \\\"paf\\\"}]]\"},\n                {\"[0]\", \"[ 1 , 2 , 3 , 4]\"},\n                {\"[1]\", \"[ false , true]\"},\n                {\"[2]\", \"[ { \\\"tagName\\\" : \\\"pouet\\\"} , { \\\"tagName\\\" : \\\"paf\\\"}]\"}});\n\n    }\n\n    private static class JsonTableCellReader extends BasicJTableCellReader {\n\n        @Override\n        public String valueAt(JTable table, int row, int column) {\n            Object value = table.getValueAt(row, column);\n            if (value instanceof NodeDescriptor) {\n                NodeDescriptor nodeDescriptor = (NodeDescriptor) value;\n                return nodeDescriptor.getFormattedKey();\n            } else {\n                return value == null ? \"null\" : value.toString();\n            }\n        }\n\n    }\n\n    private DBObject buildDocument(String jsonFile) throws IOException {\n        DBObject mongoDocument = (DBObject) JSON.parse(IOUtils.toString(getClass().getResourceAsStream(jsonFile)));\n        mongoDocument.put(\"_id\", new ObjectId(String.valueOf(mongoDocument.get(\"_id\"))));\n        return mongoDocument;\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/codinjutsu/tools/nosql/mongo/view/MongoResultPanelTest.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view;\n\nimport com.intellij.openapi.command.impl.DummyProject;\nimport com.intellij.util.ui.tree.TreeUtil;\nimport com.mongodb.DBObject;\nimport com.mongodb.util.JSON;\nimport org.apache.commons.io.IOUtils;\nimport org.codinjutsu.tools.nosql.commons.view.TableCellReader;\nimport org.codinjutsu.tools.nosql.mongo.model.MongoResult;\nimport org.fest.swing.edt.GuiActionRunner;\nimport org.fest.swing.edt.GuiQuery;\nimport org.fest.swing.fixture.Containers;\nimport org.fest.swing.fixture.FrameFixture;\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.mockito.Mock;\nimport org.mockito.MockitoAnnotations;\n\nimport java.io.IOException;\n\nimport static org.junit.Assert.assertEquals;\n\npublic class MongoResultPanelTest {\n\n    private MongoResultPanel mongoResultPanel;\n\n    private FrameFixture frameFixture;\n\n    @Mock\n    private MongoPanel.MongoDocumentOperations mongoDocumentOperations;\n\n    @After\n    public void tearDown() {\n        frameFixture.cleanUp();\n    }\n\n    @Before\n    public void setUp() throws Exception {\n        MockitoAnnotations.initMocks(MongoResultPanelTest.class);\n\n        mongoResultPanel = GuiActionRunner.execute(new GuiQuery<MongoResultPanel>() {\n            protected MongoResultPanel executeInEDT() {\n                return new MongoResultPanel(DummyProject.getInstance(), mongoDocumentOperations) {\n                    @Override\n                    void buildPopupMenu() {\n                    }\n                };\n            }\n        });\n\n        frameFixture = Containers.showInFrame(mongoResultPanel);\n    }\n\n    @Test\n    public void displayTreeWithASimpleArray() throws Exception {\n        mongoResultPanel.updateResultTableTree(createCollectionResults(\"simpleArray.json\", \"mycollec\"));\n\n        frameFixture.table(\"resultTreeTable\").cellReader(new TableCellReader())\n                .requireColumnCount(2)\n                .requireContents(new String[][]{\n                        {\"[0]\", \"\\\"toto\\\"\"},\n                        {\"[1]\", \"true\"},\n                        {\"[2]\", \"10\"},\n                        {\"[3]\", \"null\"},\n                });\n    }\n\n    @Test\n    public void testDisplayTreeWithASimpleDocument() throws Exception {\n        mongoResultPanel.updateResultTableTree(createCollectionResults(\"simpleDocument.json\", \"mycollec\"));\n\n        frameFixture.table(\"resultTreeTable\").cellReader(new TableCellReader())\n                .requireColumnCount(2)\n                .requireContents(new String[][]{\n                        {\"[0]\", \"{ \\\"_id\\\" : \\\"50b8d63414f85401b9268b99\\\" , \\\"label\\\" : \\\"toto\\\" , \\\"visible\\\" : false , \\\"image\\\" :  null }\"},\n                        {\"_id\", \"\\\"50b8d63414f85401b9268b99\\\"\"},\n                        {\"label\", \"\\\"toto\\\"\"},\n                        {\"visible\", \"false\"},\n                        {\"image\", \"null\"}\n                });\n    }\n\n\n    @Test\n    public void testDisplayTreeWithAStructuredDocument() throws Exception {\n        mongoResultPanel.updateResultTableTree(createCollectionResults(\"structuredDocument.json\", \"mycollec\"));\n        TreeUtil.expandAll(mongoResultPanel.resultTableView.getTree());\n        frameFixture.table(\"resultTreeTable\").cellReader(new TableCellReader())\n                .requireColumnCount(2)\n                .requireContents(new String[][]{\n                        {\"[0]\", \"{ \\\"id\\\" : 0 , \\\"label\\\" : \\\"toto\\\" , \\\"visible\\\" : false , \\\"doc\\\" : { \\\"title\\\" : \\\"hello\\\" , \\\"nbPages\\\" : 10 , \\\"keyWord\\\" : [ \\\"toto\\\" , true , 10]}}\"},\n                        {\"id\", \"0\"},\n                        {\"label\", \"\\\"toto\\\"\"},\n                        {\"visible\", \"false\"},\n                        {\"doc\", \"{ \\\"title\\\" : \\\"hello\\\" , \\\"nbPages\\\" : 10 , \\\"keyWord\\\" : [ \\\"toto\\\" , true , 10]}\"},\n                        {\"title\", \"\\\"hello\\\"\"},\n                        {\"nbPages\", \"10\"},\n                        {\"keyWord\", \"[ \\\"toto\\\" , true , 10]\"},\n                        {\"[0]\", \"\\\"toto\\\"\"},\n                        {\"[1]\", \"true\"},\n                        {\"[2]\", \"10\"},\n                });\n    }\n\n\n    @Test\n    public void testDisplayTreeWithAnArrayOfStructuredDocument() throws Exception {\n        mongoResultPanel.updateResultTableTree(createCollectionResults(\"arrayOfDocuments.json\", \"mycollec\"));\n\n        TreeUtil.expandAll(mongoResultPanel.resultTableView.getTree());\n        frameFixture.table(\"resultTreeTable\").cellReader(new TableCellReader())\n                .requireContents(new String[][]{\n\n                        {\"[0]\", \"{ \\\"id\\\" : 0 , \\\"label\\\" : \\\"toto\\\" , \\\"visible\\\" : false , \\\"doc\\\" : { \\\"title\\\" : \\\"hello\\\" , \\\"nbPages\\\" : 10 , \\\"keyWord\\\" : [ \\\"toto\\\" , true , 10]}}\"},\n                        {\"id\", \"0\"},\n                        {\"label\", \"\\\"toto\\\"\"},\n                        {\"visible\", \"false\"},\n                        {\"doc\", \"{ \\\"title\\\" : \\\"hello\\\" , \\\"nbPages\\\" : 10 , \\\"keyWord\\\" : [ \\\"toto\\\" , true , 10]}\"},\n                        {\"title\", \"\\\"hello\\\"\"},\n                        {\"nbPages\", \"10\"},\n                        {\"keyWord\", \"[ \\\"toto\\\" , true , 10]\"},\n                        {\"[0]\", \"\\\"toto\\\"\"},\n                        {\"[1]\", \"true\"},\n                        {\"[2]\", \"10\"},\n                        {\"[1]\", \"{ \\\"id\\\" : 1 , \\\"label\\\" : \\\"tata\\\" , \\\"visible\\\" : true , \\\"doc\\\" : { \\\"title\\\" : \\\"ola\\\" , \\\"nbPages\\\" : 1 , \\\"keyWord\\\" : [ \\\"tutu\\\" , false , 10]}}\"},\n                        {\"id\", \"1\"},\n                        {\"label\", \"\\\"tata\\\"\"},\n                        {\"visible\", \"true\"},\n                        {\"doc\", \"{ \\\"title\\\" : \\\"ola\\\" , \\\"nbPages\\\" : 1 , \\\"keyWord\\\" : [ \\\"tutu\\\" , false , 10]}\"},\n                        {\"title\", \"\\\"ola\\\"\"},\n                        {\"nbPages\", \"1\"},\n                        {\"keyWord\", \"[ \\\"tutu\\\" , false , 10]\"},\n                        {\"[0]\", \"\\\"tutu\\\"\"},\n                        {\"[1]\", \"false\"},\n                        {\"[2]\", \"10\"},\n                });\n    }\n\n    @Test\n    public void testCopyMongoObjectNodeValue() throws Exception {\n        mongoResultPanel.updateResultTableTree(createCollectionResults(\"structuredDocument.json\", \"mycollec\"));\n        TreeUtil.expandAll(mongoResultPanel.resultTableView.getTree());\n\n        mongoResultPanel.resultTableView.setRowSelectionInterval(0, 0);\n        assertEquals(\"{ \\\"id\\\" : 0 , \\\"label\\\" : \\\"toto\\\" , \\\"visible\\\" : false , \\\"doc\\\" : { \\\"title\\\" : \\\"hello\\\" , \\\"nbPages\\\" : 10 , \\\"keyWord\\\" : [ \\\"toto\\\" , true , 10]}}\", mongoResultPanel.getSelectedNodeStringifiedValue());\n\n        mongoResultPanel.resultTableView.setRowSelectionInterval(2, 2);\n        assertEquals(\"\\\"label\\\" : \\\"toto\\\"\", mongoResultPanel.getSelectedNodeStringifiedValue());\n\n        mongoResultPanel.resultTableView.setRowSelectionInterval(4, 4);\n        assertEquals(\"\\\"doc\\\" : { \\\"title\\\" : \\\"hello\\\" , \\\"nbPages\\\" : 10 , \\\"keyWord\\\" : [ \\\"toto\\\" , true , 10]}\", mongoResultPanel.getSelectedNodeStringifiedValue());\n    }\n\n    @Test\n    public void copyMongoResults() throws Exception {\n        mongoResultPanel.updateResultTableTree(createCollectionResults(\"arrayOfDocuments.json\", \"mycollec\"));\n\n        TreeUtil.expandAll(mongoResultPanel.resultTableView.getTree());\n\n        frameFixture.table(\"resultTreeTable\").cellReader(new TableCellReader())\n                .requireContents(new String[][]{\n                        {\"[0]\", \"{ \\\"id\\\" : 0 , \\\"label\\\" : \\\"toto\\\" , \\\"visible\\\" : false , \\\"doc\\\" : { \\\"title\\\" : \\\"hello\\\" , \\\"nbPages\\\" : 10 , \\\"keyWord\\\" : [ \\\"toto\\\" , true , 10]}}\"},\n                        {\"id\", \"0\"},\n                        {\"label\", \"\\\"toto\\\"\"},\n                        {\"visible\", \"false\"},\n                        {\"doc\", \"{ \\\"title\\\" : \\\"hello\\\" , \\\"nbPages\\\" : 10 , \\\"keyWord\\\" : [ \\\"toto\\\" , true , 10]}\"},\n                        {\"title\", \"\\\"hello\\\"\"},\n                        {\"nbPages\", \"10\"},\n                        {\"keyWord\", \"[ \\\"toto\\\" , true , 10]\"},\n                        {\"[0]\", \"\\\"toto\\\"\"},\n                        {\"[1]\", \"true\"},\n                        {\"[2]\", \"10\"},\n                        {\"[1]\", \"{ \\\"id\\\" : 1 , \\\"label\\\" : \\\"tata\\\" , \\\"visible\\\" : true , \\\"doc\\\" : { \\\"title\\\" : \\\"ola\\\" , \\\"nbPages\\\" : 1 , \\\"keyWord\\\" : [ \\\"tutu\\\" , false , 10]}}\"},\n                        {\"id\", \"1\"},\n                        {\"label\", \"\\\"tata\\\"\"},\n                        {\"visible\", \"true\"},\n                        {\"doc\", \"{ \\\"title\\\" : \\\"ola\\\" , \\\"nbPages\\\" : 1 , \\\"keyWord\\\" : [ \\\"tutu\\\" , false , 10]}\"},\n                        {\"title\", \"\\\"ola\\\"\"},\n                        {\"nbPages\", \"1\"},\n                        {\"keyWord\", \"[ \\\"tutu\\\" , false , 10]\"},\n                        {\"[0]\", \"\\\"tutu\\\"\"},\n                        {\"[1]\", \"false\"},\n                        {\"[2]\", \"10\"},\n                });\n\n        assertEquals(\"[ \" +\n                \"{ \\\"id\\\" : 0 , \\\"label\\\" : \\\"toto\\\" , \\\"visible\\\" : false , \\\"doc\\\" : { \\\"title\\\" : \\\"hello\\\" , \\\"nbPages\\\" : 10 , \\\"keyWord\\\" : [ \\\"toto\\\" , true , 10]}} , \" +\n                \"{ \\\"id\\\" : 1 , \\\"label\\\" : \\\"tata\\\" , \\\"visible\\\" : true , \\\"doc\\\" : { \\\"title\\\" : \\\"ola\\\" , \\\"nbPages\\\" : 1 , \\\"keyWord\\\" : [ \\\"tutu\\\" , false , 10]}}\" +\n                \" ]\",\n                mongoResultPanel.getSelectedNodeStringifiedValue());\n    }\n\n    private MongoResult createCollectionResults(String data, String collectionName) throws IOException {\n        DBObject jsonObject = (DBObject) JSON.parse(IOUtils.toString(getClass().getResourceAsStream(data)));\n\n        MongoResult mongoResult = new MongoResult(collectionName);\n        mongoResult.add(jsonObject);\n\n        return mongoResult;\n    }\n\n}\n"
  },
  {
    "path": "src/test/java/org/codinjutsu/tools/nosql/mongo/view/ServerConfigurationPanelTest.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view;\n\nimport com.intellij.openapi.command.impl.DummyProject;\nimport com.mongodb.AuthenticationMechanism;\nimport org.codinjutsu.tools.nosql.DatabaseVendor;\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.codinjutsu.tools.nosql.commons.logic.ConfigurationException;\nimport org.codinjutsu.tools.nosql.commons.logic.DatabaseClient;\nimport org.codinjutsu.tools.nosql.commons.model.AuthenticationSettings;\nimport org.codinjutsu.tools.nosql.commons.view.ServerConfigurationPanel;\nimport org.codinjutsu.tools.nosql.mongo.logic.MongoExtraSettings;\nimport org.fest.swing.edt.GuiActionRunner;\nimport org.fest.swing.edt.GuiQuery;\nimport org.fest.swing.fixture.Containers;\nimport org.fest.swing.fixture.FrameFixture;\nimport org.junit.*;\nimport org.junit.rules.ExpectedException;\nimport org.mockito.Mockito;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertTrue;\n\npublic class ServerConfigurationPanelTest {\n\n    @Rule\n    public ExpectedException thrown = ExpectedException.none();\n\n    private ServerConfigurationPanel configurationPanel;\n    private DatabaseClient databaseClientMock;\n\n    private FrameFixture frameFixture;\n\n    @Before\n    public void setUp() throws Exception {\n        databaseClientMock = Mockito.mock(DatabaseClient.class);\n        configurationPanel = GuiActionRunner.execute(new GuiQuery<ServerConfigurationPanel>() {\n            protected ServerConfigurationPanel executeInEDT() {\n                return new ServerConfigurationPanel(DummyProject.getInstance(),\n                        DatabaseVendor.MONGO,\n                        databaseClientMock,\n                        new MongoAuthenticationPanel()\n                );\n            }\n        });\n\n        frameFixture = Containers.showInFrame(configurationPanel);\n    }\n\n    @After\n    public void tearDown() {\n        frameFixture.cleanUp();\n    }\n\n    @Test\n    public void createMongoConfiguration() throws Exception {\n        frameFixture.textBox(\"labelField\").setText(\"Localhost\");\n\n        frameFixture.label(\"databaseVendorLabel\").requireText(\"MongoDB\");\n        frameFixture.label(\"databaseTipsLabel\").requireText(\"format: host:port. If replicat set: host:port1,host:port2,...\");\n\n        frameFixture.textBox(\"serverUrlField\").setText(\"localhost:25\");\n        frameFixture.textBox(\"usernameField\").setText(\"john\");\n        frameFixture.textBox(\"passwordField\").setText(\"johnpassword\");\n\n        frameFixture.textBox(\"userDatabaseField\").setText(\"mydatabase\");\n\n        frameFixture.textBox(\"authenticationDatabaseField\").setText(\"admin\");\n        frameFixture.radioButton(\"defaultAuthMethod\").requireSelected();\n        frameFixture.radioButton(\"mongoCRAuthField\").click();\n\n        frameFixture.checkBox(\"sslConnectionField\").check();\n        frameFixture.checkBox(\"autoConnectField\").check();\n        ServerConfiguration configuration = new ServerConfiguration();\n\n        configurationPanel.applyConfigurationData(configuration);\n\n        assertEquals(\"Localhost\", configuration.getLabel());\n        assertEquals(DatabaseVendor.MONGO, configuration.getDatabaseVendor());\n        assertEquals(\"localhost:25\", configuration.getServerUrl());\n        AuthenticationSettings authenticationSettings = configuration.getAuthenticationSettings();\n        assertEquals(\"john\", authenticationSettings.getUsername());\n        assertEquals(\"johnpassword\", authenticationSettings.getPassword());\n\n        MongoExtraSettings mongoExtraSettings = new MongoExtraSettings(authenticationSettings.getExtras());\n\n        assertEquals(\"admin\", mongoExtraSettings.getAuthenticationDatabase());\n        assertEquals(AuthenticationMechanism.MONGODB_CR, mongoExtraSettings.getAuthenticationMechanism());\n        assertEquals(\"mydatabase\", configuration.getUserDatabase());\n        assertTrue(configuration.isConnectOnIdeStartup());\n    }\n\n    @Test\n    public void loadMongoConfiguration() throws Exception {\n        ServerConfiguration configuration = new ServerConfiguration();\n        configuration.setLabel(\"Localhost\");\n        configuration.setDatabaseVendor(DatabaseVendor.MONGO);\n        configuration.setServerUrl(\"localhost:25\");\n\n        AuthenticationSettings authenticationSettings = new AuthenticationSettings();\n        authenticationSettings.setUsername(\"john\");\n        authenticationSettings.setPassword(\"johnpassword\");\n        MongoExtraSettings mongoExtraSettings = new MongoExtraSettings();\n        mongoExtraSettings.setAuthenticationDatabase(\"admin\");\n        mongoExtraSettings.setAuthenticationMechanism(AuthenticationMechanism.SCRAM_SHA_1);\n        mongoExtraSettings.setSsl(true);\n\n        authenticationSettings.setExtras(mongoExtraSettings.get());\n\n        configuration.setAuthenticationSettings(authenticationSettings);\n        configuration.setUserDatabase(\"mydatabase\");\n\n        configurationPanel.loadConfigurationData(configuration);\n\n        frameFixture.textBox(\"labelField\").requireText(\"Localhost\");\n        frameFixture.textBox(\"serverUrlField\").requireText(\"localhost:25\");\n        frameFixture.textBox(\"usernameField\").requireText(\"john\");\n        frameFixture.textBox(\"passwordField\").requireText(\"johnpassword\");\n        frameFixture.textBox(\"authenticationDatabaseField\").requireText(\"admin\");\n        frameFixture.checkBox(\"sslConnectionField\").requireSelected();\n        frameFixture.radioButton(\"scramSHA1AuthField\").requireSelected();\n    }\n\n    @Test\n    public void validateFormWithEmptyLabelShouldReturnAValidationInfo() {\n        assertEquals(\"Label should be set\", configurationPanel.validateInputs().message);\n    }\n\n    @Test\n    public void validateFormWithMissingMongoUrlShouldThrowAConfigurationException() {\n        frameFixture.textBox(\"labelField\").setText(\"Localhost\");\n        frameFixture.textBox(\"serverUrlField\").setText(null);\n\n        assertEquals(\"URL(s) should be set\", configurationPanel.validateInputs().message);\n    }\n\n    @Test\n    public void validateFormWithEmptyMongoUrlShouldReturnAValidationInfo() {\n        frameFixture.textBox(\"labelField\").setText(\"Localhost\");\n\n        frameFixture.textBox(\"serverUrlField\").setText(\"\");\n\n        assertEquals(\"URL(s) should be set\", configurationPanel.validateInputs().message);\n    }\n\n    @Test\n    @Ignore\n    public void validateFormWithBadMongoUrlShouldReturnAValidationInfo() {\n        frameFixture.textBox(\"labelField\").setText(\"Localhost\");\n\n        frameFixture.textBox(\"serverUrlField\").setText(\"host\");\n\n        configurationPanel.applyConfigurationData(new ServerConfiguration());\n    }\n\n    @Test\n    @Ignore\n    public void validateFormWithBadMongoPortShouldThrowAConfigurationException() {\n        thrown.expect(ConfigurationException.class);\n        thrown.expectMessage(\"Port in the URL 'host:port' is incorrect. It should be a number\");\n        frameFixture.textBox(\"labelField\").setText(\"Localhost\");\n\n        frameFixture.textBox(\"serverUrlField\").setText(\"host:port\");\n\n        configurationPanel.applyConfigurationData(new ServerConfiguration());\n    }\n\n    @Test\n    public void validateFormWithReplicatSet() throws Exception {\n        frameFixture.textBox(\"labelField\").setText(\"Localhost\");\n        frameFixture.textBox(\"serverUrlField\").setText(\"localhost:25, localhost:26\");\n\n        ServerConfiguration configuration = new ServerConfiguration();\n\n        configurationPanel.applyConfigurationData(configuration);\n\n        assertEquals(\"localhost:25, localhost:26\", configuration.getServerUrl());\n    }\n\n    @Test\n    public void loadFormWithReplicatSet() throws Exception {\n        ServerConfiguration configuration = new ServerConfiguration();\n        configuration.setAuthenticationSettings(new AuthenticationSettings());\n\n        configuration.setServerUrl(\"localhost:25, localhost:26\");\n\n        configurationPanel.loadConfigurationData(configuration);\n\n        frameFixture.textBox(\"serverUrlField\").requireText(\"localhost:25, localhost:26\");\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/codinjutsu/tools/nosql/mongo/view/model/JsonTreeModelTest.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.mongo.view.model;\n\nimport com.mongodb.BasicDBList;\nimport com.mongodb.DBObject;\nimport com.mongodb.util.JSON;\nimport org.apache.commons.io.IOUtils;\nimport org.bson.types.ObjectId;\nimport org.codinjutsu.tools.nosql.commons.view.NoSqlTreeNode;\nimport org.junit.Test;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertNull;\n\npublic class JsonTreeModelTest {\n\n    @Test\n    public void buildDBObjectFromSimpleTree() throws Exception {\n        DBObject jsonObject = (DBObject) JSON.parse(IOUtils.toString(getClass().getResourceAsStream(\"simpleDocument.json\")));\n\n//        Hack to convert _id fron string to ObjectId\n        jsonObject.put(\"_id\", new ObjectId(String.valueOf(jsonObject.get(\"_id\"))));\n\n        NoSqlTreeNode treeNode = (NoSqlTreeNode) JsonTreeModel.buildJsonTree(jsonObject);\n        NoSqlTreeNode labelNode = (NoSqlTreeNode) treeNode.getChildAt(1);\n        labelNode.getDescriptor().setValue(\"tata\");\n\n\n        DBObject dbObject = JsonTreeModel.buildDBObject(treeNode);\n\n        assertEquals(\"{ \\\"_id\\\" : { \\\"$oid\\\" : \\\"50b8d63414f85401b9268b99\\\"} , \\\"label\\\" : \\\"tata\\\" , \\\"visible\\\" : false , \\\"image\\\" :  null }\",\n                dbObject.toString());\n    }\n\n    @Test\n    public void buildDBObjectFromTreeWithSubNodes() throws Exception {\n        DBObject jsonObject = (DBObject) JSON.parse(IOUtils.toString(getClass().getResourceAsStream(\"simpleDocumentWithInnerNodes.json\")));\n\n//        Hack to convert _id fron string to ObjectId\n        jsonObject.put(\"_id\", new ObjectId(String.valueOf(jsonObject.get(\"_id\"))));\n\n        NoSqlTreeNode treeNode = (NoSqlTreeNode) JsonTreeModel.buildJsonTree(jsonObject);\n\n//      Simulate updating from the treeNode\n        NoSqlTreeNode innerDocNode = (NoSqlTreeNode) treeNode.getChildAt(4);\n        NoSqlTreeNode soldOutNode = (NoSqlTreeNode) innerDocNode.getChildAt(2);\n        soldOutNode.getDescriptor().setValue(\"false\");\n\n        DBObject dbObject = JsonTreeModel.buildDBObject(treeNode);\n\n        assertEquals(\"{ \\\"_id\\\" : { \\\"$oid\\\" : \\\"50b8d63414f85401b9268b99\\\"} , \\\"label\\\" : \\\"toto\\\" , \\\"visible\\\" : false , \\\"image\\\" :  null  , \\\"innerdoc\\\" : { \\\"title\\\" : \\\"What?\\\" , \\\"numberOfPages\\\" : 52 , \\\"soldOut\\\" : false}}\",\n                dbObject.toString());\n    }\n\n    @Test\n    public void buildDBObjectFromTreeWithSubList() throws Exception {\n        DBObject jsonObject = (DBObject) JSON.parse(IOUtils.toString(getClass().getResourceAsStream(\"simpleDocumentWithSubList.json\")));\n\n//        Hack to convert _id fron string to ObjectId\n        jsonObject.put(\"_id\", new ObjectId(String.valueOf(jsonObject.get(\"_id\"))));\n\n        NoSqlTreeNode treeNode = (NoSqlTreeNode) JsonTreeModel.buildJsonTree(jsonObject);\n        NoSqlTreeNode tagsNode = (NoSqlTreeNode) treeNode.getChildAt(2);\n        NoSqlTreeNode agileTagNode = (NoSqlTreeNode) tagsNode.getChildAt(2);\n        agileTagNode.getDescriptor().setValue(\"a gilles\");\n\n        DBObject dbObject = JsonTreeModel.buildDBObject(treeNode);\n\n        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\\\"}]]}\",\n                dbObject.toString());\n    }\n\n    @Test\n    public void getObjectIdFromANode() throws Exception {\n        DBObject jsonObject = (DBObject) JSON.parse(IOUtils.toString(getClass().getResourceAsStream(\"simpleDocumentWithInnerNodes.json\")));\n        jsonObject.put(\"_id\", new ObjectId(String.valueOf(jsonObject.get(\"_id\"))));\n\n        NoSqlTreeNode treeNode = (NoSqlTreeNode) JsonTreeModel.buildJsonTree(jsonObject);\n        NoSqlTreeNode objectIdNode = (NoSqlTreeNode) treeNode.getChildAt(0);\n        assertEquals(\"_id\", objectIdNode.getDescriptor().getFormattedKey());\n\n        assertNull(JsonTreeModel.findObjectIdNode(treeNode));\n        assertEquals(objectIdNode, JsonTreeModel.findObjectIdNode((NoSqlTreeNode) treeNode.getChildAt(0)));\n\n    }\n\n    @Test\n    public void findDocumentFromANode() throws Exception {\n        BasicDBList dbList = (BasicDBList) JSON.parse(IOUtils.toString(getClass().getResourceAsStream(\"arrayOfDocuments.json\")));\n\n        DBObject first = (DBObject) dbList.get(0);\n        first.put(\"_id\", new ObjectId(String.valueOf(first.get(\"_id\"))));\n\n        DBObject second = (DBObject) dbList.get(1);\n        second.put(\"_id\", new ObjectId(String.valueOf(second.get(\"_id\"))));\n\n        NoSqlTreeNode treeNode = (NoSqlTreeNode) JsonTreeModel.buildJsonTree(dbList);\n\n        assertEquals(first, JsonTreeModel.findDocument((NoSqlTreeNode) treeNode.getChildAt(0)));\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/codinjutsu/tools/nosql/redis/logic/RedisClientTest.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.redis.logic;\n\nimport org.codinjutsu.tools.nosql.DatabaseVendor;\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.codinjutsu.tools.nosql.redis.model.*;\nimport org.junit.Before;\nimport org.junit.Test;\nimport redis.clients.jedis.Jedis;\n\nimport java.util.List;\n\nimport static org.junit.Assert.assertEquals;\n\npublic class RedisClientTest {\n\n    private Jedis jedis;\n\n    @Test\n    public void loadWithEmptyFilter() throws Exception {\n        jedis.sadd(\"books\", \"eXtreme Programming\", \"Haskell for Dummies\");\n        jedis.set(\"status\", \"online\");\n        jedis.lpush(\"todos\", \"coffee\", \"code\", \"drink\", \"sleep\");\n        jedis.zadd(\"reviews\", 12.0d, \"writing\");\n        jedis.zadd(\"reviews\", 14.0d, \"reading\");\n        jedis.zadd(\"reviews\", 15.0d, \"maths\");\n\n        RedisClient redisClient = new RedisClient();\n        ServerConfiguration serverConfiguration = new ServerConfiguration();\n        serverConfiguration.setDatabaseVendor(DatabaseVendor.REDIS);\n        serverConfiguration.setServerUrl(\"localhost:6379\");\n\n        RedisQuery query = new RedisQuery(\"*\");\n        RedisResult result = redisClient.loadRecords(serverConfiguration, new RedisDatabase(\"1\"), query);\n\n        List<RedisRecord> redisRecords = result.getResults();\n        assertEquals(4, redisRecords.size());\n        RedisRecord redisRecord = redisRecords.get(0);\n        assertEquals(RedisKeyType.SET, redisRecord.getKeyType());\n        assertEquals(\"books\", redisRecord.getKey());\n        redisRecord = redisRecords.get(1);\n        assertEquals(RedisKeyType.ZSET, redisRecord.getKeyType());\n        assertEquals(\"reviews\", redisRecord.getKey());\n        redisRecord = redisRecords.get(2);\n        assertEquals(RedisKeyType.LIST, redisRecord.getKeyType());\n        assertEquals(\"todos\", redisRecord.getKey());\n        redisRecord = redisRecords.get(3);\n        assertEquals(RedisKeyType.STRING, redisRecord.getKeyType());\n        assertEquals(\"status\", redisRecord.getKey());\n    }\n\n    @Test\n    public void loadWithFilter() throws Exception {\n        jedis.sadd(\"books\", \"eXtreme Programming\", \"Haskell for Dummies\");\n        jedis.set(\"status\", \"online\");\n        jedis.lpush(\"todos\", \"coffee\", \"code\", \"drink\", \"sleep\");\n        jedis.zadd(\"reviews\", 12.0d, \"writing\");\n        jedis.zadd(\"reviews\", 14.0d, \"reading\");\n        jedis.zadd(\"reviews\", 15.0d, \"maths\");\n\n        RedisClient redisClient = new RedisClient();\n        ServerConfiguration serverConfiguration = new ServerConfiguration();\n        serverConfiguration.setDatabaseVendor(DatabaseVendor.REDIS);\n        serverConfiguration.setServerUrl(\"localhost:6379\");\n\n        RedisQuery query = new RedisQuery(\"reviews\");\n        RedisResult result = redisClient.loadRecords(serverConfiguration, new RedisDatabase(\"1\"), query);\n\n        List<RedisRecord> redisRecords = result.getResults();\n        assertEquals(1, redisRecords.size());\n        RedisRecord redisRecord = redisRecords.get(0);\n        assertEquals(RedisKeyType.ZSET, redisRecord.getKeyType());\n        assertEquals(\"reviews\", redisRecord.getKey());\n    }\n\n    @Before\n    public void setUp() throws Exception {\n        jedis = new Jedis(\"localhost\", 6379);\n        jedis.select(1);\n        jedis.flushDB();\n\n    }\n\n    public void tearDown() throws Exception {\n        jedis.close();\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/codinjutsu/tools/nosql/redis/view/RedisPanelTest.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.redis.view;\n\nimport com.intellij.openapi.command.impl.DummyProject;\nimport com.intellij.openapi.project.Project;\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.codinjutsu.tools.nosql.commons.view.TableCellReader;\nimport org.codinjutsu.tools.nosql.redis.model.RedisQuery;\nimport org.codinjutsu.tools.nosql.redis.logic.RedisClient;\nimport org.codinjutsu.tools.nosql.redis.model.RedisDatabase;\nimport org.codinjutsu.tools.nosql.redis.model.RedisResult;\nimport org.fest.swing.edt.GuiActionRunner;\nimport org.fest.swing.edt.GuiQuery;\nimport org.fest.swing.fixture.Containers;\nimport org.fest.swing.fixture.FrameFixture;\nimport org.fest.swing.fixture.JTableFixture;\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.mockito.Mockito;\nimport redis.clients.jedis.Tuple;\n\nimport java.util.*;\n\nimport static org.mockito.Matchers.any;\nimport static org.mockito.Mockito.when;\n\npublic class RedisPanelTest {\n\n    private RedisPanel redisPanelWrapper;\n\n    private FrameFixture frameFixture;\n\n    private Project dummyProject = DummyProject.getInstance();\n\n    private RedisClient redisClientMock = Mockito.mock(RedisClient.class);\n\n    @After\n    public void tearDown() {\n        frameFixture.cleanUp();\n    }\n\n    @Before\n    public void setUp() throws Exception {\n        when(redisClientMock.loadRecords(any(ServerConfiguration.class), any(RedisDatabase.class), any(RedisQuery.class))).thenReturn(new RedisResult());\n\n        redisPanelWrapper = GuiActionRunner.execute(new GuiQuery<RedisPanel>() {\n            protected RedisPanel executeInEDT() {\n                return new RedisPanel(dummyProject, redisClientMock, new ServerConfiguration(), new RedisDatabase(\"0\")) {\n                    @Override\n                    protected void addCommonsActions() { }\n                };\n            }\n        });\n\n        frameFixture = Containers.showInFrame(redisPanelWrapper);\n    }\n\n    @Test\n    public void displayTreeWithEachSupportedKeyType() throws Exception {\n\n        redisPanelWrapper.updateResultTableTree(createRedisResults(), false, \"\");\n\n        frameFixture.table(\"resultTreeTable\").cellReader(new TableCellReader())\n                .requireColumnCount(2)\n                .requireContents(new String[][]{\n                        {\"foo:bar\", \"john\"},\n                        {\"stuff:bar\", \"[drink, some, beer]\"},\n                        {\"[0]\", \"drink\"},\n                        {\"[1]\", \"some\"},\n                        {\"[2]\", \"beer\"},\n                        {\"stuff:countries\", \"{France, Canada, Japan}\"},\n                        {\"-\", \"France\"},\n                        {\"-\", \"Canada\"},\n                        {\"-\", \"Japan\"},\n                        {\"stuff:aliases\", \"{david=dada, mickael=mike, bruno=nono}\"},\n                        {\"david\", \"dada\"},\n                        {\"mickael\", \"mike\"},\n                        {\"bruno\", \"nono\"},\n                        {\"stuff:games:critics\", \"{(unreal, 8.0), (quake, 9.0), (half-life, 10.0)}\"},\n                        {\"-\", \"(unreal, 8.0)\"},\n                        {\"-\", \"(quake, 9.0)\"},\n                        {\"-\", \"(half-life, 10.0)\"},\n                });\n    }\n\n    @Test\n    public void testDisplayTreeWithFragmentedKey() throws Exception {\n        redisPanelWrapper.updateResultTableTree(createRedisResults(), true,  \":\");\n        redisPanelWrapper.expandAll();\n\n\n        JTableFixture resultTreeTable = frameFixture.table(\"resultTreeTable\");\n        resultTreeTable.cellReader(new TableCellReader())\n                .requireColumnCount(2)\n                .requireContents(new String[][]{\n                        {\"foo\", \"\"},\n                        {\"bar\", \"john\"},\n                        {\"stuff\", \"\"},\n                        {\"bar\", \"[drink, some, beer]\"},\n                        {\"[0]\", \"drink\"},\n                        {\"[1]\", \"some\"},\n                        {\"[2]\", \"beer\"},\n                        {\"countries\", \"{France, Canada, Japan}\"},\n                        {\"-\", \"France\"},\n                        {\"-\", \"Canada\"},\n                        {\"-\", \"Japan\"},\n                        {\"aliases\", \"{david=dada, mickael=mike, bruno=nono}\"},\n                        {\"david\", \"dada\"},\n                        {\"mickael\", \"mike\"},\n                        {\"bruno\", \"nono\"},\n                        {\"games\", \"\"},\n                        {\"critics\", \"{(unreal, 8.0), (quake, 9.0), (half-life, 10.0)}\"},\n                        {\"-\", \"(unreal, 8.0)\"},\n                        {\"-\", \"(quake, 9.0)\"},\n                        {\"-\", \"(half-life, 10.0)\"},\n                });\n\n\n    }\n\n    private RedisResult createRedisResults() {\n        RedisResult redisResult = new RedisResult();\n        redisResult.addString(\"foo:bar\", \"john\");\n        redisResult.addList(\"stuff:bar\", Arrays.asList(\"drink\", \"some\", \"beer\"));\n        Set<String> countries = new HashSet<>();\n        countries.add(\"France\");\n        countries.add(\"Japan\");\n        countries.add(\"Canada\");\n        redisResult.addSet(\"stuff:countries\", countries);\n\n        Map<String, String> aliasByPeopleName = new HashMap<>();\n        aliasByPeopleName.put(\"david\", \"dada\");\n        aliasByPeopleName.put(\"mickael\", \"mike\");\n        aliasByPeopleName.put(\"bruno\", \"nono\");\n        redisResult.addHash(\"stuff:aliases\", aliasByPeopleName);\n\n        SortedSet<Tuple> scoreByGameTitle = new TreeSet<>();\n        scoreByGameTitle.add(new Tuple(\"quake\", 9d));\n        scoreByGameTitle.add(new Tuple(\"half-life\", 10d));\n        scoreByGameTitle.add(new Tuple(\"unreal\", 8d));\n\n        redisResult.addSortedSet(\"stuff:games:critics\", scoreByGameTitle);\n        return redisResult;\n    }\n\n}"
  },
  {
    "path": "src/test/java/org/codinjutsu/tools/nosql/redis/view/ServerConfigurationPanelTest.java",
    "content": "/*\n * Copyright (c) 2015 David Boissier\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.codinjutsu.tools.nosql.redis.view;\n\nimport com.intellij.openapi.command.impl.DummyProject;\nimport org.codinjutsu.tools.nosql.DatabaseVendor;\nimport org.codinjutsu.tools.nosql.ServerConfiguration;\nimport org.codinjutsu.tools.nosql.commons.logic.DatabaseClient;\nimport org.codinjutsu.tools.nosql.commons.model.AuthenticationSettings;\nimport org.codinjutsu.tools.nosql.commons.view.ServerConfigurationPanel;\nimport org.codinjutsu.tools.nosql.redis.view.RedisAuthenticationPanel;\nimport org.fest.swing.edt.GuiActionRunner;\nimport org.fest.swing.edt.GuiQuery;\nimport org.fest.swing.fixture.Containers;\nimport org.fest.swing.fixture.FrameFixture;\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.rules.ExpectedException;\nimport org.mockito.Mockito;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertTrue;\n\npublic class ServerConfigurationPanelTest {\n\n    @Rule\n    public ExpectedException thrown = ExpectedException.none();\n\n    private ServerConfigurationPanel configurationPanel;\n    private DatabaseClient databaseClientMock;\n\n    private FrameFixture frameFixture;\n\n    @Before\n    public void setUp() throws Exception {\n        databaseClientMock = Mockito.mock(DatabaseClient.class);\n        configurationPanel = GuiActionRunner.execute(new GuiQuery<ServerConfigurationPanel>() {\n            protected ServerConfigurationPanel executeInEDT() {\n                return new ServerConfigurationPanel(DummyProject.getInstance(),\n                        DatabaseVendor.REDIS,\n                        databaseClientMock,\n                        new RedisAuthenticationPanel()\n                );\n            }\n        });\n\n        frameFixture = Containers.showInFrame(configurationPanel);\n    }\n\n    @After\n    public void tearDown() {\n        frameFixture.cleanUp();\n    }\n\n    @Test\n    public void createRedisConfiguration() throws Exception {\n        frameFixture.textBox(\"labelField\").setText(\"Localhost\");\n\n        frameFixture.label(\"databaseVendorLabel\").requireText(\"RedisDB\");\n        frameFixture.label(\"databaseTipsLabel\").requireText(\"format: host:port. If cluster: host:port1,host:port2,...\");\n\n        frameFixture.textBox(\"serverUrlField\").setText(\"localhost:25\");\n        frameFixture.textBox(\"passwordField\").setText(\"johnpassword\");\n\n        frameFixture.textBox(\"userDatabaseField\").setText(\"0\");\n        frameFixture.checkBox(\"autoConnectField\").check();\n\n        ServerConfiguration configuration = new ServerConfiguration();\n\n        configurationPanel.applyConfigurationData(configuration);\n\n        assertEquals(\"Localhost\", configuration.getLabel());\n        assertEquals(DatabaseVendor.REDIS, configuration.getDatabaseVendor());\n        assertEquals(\"localhost:25\", configuration.getServerUrl());\n\n        AuthenticationSettings authenticationSettings = configuration.getAuthenticationSettings();\n        assertEquals(\"johnpassword\", authenticationSettings.getPassword());\n\n        assertEquals(\"0\", configuration.getUserDatabase());\n        assertTrue(configuration.isConnectOnIdeStartup());\n    }\n\n    @Test\n    public void loadRedisConfiguration() throws Exception {\n        ServerConfiguration configuration = new ServerConfiguration();\n        configuration.setLabel(\"Localhost\");\n        configuration.setDatabaseVendor(DatabaseVendor.REDIS);\n        configuration.setServerUrl(\"localhost:6379\");\n\n        AuthenticationSettings authenticationSettings = new AuthenticationSettings();\n        authenticationSettings.setPassword(\"johnpassword\");\n        configuration.setAuthenticationSettings(authenticationSettings);\n\n        configurationPanel.loadConfigurationData(configuration);\n\n        frameFixture.textBox(\"labelField\").requireText(\"Localhost\");\n        frameFixture.label(\"databaseVendorLabel\").requireText(\"RedisDB\");\n        frameFixture.label(\"databaseTipsLabel\").requireText(\"format: host:port. If cluster: host:port1,host:port2,...\");\n        frameFixture.textBox(\"serverUrlField\").requireText(\"localhost:6379\");\n        frameFixture.textBox(\"passwordField\").requireText(\"johnpassword\");\n    }\n}\n"
  },
  {
    "path": "src/test/resources/org/codinjutsu/tools/nosql/mongo/logic/dummyCollection.json",
    "content": "[\n    {\n        \"label\":\"tata\",\n        \"comment\":\"prout\",\n        \"price\":15\n    },\n    {\n        \"label\":\"tata\",\n        \"comment\":\"prout\",\n        \"price\":10\n    },\n    {\n        \"label\":\"tutu\",\n        \"comment\":\"prout\",\n        \"price\":15\n    },\n    {\n        \"label\":\"titi\",\n        \"comment\":\"prout\",\n        \"price\":20\n    },\n    {\n        \"label\":\"tete\",\n        \"comment\":\"prout\",\n        \"price\":20\n    }\n]"
  },
  {
    "path": "src/test/resources/org/codinjutsu/tools/nosql/mongo/view/arrayOfDocuments.json",
    "content": "[\n    {\n        \"id\":0,\n        \"label\":\"toto\",\n        \"visible\":false,\n        \"doc\":{\n            \"title\":\"hello\",\n            \"nbPages\":10,\n            \"keyWord\":[\n                \"toto\", true, 10\n            ]\n        }\n    },\n    {\n        \"id\":1,\n        \"label\":\"tata\",\n        \"visible\":true,\n        \"doc\":{\n            \"title\":\"ola\",\n            \"nbPages\":1,\n            \"keyWord\":[\n                \"tutu\", false, 10\n            ]\n        }\n    }\n]"
  },
  {
    "path": "src/test/resources/org/codinjutsu/tools/nosql/mongo/view/model/arrayOfDocuments.json",
    "content": "[\n    {\n        \"_id\": \"50b8d63414f85401b9268b99\",\n        \"label\": \"toto\",\n        \"visible\": false,\n        \"doc\": {\n            \"title\": \"hello\",\n            \"nbPages\": 10,\n            \"keyWord\": [\n                \"toto\", true, 10\n            ]\n        }\n    },\n    {\n        \"_id\": \"50b8d63414f85401b9268baa\",\n        \"label\": \"tata\",\n        \"visible\": true,\n        \"doc\": {\n            \"title\": \"ola\",\n            \"nbPages\": 1,\n            \"keyWord\": [\n                \"tutu\", false, 10\n            ]\n        }\n    }\n]"
  },
  {
    "path": "src/test/resources/org/codinjutsu/tools/nosql/mongo/view/model/simpleDocument.json",
    "content": "{\n    \"_id\": \"50b8d63414f85401b9268b99\",\n    \"label\":\"toto\",\n    \"visible\":false,\n    \"image\":null\n}"
  },
  {
    "path": "src/test/resources/org/codinjutsu/tools/nosql/mongo/view/model/simpleDocumentWithInnerNodes.json",
    "content": "{\n    \"_id\": \"50b8d63414f85401b9268b99\",\n    \"label\": \"toto\",\n    \"visible\": false,\n    \"image\": null,\n    \"innerdoc\": {\n        \"title\" : \"What?\",\n        \"numberOfPages\": 52,\n        \"soldOut\": true\n    }\n}"
  },
  {
    "path": "src/test/resources/org/codinjutsu/tools/nosql/mongo/view/model/simpleDocumentWithSubList.json",
    "content": "{\n    \"_id\": {\n        \"$oid\": \"50b8d63414f85401b9268b99\"\n    },\n    \"title\": \"XP by example\",\n    \"tags\": [ \"pair programming\", \"tdd\", \"agile\"],\n    \"innerList\" : [\n        [1, 2, 3, 4],\n        [false , true],\n        [\n            { \"tagName\": \"pouet\"},\n            { \"tagName\": \"paf\"}\n        ]\n    ]\n}"
  },
  {
    "path": "src/test/resources/org/codinjutsu/tools/nosql/mongo/view/simpleArray.json",
    "content": "[\n    \"toto\", true, 10, null\n]\n"
  },
  {
    "path": "src/test/resources/org/codinjutsu/tools/nosql/mongo/view/simpleDocument.json",
    "content": "{\n    \"_id\": \"50b8d63414f85401b9268b99\",\n    \"label\":\"toto\",\n    \"visible\":false,\n    \"image\":null\n}"
  },
  {
    "path": "src/test/resources/org/codinjutsu/tools/nosql/mongo/view/simpleDocumentForEdition.json",
    "content": "{\n    \"_id\": \"50b8d63414f85401b9268b99\",\n    \"label\":\"toto\",\n    \"visible\":false,\n    \"image\":null\n}"
  },
  {
    "path": "src/test/resources/org/codinjutsu/tools/nosql/mongo/view/simpleDocumentWithSubList.json",
    "content": "{\n    \"_id\": {\n        \"$oid\": \"50b8d63414f85401b9268b99\"\n    },\n    \"title\": \"XP by example\",\n    \"tags\": [ \"pair programming\", \"tdd\", \"agile\"],\n    \"innerList\" : [\n        [1, 2, 3, 4],\n        [false , true],\n        [\n            { \"tagName\": \"pouet\"},\n            { \"tagName\": \"paf\"}\n        ]\n    ]\n}"
  },
  {
    "path": "src/test/resources/org/codinjutsu/tools/nosql/mongo/view/structuredDocument.json",
    "content": "{\n    \"id\":0,\n    \"label\":\"toto\",\n    \"visible\":false,\n    \"doc\":{\n        \"title\":\"hello\",\n        \"nbPages\":10,\n        \"keyWord\":[\n            \"toto\", true, 10\n        ]\n    }\n}"
  }
]