Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

initial import

  • Loading branch information...
commit 24867ffc9bde8e2764525c92122475c5dca2fe2c 0 parents
Juri Kuehn authored
Showing with 5,078 additions and 0 deletions.
  1. +14 −0 .classpath
  2. +2 −0  .gitignore
  3. +19 −0 .project
  4. +3 −0  .settings/org.codehaus.groovy.eclipse.preferences.prefs
  5. +85 −0 GormMongodbGrailsPlugin.groovy
  6. +203 −0 LICENSE
  7. +23 −0 MongoPlugin-grailsPlugins.iml
  8. +52 −0 MongoPlugin.iml
  9. +232 −0 MongoPlugin.ipr
  10. +560 −0 MongoPlugin.iws
  11. +6 −0 application.properties
  12. +32 −0 grails-app/conf/BuildConfig.groovy
  13. +5 −0 grails-app/conf/Config.groovy
  14. +32 −0 grails-app/conf/DataSource.groovy
  15. +11 −0 grails-app/conf/UrlMappings.groovy
  16. +26 −0 grails-app/mongo/org/acme/Contact.groovy
  17. +19 −0 grails-app/mongo/org/acme/NotMongoDB.groovy
  18. +51 −0 grails-app/mongo/org/acme/Project.groovy
  19. +69 −0 grails-app/mongo/org/acme/Task.groovy
  20. +54 −0 grails-app/views/error.gsp
  21. BIN  grails-gorm-mongodb-0.1.zip
  22. BIN  lib/hibernate-core-3.3.1.GA.jar
  23. BIN  lib/mongo-1.4.jar
  24. BIN  lib/morphia-0.93-mod.jar
  25. +19 −0 plugin.xml
  26. +39 −0 scripts/CreateMongodbClass.groovy
  27. +73 −0 scripts/GenerateAllMongodb.groovy
  28. +10 −0 scripts/_Install.groovy
  29. +5 −0 scripts/_Uninstall.groovy
  30. +10 −0 scripts/_Upgrade.groovy
  31. +479 −0 src/groovy/grails/plugins/mongodb/MongoPluginSupport.groovy
  32. +228 −0 src/java/grails/plugins/mongodb/MongoDomainClass.java
  33. +30 −0 src/java/grails/plugins/mongodb/MongoDomainClassArtefactHandler.java
  34. +268 −0 src/java/grails/plugins/mongodb/MongoDomainClassProperty.java
  35. +9 −0 src/templates/artifacts/MongoDBClass.groovy
  36. +12 −0 test/integration/grails/plugins/mongodb/test/AdvancedQueryingTests.groovy
  37. +120 −0 test/integration/grails/plugins/mongodb/test/BasicPersistenceTests.groovy
  38. +78 −0 test/integration/grails/plugins/mongodb/test/StaticMethodsTests.groovy
  39. +49 −0 test/integration/grails/plugins/mongodb/test/UnicodeTests.groovy
  40. +42 −0 web-app/WEB-INF/applicationContext.xml
  41. +14 −0 web-app/WEB-INF/sitemesh.xml
  42. +563 −0 web-app/WEB-INF/tld/c.tld
  43. +671 −0 web-app/WEB-INF/tld/fmt.tld
  44. +550 −0 web-app/WEB-INF/tld/grails.tld
  45. +311 −0 web-app/WEB-INF/tld/spring.tld
14 .classpath
@@ -0,0 +1,14 @@
+<classpath>
+ <classpathentry kind="src" path="src/java"/>
+ <classpathentry kind="src" path="src/groovy"/>
+ <classpathentry kind="src" path="grails-app/conf"/>
+ <classpathentry kind="src" path="grails-app/controllers"/>
+ <classpathentry kind="src" path="grails-app/domain"/>
+ <classpathentry kind="src" path="grails-app/services"/>
+ <classpathentry kind="src" path="grails-app/taglib"/>
+ <classpathentry kind="src" path="test/integration"/>
+ <classpathentry kind="src" path="test/unit"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="com.springsource.sts.grails.core.CLASSPATH_CONTAINER"/>
+ <classpathentry kind="output" path="web-app/WEB-INF/classes"/>
+</classpath>
2  .gitignore
@@ -0,0 +1,2 @@
+target/*
+out/*
19 .project
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>mongoPlugin</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>com.springsource.sts.grails.core.nature</nature>
+ <nature>org.eclipse.jdt.groovy.core.groovyNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
3  .settings/org.codehaus.groovy.eclipse.preferences.prefs
@@ -0,0 +1,3 @@
+#Created by grails
+eclipse.preferences.version=1
+groovy.dont.generate.class.files=true
85 GormMongodbGrailsPlugin.groovy
@@ -0,0 +1,85 @@
+import grails.plugins.mongodb.MongoDomainClassArtefactHandler
+import grails.plugins.mongodb.MongoPluginSupport
+import org.springframework.context.ApplicationContext
+import grails.plugins.mongodb.MongoDomainClass
+import org.springframework.beans.factory.config.MethodInvokingFactoryBean
+import org.codehaus.groovy.grails.validation.GrailsDomainClassValidator
+
+class GormMongodbGrailsPlugin {
+ // the plugin version
+ def version = "0.1"
+ // the version or versions of Grails the plugin is designed for
+ def grailsVersion = "1.3.1 > *"
+ // the other plugins this plugin depends on
+ def dependsOn = [:]
+ // resources that are excluded from plugin packaging
+ def pluginExcludes = [
+ "grails-app/views/error.gsp",
+ "grails-app/controllers/**", // they exist only for testing purposes
+ "grails-app/conf/Config.groovy",
+ "grails-app/mongo/**",
+ "lib/hibernate*" // see issue GRAILS-6341 NoClassDefFoundError: org/hibernate/mapping/Value when Hibernate not present
+ ]
+
+ // TODO Fill in these fields
+ def author = "Juri Kuehn"
+ def authorEmail = "juri.kuehn at gmail.com"
+ def title = "Grails MongoDB plugin"
+ def description = '''GORM Layer for the superfast, highly scalable, schemafree, document oriented database MongoDB'''
+
+ // URL to the plugin's documentation
+ def documentation = "http://grails.org/plugin/gorm-mongodb"
+
+ def artefacts = [grails.plugins.mongodb.MongoDomainClassArtefactHandler]
+
+ def watchedResources = [
+ 'file:./grails-app/mongo/**',
+ ]
+
+ def doWithSpring = { ApplicationContext ctx ->
+ // register mongo domains as beans
+ application.MongoDomainClasses.each { MongoDomainClass dc ->
+
+ // Note the use of Groovy's ability to use dynamic strings in method names!
+ "${dc.fullName}"(dc.getClazz()) {bean ->
+ bean.singleton = false
+ bean.autowire = "byName"
+ }
+
+ "${dc.fullName}DomainClass"(MethodInvokingFactoryBean) {
+ targetObject = ref("grailsApplication", true)
+ targetMethod = "getArtefact"
+ arguments = [MongoDomainClassArtefactHandler.TYPE, dc.fullName]
+ }
+
+ "${dc.fullName}PersistentClass"(MethodInvokingFactoryBean) {
+ targetObject = ref("${dc.fullName}DomainClass")
+ targetMethod = "getClazz"
+ }
+
+ "${dc.fullName}Validator"(GrailsDomainClassValidator) {
+ messageSource = ref("messageSource")
+ domainClass = ref("${dc.fullName}DomainClass")
+ grailsApplication = ref("grailsApplication", true)
+ }
+ }
+ }
+
+ def doWithDynamicMethods = { ApplicationContext ctx ->
+ application.MongoDomainClasses.each { MongoDomainClass domainClass ->
+ // add dynamic finders, validation, querying methods etc
+ MongoPluginSupport.enhanceDomainClass(domainClass, application, ctx)
+ }
+ }
+
+ /**
+ * in order to reload the mongoclasses grails app has to be reloaded
+ */
+ def onChange = {event ->
+ if (grails.plugins.mongodb.MongoDomainClassArtefactHandler.isMongoDomainClass(event.source)) {
+ // reload needed, reregistering spring beans, enhancing domainclass, evaluating constraints etc
+ log.info("MongoDB domain ${event.source} changed, reloading.")
+ application.rebuild()
+ }
+ }
+}
203 LICENSE
@@ -0,0 +1,203 @@
+/*
+* Apache License
+* Version 2.0, January 2004
+* http://www.apache.org/licenses/
+*
+* TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+*
+* 1. Definitions.
+*
+* "License" shall mean the terms and conditions for use, reproduction,
+* and distribution as defined by Sections 1 through 9 of this document.
+*
+* "Licensor" shall mean the copyright owner or entity authorized by
+* the copyright owner that is granting the License.
+*
+* "Legal Entity" shall mean the union of the acting entity and all
+* other entities that control, are controlled by, or are under common
+* control with that entity. For the purposes of this definition,
+* "control" means (i) the power, direct or indirect, to cause the
+* direction or management of such entity, whether by contract or
+* otherwise, or (ii) ownership of fifty percent (50%) or more of the
+* outstanding shares, or (iii) beneficial ownership of such entity.
+*
+* "You" (or "Your") shall mean an individual or Legal Entity
+* exercising permissions granted by this License.
+*
+* "Source" form shall mean the preferred form for making modifications,
+* including but not limited to software source code, documentation
+* source, and configuration files.
+*
+* "Object" form shall mean any form resulting from mechanical
+* transformation or translation of a Source form, including but
+* not limited to compiled object code, generated documentation,
+* and conversions to other media types.
+*
+* "Work" shall mean the work of authorship, whether in Source or
+* Object form, made available under the License, as indicated by a
+* copyright notice that is included in or attached to the work
+* (an example is provided in the Appendix below).
+*
+* "Derivative Works" shall mean any work, whether in Source or Object
+* form, that is based on (or derived from) the Work and for which the
+* editorial revisions, annotations, elaborations, or other modifications
+* represent, as a whole, an original work of authorship. For the purposes
+* of this License, Derivative Works shall not include works that remain
+* separable from, or merely link (or bind by name) to the interfaces of,
+* the Work and Derivative Works thereof.
+*
+* "Contribution" shall mean any work of authorship, including
+* the original version of the Work and any modifications or additions
+* to that Work or Derivative Works thereof, that is intentionally
+* submitted to Licensor for inclusion in the Work by the copyright owner
+* or by an individual or Legal Entity authorized to submit on behalf of
+* the copyright owner. For the purposes of this definition, "submitted"
+* means any form of electronic, verbal, or written communication sent
+* to the Licensor or its representatives, including but not limited to
+* communication on electronic mailing lists, source code control systems,
+* and issue tracking systems that are managed by, or on behalf of, the
+* Licensor for the purpose of discussing and improving the Work, but
+* excluding communication that is conspicuously marked or otherwise
+* designated in writing by the copyright owner as "Not a Contribution."
+*
+* "Contributor" shall mean Licensor and any individual or Legal Entity
+* on behalf of whom a Contribution has been received by Licensor and
+* subsequently incorporated within the Work.
+*
+* 2. Grant of Copyright License. Subject to the terms and conditions of
+* this License, each Contributor hereby grants to You a perpetual,
+* worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+* copyright license to reproduce, prepare Derivative Works of,
+* publicly display, publicly perform, sublicense, and distribute the
+* Work and such Derivative Works in Source or Object form.
+*
+* 3. Grant of Patent License. Subject to the terms and conditions of
+* this License, each Contributor hereby grants to You a perpetual,
+* worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+* (except as stated in this section) patent license to make, have made,
+* use, offer to sell, sell, import, and otherwise transfer the Work,
+* where such license applies only to those patent claims licensable
+* by such Contributor that are necessarily infringed by their
+* Contribution(s) alone or by combination of their Contribution(s)
+* with the Work to which such Contribution(s) was submitted. If You
+* institute patent litigation against any entity (including a
+* cross-claim or counterclaim in a lawsuit) alleging that the Work
+* or a Contribution incorporated within the Work constitutes direct
+* or contributory patent infringement, then any patent licenses
+* granted to You under this License for that Work shall terminate
+* as of the date such litigation is filed.
+*
+* 4. Redistribution. You may reproduce and distribute copies of the
+* Work or Derivative Works thereof in any medium, with or without
+* modifications, and in Source or Object form, provided that You
+* meet the following conditions:
+*
+* (a) You must give any other recipients of the Work or
+* Derivative Works a copy of this License; and
+*
+* (b) You must cause any modified files to carry prominent notices
+* stating that You changed the files; and
+*
+* (c) You must retain, in the Source form of any Derivative Works
+* that You distribute, all copyright, patent, trademark, and
+* attribution notices from the Source form of the Work,
+* excluding those notices that do not pertain to any part of
+* the Derivative Works; and
+*
+* (d) If the Work includes a "NOTICE" text file as part of its
+* distribution, then any Derivative Works that You distribute must
+* include a readable copy of the attribution notices contained
+* within such NOTICE file, excluding those notices that do not
+* pertain to any part of the Derivative Works, in at least one
+* of the following places: within a NOTICE text file distributed
+* as part of the Derivative Works; within the Source form or
+* documentation, if provided along with the Derivative Works; or,
+* within a display generated by the Derivative Works, if and
+* wherever such third-party notices normally appear. The contents
+* of the NOTICE file are for informational purposes only and
+* do not modify the License. You may add Your own attribution
+* notices within Derivative Works that You distribute, alongside
+* or as an addendum to the NOTICE text from the Work, provided
+* that such additional attribution notices cannot be construed
+* as modifying the License.
+*
+* You may add Your own copyright statement to Your modifications and
+* may provide additional or different license terms and conditions
+* for use, reproduction, or distribution of Your modifications, or
+* for any such Derivative Works as a whole, provided Your use,
+* reproduction, and distribution of the Work otherwise complies with
+* the conditions stated in this License.
+*
+* 5. Submission of Contributions. Unless You explicitly state otherwise,
+* any Contribution intentionally submitted for inclusion in the Work
+* by You to the Licensor shall be under the terms and conditions of
+* this License, without any additional terms or conditions.
+* Notwithstanding the above, nothing herein shall supersede or modify
+* the terms of any separate license agreement you may have executed
+* with Licensor regarding such Contributions.
+*
+* 6. Trademarks. This License does not grant permission to use the trade
+* names, trademarks, service marks, or product names of the Licensor,
+* except as required for reasonable and customary use in describing the
+* origin of the Work and reproducing the content of the NOTICE file.
+*
+* 7. Disclaimer of Warranty. Unless required by applicable law or
+* agreed to in writing, Licensor provides the Work (and each
+* Contributor provides its Contributions) on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+* implied, including, without limitation, any warranties or conditions
+* of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+* PARTICULAR PURPOSE. You are solely responsible for determining the
+* appropriateness of using or redistributing the Work and assume any
+* risks associated with Your exercise of permissions under this License.
+*
+* 8. Limitation of Liability. In no event and under no legal theory,
+* whether in tort (including negligence), contract, or otherwise,
+* unless required by applicable law (such as deliberate and grossly
+* negligent acts) or agreed to in writing, shall any Contributor be
+* liable to You for damages, including any direct, indirect, special,
+* incidental, or consequential damages of any character arising as a
+* result of this License or out of the use or inability to use the
+* Work (including but not limited to damages for loss of goodwill,
+* work stoppage, computer failure or malfunction, or any and all
+* other commercial damages or losses), even if such Contributor
+* has been advised of the possibility of such damages.
+*
+* 9. Accepting Warranty or Additional Liability. While redistributing
+* the Work or Derivative Works thereof, You may choose to offer,
+* and charge a fee for, acceptance of support, warranty, indemnity,
+* or other liability obligations and/or rights consistent with this
+* License. However, in accepting such obligations, You may act only
+* on Your own behalf and on Your sole responsibility, not on behalf
+* of any other Contributor, and only if You agree to indemnify,
+* defend, and hold each Contributor harmless for any liability
+* incurred by, or claims asserted against, such Contributor by reason
+* of your accepting any such warranty or additional liability.
+*
+* END OF TERMS AND CONDITIONS
+*
+* APPENDIX: How to apply the Apache License to your work.
+*
+* To apply the Apache License to your work, attach the following
+* boilerplate notice, with the fields enclosed by brackets "[]"
+* replaced with your own identifying information. (Don't include
+* the brackets!) The text should be enclosed in the appropriate
+* comment syntax for the file format. We also recommend that a
+* file or class name and description of purpose be included on the
+* same "printed page" as the copyright notice for easier
+* identification within third-party archives.
+*
+* Copyright [yyyy] [name of copyright owner]
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
23 MongoPlugin-grailsPlugins.iml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$USER_HOME_GRAILS$/1.3.1/projects/mongoPlugin/plugins/tomcat-1.3.1">
+ <sourceFolder url="file://$USER_HOME_GRAILS$/1.3.1/projects/mongoPlugin/plugins/tomcat-1.3.1/src/groovy" isTestSource="false" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" name="grails-1.3.1" level="application" />
+ <orderEntry type="module-library" exported="">
+ <library name="Grails User Library">
+ <CLASSES>
+ <root url="file://$USER_HOME_GRAILS$/1.3.1/projects/mongoPlugin/plugins/tomcat-1.3.1/lib" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ <jarDirectory url="file://$USER_HOME_GRAILS$/1.3.1/projects/mongoPlugin/plugins/tomcat-1.3.1/lib" recursive="false" />
+ </library>
+ </orderEntry>
+ </component>
+</module>
+
52 MongoPlugin.iml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+ <component name="FacetManager">
+ <facet type="Spring" name="Spring">
+ <configuration>
+ <fileset id="Grails" name="Grails" removed="false">
+ <file>file://$MODULE_DIR$/web-app/WEB-INF/applicationContext.xml</file>
+ </fileset>
+ </configuration>
+ </facet>
+ <facet type="web" name="GrailsWeb">
+ <configuration>
+ <webroots>
+ <root url="file://$MODULE_DIR$/web-app" relative="/" />
+ </webroots>
+ <sourceRoots />
+ </configuration>
+ </facet>
+ </component>
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/src/java" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/grails-app/utils" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/groovy" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/grails-app/controllers" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/grails-app/domain" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/grails-app/services" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/grails-app/taglib" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/test/unit" isTestSource="true" />
+ <sourceFolder url="file://$MODULE_DIR$/test/integration" isTestSource="true" />
+ <sourceFolder url="file://$MODULE_DIR$/grails-app/mongo" isTestSource="false" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" name="grails-1.3.1" level="application" />
+ <orderEntry type="module-library">
+ <library name="Grails User Library">
+ <CLASSES>
+ <root url="file://$MODULE_DIR$/lib" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES>
+ <root url="file://$SPRING_DIR$/mongodb/morphia/morphia/src/main/java" />
+ </SOURCES>
+ <jarDirectory url="file://$MODULE_DIR$/lib" recursive="false" />
+ </library>
+ </orderEntry>
+ <orderEntry type="module" module-name="MongoPlugin-grailsPlugins" />
+ </component>
+</module>
+
232 MongoPlugin.ipr
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="AntConfiguration">
+ <defaultAnt bundledAnt="true" />
+ </component>
+ <component name="BuildJarProjectSettings">
+ <option name="BUILD_JARS_ON_MAKE" value="false" />
+ </component>
+ <component name="CompilerConfiguration">
+ <option name="DEFAULT_COMPILER" value="Javac" />
+ <resourceExtensions>
+ <entry name=".+\.(properties|xml|html|dtd|tld)" />
+ <entry name=".+\.(gif|png|jpeg|jpg)" />
+ </resourceExtensions>
+ <wildcardResourcePatterns>
+ <entry name="?*.properties" />
+ <entry name="?*.xml" />
+ <entry name="?*.gif" />
+ <entry name="?*.png" />
+ <entry name="?*.jpeg" />
+ <entry name="?*.jpg" />
+ <entry name="?*.html" />
+ <entry name="?*.dtd" />
+ <entry name="?*.tld" />
+ <entry name="?*.ftl" />
+ </wildcardResourcePatterns>
+ <annotationProcessing enabled="false" useClasspath="true" />
+ </component>
+ <component name="CopyrightManager" default="">
+ <module2copyright />
+ </component>
+ <component name="DependencyValidationManager">
+ <option name="SKIP_IMPORT_STATEMENTS" value="false" />
+ </component>
+ <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
+ <component name="InspectionProjectProfileManager">
+ <profiles>
+ <profile version="1.0" is_locked="false">
+ <option name="myName" value="Project Default" />
+ <option name="myLocal" value="false" />
+ <inspection_tool class="GroovyFallthrough" enabled="false" level="WARNING" enabled_by_default="false" />
+ <inspection_tool class="GroovyUnusedAssignment" enabled="false" level="WARNING" enabled_by_default="false" />
+ </profile>
+ </profiles>
+ <option name="PROJECT_PROFILE" value="Project Default" />
+ <option name="USE_PROJECT_PROFILE" value="true" />
+ <version value="1.0" />
+ <list size="5">
+ <item index="0" class="java.lang.String" itemvalue="SERVER PROBLEM" />
+ <item index="1" class="java.lang.String" itemvalue="INFO" />
+ <item index="2" class="java.lang.String" itemvalue="TYPO" />
+ <item index="3" class="java.lang.String" itemvalue="WARNING" />
+ <item index="4" class="java.lang.String" itemvalue="ERROR" />
+ </list>
+ </component>
+ <component name="JavadocGenerationManager">
+ <option name="OUTPUT_DIRECTORY" />
+ <option name="OPTION_SCOPE" value="protected" />
+ <option name="OPTION_HIERARCHY" value="true" />
+ <option name="OPTION_NAVIGATOR" value="true" />
+ <option name="OPTION_INDEX" value="true" />
+ <option name="OPTION_SEPARATE_INDEX" value="true" />
+ <option name="OPTION_DOCUMENT_TAG_USE" value="false" />
+ <option name="OPTION_DOCUMENT_TAG_AUTHOR" value="false" />
+ <option name="OPTION_DOCUMENT_TAG_VERSION" value="false" />
+ <option name="OPTION_DOCUMENT_TAG_DEPRECATED" value="true" />
+ <option name="OPTION_DEPRECATED_LIST" value="true" />
+ <option name="OTHER_OPTIONS" value="" />
+ <option name="HEAP_SIZE" />
+ <option name="LOCALE" />
+ <option name="OPEN_IN_BROWSER" value="true" />
+ </component>
+ <component name="Palette2">
+ <group name="Swing">
+ <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
+ <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
+ </item>
+ <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
+ <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
+ </item>
+ <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
+ <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
+ </item>
+ <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
+ <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
+ </item>
+ <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
+ <initial-values>
+ <property name="text" value="Button" />
+ </initial-values>
+ </item>
+ <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+ <initial-values>
+ <property name="text" value="RadioButton" />
+ </initial-values>
+ </item>
+ <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+ <initial-values>
+ <property name="text" value="CheckBox" />
+ </initial-values>
+ </item>
+ <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
+ <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
+ <initial-values>
+ <property name="text" value="Label" />
+ </initial-values>
+ </item>
+ <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
+ <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+ <preferred-size width="150" height="-1" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
+ <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+ <preferred-size width="150" height="-1" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
+ <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+ <preferred-size width="150" height="-1" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
+ <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+ <preferred-size width="150" height="50" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
+ <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+ <preferred-size width="150" height="50" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
+ <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+ <preferred-size width="150" height="50" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
+ <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
+ </item>
+ <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+ <preferred-size width="150" height="50" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
+ <preferred-size width="150" height="50" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+ <preferred-size width="150" height="50" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+ <preferred-size width="200" height="200" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
+ <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+ <preferred-size width="200" height="200" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
+ <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+ </item>
+ <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+ </item>
+ <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
+ <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
+ </item>
+ <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
+ </item>
+ <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
+ <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
+ <preferred-size width="-1" height="20" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
+ <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
+ </item>
+ <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
+ </item>
+ </group>
+ </component>
+ <component name="ProjectModuleManager">
+ <modules>
+ <module fileurl="file://$PROJECT_DIR$/MongoPlugin.iml" filepath="$PROJECT_DIR$/MongoPlugin.iml" />
+ <module fileurl="file://$PROJECT_DIR$/MongoPlugin-grailsPlugins.iml" filepath="$PROJECT_DIR$/MongoPlugin-grailsPlugins.iml" />
+ </modules>
+ </component>
+ <component name="ProjectRootManager" version="2" languageLevel="JDK_1_5" assert-keyword="true" jdk-15="true" project-jdk-name="1.6" project-jdk-type="JavaSDK">
+ <output url="file://$PROJECT_DIR$/out" />
+ </component>
+ <component name="ResourceManagerContainer">
+ <option name="myResourceBundles">
+ <value>
+ <list size="0" />
+ </value>
+ </option>
+ </component>
+ <component name="SvnConfiguration">
+ <option name="USER" value="" />
+ <option name="PASSWORD" value="" />
+ <option name="LAST_MERGED_REVISION" />
+ <option name="UPDATE_RUN_STATUS" value="false" />
+ <option name="MERGE_DRY_RUN" value="false" />
+ <option name="MERGE_DIFF_USE_ANCESTRY" value="true" />
+ <option name="UPDATE_LOCK_ON_DEMAND" value="false" />
+ <option name="IGNORE_SPACES_IN_MERGE" value="false" />
+ <option name="DETECT_NESTED_COPIES" value="false" />
+ <option name="IGNORE_SPACES_IN_ANNOTATE" value="true" />
+ <option name="SHOW_MERGE_SOURCES_IN_ANNOTATE" value="true" />
+ <myIsUseDefaultProxy>false</myIsUseDefaultProxy>
+ </component>
+ <component name="VcsDirectoryMappings">
+ <mapping directory="" vcs="" />
+ </component>
+ <component name="XPathView.XPathProjectComponent">
+ <history />
+ <find-history />
+ </component>
+</project>
+
560 MongoPlugin.iws
@@ -0,0 +1,560 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="ChangeListManager">
+ <list default="true" id="eacb9a6d-ffb5-41d0-a511-4b68b9834b42" name="Default" comment="" />
+ <ignored path="$USER_HOME_GRAILS$/" />
+ <ignored path="$USER_HOME_GRIFFON$/" />
+ <option name="TRACKING_ENABLED" value="true" />
+ <option name="SHOW_DIALOG" value="false" />
+ <option name="HIGHLIGHT_CONFLICTS" value="true" />
+ <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
+ <option name="LAST_RESOLUTION" value="IGNORE" />
+ </component>
+ <component name="ChangesViewManager" flattened_view="true" show_ignored="false" />
+ <component name="CreatePatchCommitExecutor">
+ <option name="PATCH_PATH" value="" />
+ <option name="REVERSE_PATCH" value="false" />
+ </component>
+ <component name="DaemonCodeAnalyzer">
+ <disable_hints />
+ </component>
+ <component name="DebuggerManager">
+ <breakpoint_any>
+ <breakpoint>
+ <option name="NOTIFY_CAUGHT" value="true" />
+ <option name="NOTIFY_UNCAUGHT" value="true" />
+ <option name="ENABLED" value="false" />
+ <option name="LOG_ENABLED" value="false" />
+ <option name="LOG_EXPRESSION_ENABLED" value="false" />
+ <option name="SUSPEND_POLICY" value="SuspendAll" />
+ <option name="COUNT_FILTER_ENABLED" value="false" />
+ <option name="COUNT_FILTER" value="0" />
+ <option name="CONDITION_ENABLED" value="false" />
+ <option name="CLASS_FILTERS_ENABLED" value="false" />
+ <option name="INSTANCE_FILTERS_ENABLED" value="false" />
+ <option name="CONDITION" value="" />
+ <option name="LOG_MESSAGE" value="" />
+ </breakpoint>
+ <breakpoint>
+ <option name="NOTIFY_CAUGHT" value="true" />
+ <option name="NOTIFY_UNCAUGHT" value="true" />
+ <option name="ENABLED" value="false" />
+ <option name="LOG_ENABLED" value="false" />
+ <option name="LOG_EXPRESSION_ENABLED" value="false" />
+ <option name="SUSPEND_POLICY" value="SuspendAll" />
+ <option name="COUNT_FILTER_ENABLED" value="false" />
+ <option name="COUNT_FILTER" value="0" />
+ <option name="CONDITION_ENABLED" value="false" />
+ <option name="CLASS_FILTERS_ENABLED" value="false" />
+ <option name="INSTANCE_FILTERS_ENABLED" value="false" />
+ <option name="CONDITION" value="" />
+ <option name="LOG_MESSAGE" value="" />
+ </breakpoint>
+ </breakpoint_any>
+ <breakpoint_rules />
+ <ui_properties />
+ </component>
+ <component name="FavoritesManager">
+ <favorites_list name="MongoPlugin" />
+ </component>
+ <component name="FileColors" enabled="true" enabledForTabs="true" />
+ <component name="FileEditorManager">
+ <leaf />
+ </component>
+ <component name="FindManager">
+ <FindUsagesManager>
+ <setting name="OPEN_NEW_TAB" value="false" />
+ </FindUsagesManager>
+ </component>
+ <component name="IdeDocumentHistory">
+ <option name="changedFiles">
+ <list>
+ <option value="$PROJECT_DIR$/test/integration/grails/plugins/mongodb/test/AdvancedQueryingTests.groovy" />
+ <option value="$PROJECT_DIR$/test/integration/grails/plugins/mongodb/test/BasicPersistenceTests.groovy" />
+ <option value="$PROJECT_DIR$/test/integration/grails/plugins/mongodb/test/DynamicFindersTests.groovy" />
+ <option value="$PROJECT_DIR$/grails-app/mongo/org/acme/Contact.groovy" />
+ <option value="$PROJECT_DIR$/src/java/grails/plugins/mongodb/MongoDomainClass.java" />
+ <option value="$PROJECT_DIR$/src/java/grails/plugins/mongodb/MongoDomainClassProperty.java" />
+ <option value="$PROJECT_DIR$/test/integration/grails/plugins/mongodb/test/ClassMethodsTest.groovy" />
+ <option value="$PROJECT_DIR$/src/templates/artifacts/MongoDBDomain.groovy" />
+ <option value="$PROJECT_DIR$/scripts/CreateMongoClass.groovy" />
+ <option value="$PROJECT_DIR$/src/templates/artifacts/MongoDBClass.groovy" />
+ <option value="$PROJECT_DIR$/scripts/CreateMongodbClass.groovy" />
+ <option value="$PROJECT_DIR$/scripts/GenerateAllMongodb.groovy" />
+ <option value="$PROJECT_DIR$/grails-app/mongo/org/acme/Task.groovy" />
+ <option value="$PROJECT_DIR$/GormMongodbGrailsPlugin.groovy" />
+ <option value="$PROJECT_DIR$/src/groovy/grails/plugins/mongodb/MongoPluginSupport.groovy" />
+ <option value="$PROJECT_DIR$/test/integration/grails/plugins/mongodb/test/StaticMethodsTests.groovy" />
+ </list>
+ </option>
+ </component>
+ <component name="ModuleEditorState">
+ <option name="LAST_EDITED_MODULE_NAME" />
+ <option name="LAST_EDITED_TAB_NAME" />
+ </component>
+ <component name="ProjectInspectionProfilesVisibleTreeState">
+ <entry key="Project Default">
+ <profile-state />
+ </entry>
+ </component>
+ <component name="ProjectLevelVcsManager">
+ <OptionsSetting value="true" id="Add" />
+ <OptionsSetting value="true" id="Remove" />
+ <OptionsSetting value="true" id="Checkout" />
+ <OptionsSetting value="true" id="Update" />
+ <OptionsSetting value="true" id="Status" />
+ <OptionsSetting value="true" id="Edit" />
+ <ConfirmationsSetting value="0" id="Add" />
+ <ConfirmationsSetting value="0" id="Remove" />
+ </component>
+ <component name="ProjectReloadState">
+ <option name="STATE" value="0" />
+ </component>
+ <component name="ProjectView">
+ <navigator currentView="ProjectPane" proportions="" version="1" splitterProportion="0.5">
+ <flattenPackages />
+ <showMembers />
+ <showModules />
+ <showLibraryContents />
+ <hideEmptyPackages />
+ <abbreviatePackageNames />
+ <autoscrollToSource />
+ <autoscrollFromSource />
+ <sortByType />
+ </navigator>
+ <panes>
+ <pane id="PackagesPane" />
+ <pane id="Favorites" />
+ <pane id="Scope" />
+ <pane id="ProjectPane">
+ <subPane>
+ <PATH>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="MongoPlugin" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+ </PATH_ELEMENT>
+ </PATH>
+ <PATH>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="MongoPlugin" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="mongoPlugin" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ </PATH>
+ <PATH>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="MongoPlugin" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="mongoPlugin" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="test" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ </PATH>
+ <PATH>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="MongoPlugin" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="mongoPlugin" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="test" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="integration" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="test" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ </PATH>
+ </subPane>
+ </pane>
+ </panes>
+ </component>
+ <component name="PropertiesComponent">
+ <property name="GoToFile.includeJavaFiles" value="false" />
+ <property name="project.structure.last.edited" value="Modules" />
+ <property name="OverrideImplement.combined" value="true" />
+ <property name="project.structure.proportion" value="0.15" />
+ <property name="options.splitter.main.proportions" value="0.3" />
+ <property name="recentsLimit" value="5" />
+ <property name="MemberChooser.sorted" value="false" />
+ <property name="options.lastSelected" value="fileTemplates" />
+ <property name="project.structure.side.proportion" value="0.2" />
+ <property name="MemberChooser.copyJavadoc" value="false" />
+ <property name="GoToClass.toSaveIncludeLibraries" value="false" />
+ <property name="MemberChooser.showClasses" value="true" />
+ <property name="GoToClass.includeLibraries" value="false" />
+ <property name="dynamic.classpath" value="false" />
+ <property name="options.splitter.details.proportions" value="0.2" />
+ <property name="options.searchVisible" value="true" />
+ </component>
+ <component name="RecentsManager">
+ <key name="CopyFile.RECENT_KEYS">
+ <recent name="G:\temp\grails_test\mongoPlugin\grails-app\mongo" />
+ </key>
+ <key name="CreateClassDialog.RecentsKey">
+ <recent name="de.jurikuehn.grails.mongodb" />
+ </key>
+ <key name="MoveFile.RECENT_KEYS">
+ <recent name="G:\temp\grails_test\mongoPlugin\grails-app\conf" />
+ </key>
+ </component>
+ <component name="RunManager" selected="Grails.MongoDebug">
+ <configuration default="true" type="GrailsRunConfigurationType" factoryName="Grails">
+ <module name="" />
+ <setting name="vmparams" value="" />
+ <setting name="cmdLine" value="run-app" />
+ <setting name="depsClasspath" value="true" />
+ <setting name="launchBrowser" value="true" />
+ <method>
+ <option name="AntTarget" enabled="false" />
+ <option name="BuildArtifacts" enabled="false" />
+ <option name="Make" enabled="true" />
+ </method>
+ </configuration>
+ <configuration default="true" type="Remote" factoryName="Remote">
+ <option name="USE_SOCKET_TRANSPORT" value="true" />
+ <option name="SERVER_MODE" value="false" />
+ <option name="SHMEM_ADDRESS" value="javadebug" />
+ <option name="HOST" value="localhost" />
+ <option name="PORT" value="5005" />
+ <method>
+ <option name="AntTarget" enabled="false" />
+ <option name="BuildArtifacts" enabled="false" />
+ <option name="Maven.BeforeRunTask" enabled="false" />
+ </method>
+ </configuration>
+ <configuration default="true" type="Applet" factoryName="Applet">
+ <module name="" />
+ <option name="MAIN_CLASS_NAME" />
+ <option name="HTML_FILE_NAME" />
+ <option name="HTML_USED" value="false" />
+ <option name="WIDTH" value="400" />
+ <option name="HEIGHT" value="300" />
+ <option name="POLICY_FILE" value="$APPLICATION_HOME_DIR$/bin/appletviewer.policy" />
+ <option name="VM_PARAMETERS" />
+ <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+ <option name="ALTERNATIVE_JRE_PATH" />
+ <method>
+ <option name="AntTarget" enabled="false" />
+ <option name="BuildArtifacts" enabled="false" />
+ <option name="Make" enabled="true" />
+ <option name="Maven.BeforeRunTask" enabled="false" />
+ </method>
+ </configuration>
+ <configuration default="true" type="Application" factoryName="Application">
+ <extension name="coverage" enabled="false" merge="false" runner="emma" />
+ <extension name="snapshooter" />
+ <option name="MAIN_CLASS_NAME" />
+ <option name="VM_PARAMETERS" />
+ <option name="PROGRAM_PARAMETERS" />
+ <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+ <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+ <option name="ALTERNATIVE_JRE_PATH" />
+ <option name="ENABLE_SWING_INSPECTOR" value="false" />
+ <option name="ENV_VARIABLES" />
+ <option name="PASS_PARENT_ENVS" value="true" />
+ <module name="" />
+ <envs />
+ <method>
+ <option name="AntTarget" enabled="false" />
+ <option name="BuildArtifacts" enabled="false" />
+ <option name="Make" enabled="true" />
+ <option name="Maven.BeforeRunTask" enabled="false" />
+ </method>
+ </configuration>
+ <configuration default="true" type="JUnit" factoryName="JUnit">
+ <extension name="coverage" enabled="false" merge="false" runner="emma" />
+ <extension name="snapshooter" />
+ <module name="" />
+ <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+ <option name="ALTERNATIVE_JRE_PATH" />
+ <option name="PACKAGE_NAME" />
+ <option name="MAIN_CLASS_NAME" />
+ <option name="METHOD_NAME" />
+ <option name="TEST_OBJECT" value="class" />
+ <option name="VM_PARAMETERS" />
+ <option name="PARAMETERS" />
+ <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+ <option name="ENV_VARIABLES" />
+ <option name="PASS_PARENT_ENVS" value="true" />
+ <option name="TEST_SEARCH_SCOPE">
+ <value defaultName="moduleWithDependencies" />
+ </option>
+ <envs />
+ <method>
+ <option name="AntTarget" enabled="false" />
+ <option name="BuildArtifacts" enabled="false" />
+ <option name="Make" enabled="true" />
+ <option name="Maven.BeforeRunTask" enabled="false" />
+ </method>
+ </configuration>
+ <configuration default="true" type="GroovyScriptRunConfiguration" factoryName="Groovy Script">
+ <module name="" />
+ <setting name="path" value="" />
+ <setting name="vmparams" value="" />
+ <setting name="params" value="" />
+ <setting name="workDir" value="G:\temp\grails_test\mongoPlugin" />
+ <setting name="debug" value="false" />
+ <method>
+ <option name="AntTarget" enabled="false" />
+ <option name="BuildArtifacts" enabled="false" />
+ <option name="Make" enabled="true" />
+ </method>
+ </configuration>
+ <configuration default="false" name="MongoDebug" type="GrailsRunConfigurationType" factoryName="Grails">
+ <module name="MongoPlugin" />
+ <setting name="vmparams" value="" />
+ <setting name="cmdLine" value="generate-all-mongodb Contact" />
+ <setting name="depsClasspath" value="true" />
+ <setting name="launchBrowser" value="false" />
+ <RunnerSettings RunnerId="Debug">
+ <option name="DEBUG_PORT" value="49590" />
+ <option name="TRANSPORT" value="0" />
+ <option name="LOCAL" value="true" />
+ </RunnerSettings>
+ <RunnerSettings RunnerId="Run" />
+ <ConfigurationWrapper RunnerId="Debug" />
+ <ConfigurationWrapper RunnerId="Run" />
+ <method />
+ </configuration>
+ <list size="1">
+ <item index="0" class="java.lang.String" itemvalue="Grails.MongoDebug" />
+ </list>
+ <configuration name="&lt;template&gt;" type="WebApp" default="true" selected="false">
+ <Host>localhost</Host>
+ <Port>5050</Port>
+ </configuration>
+ </component>
+ <component name="ShelveChangesManager" show_recycled="false" />
+ <component name="TaskManager">
+ <task active="true" id="Default" summary="Default task">
+ <changelist id="eacb9a6d-ffb5-41d0-a511-4b68b9834b42" name="Default" comment="" />
+ <created>1275241737087</created>
+ <updated>1275241737087</updated>
+ </task>
+ <servers />
+ </component>
+ <component name="ToolWindowManager">
+ <frame x="-8" y="-8" width="1296" height="970" extended-state="6" />
+ <editor active="true" />
+ <layout>
+ <window_info id="Changes" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
+ <window_info id="Palette" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
+ <window_info id="Web" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="2" side_tool="true" content_ui="tabs" />
+ <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
+ <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+ <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.26682886" sideWeight="0.66503066" order="1" side_tool="true" content_ui="tabs" />
+ <window_info id="Dependency Viewer" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
+ <window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.27656123" sideWeight="0.66503066" order="0" side_tool="false" content_ui="tabs" />
+ <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
+ <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32883435" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
+ <window_info id="Grails View" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
+ <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
+ <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
+ <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+ <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32638037" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+ <window_info id="Console" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32881773" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
+ <window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32883435" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
+ <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+ <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
+ <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
+ </layout>
+ </component>
+ <component name="VcsManagerConfiguration">
+ <option name="OFFER_MOVE_TO_ANOTHER_CHANGELIST_ON_PARTIAL_COMMIT" value="true" />
+ <option name="CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT" value="true" />
+ <option name="PERFORM_UPDATE_IN_BACKGROUND" value="true" />
+ <option name="PERFORM_COMMIT_IN_BACKGROUND" value="true" />
+ <option name="PERFORM_EDIT_IN_BACKGROUND" value="true" />
+ <option name="PERFORM_CHECKOUT_IN_BACKGROUND" value="true" />
+ <option name="PERFORM_ADD_REMOVE_IN_BACKGROUND" value="true" />
+ <option name="PERFORM_ROLLBACK_IN_BACKGROUND" value="false" />
+ <option name="CHECK_LOCALLY_CHANGED_CONFLICTS_IN_BACKGROUND" value="true" />
+ <option name="ENABLE_BACKGROUND_PROCESSES" value="false" />
+ <option name="CHANGED_ON_SERVER_INTERVAL" value="60" />
+ <option name="FORCE_NON_EMPTY_COMMENT" value="false" />
+ <option name="LAST_COMMIT_MESSAGE" />
+ <option name="MAKE_NEW_CHANGELIST_ACTIVE" value="true" />
+ <option name="OPTIMIZE_IMPORTS_BEFORE_PROJECT_COMMIT" value="false" />
+ <option name="CHECK_FILES_UP_TO_DATE_BEFORE_COMMIT" value="false" />
+ <option name="REFORMAT_BEFORE_PROJECT_COMMIT" value="false" />
+ <option name="REFORMAT_BEFORE_FILE_COMMIT" value="false" />
+ <option name="FILE_HISTORY_DIALOG_COMMENTS_SPLITTER_PROPORTION" value="0.8" />
+ <option name="FILE_HISTORY_DIALOG_SPLITTER_PROPORTION" value="0.5" />
+ <option name="ACTIVE_VCS_NAME" />
+ <option name="UPDATE_GROUP_BY_PACKAGES" value="false" />
+ <option name="UPDATE_GROUP_BY_CHANGELIST" value="false" />
+ <option name="SHOW_FILE_HISTORY_AS_TREE" value="false" />
+ <option name="FILE_HISTORY_SPLITTER_PROPORTION" value="0.6" />
+ </component>
+ <component name="XDebuggerManager">
+ <breakpoint-manager />
+ </component>
+ <component name="antWorkspaceConfiguration">
+ <option name="IS_AUTOSCROLL_TO_SOURCE" value="false" />
+ <option name="FILTER_TARGETS" value="false" />
+ </component>
+ <component name="editorHistoryManager">
+ <entry file="file://$PROJECT_DIR$/scripts/CreateMongodbClass.groovy">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="29" column="0" selection-start="905" selection-end="905" vertical-scroll-proportion="0.0" />
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/java/grails/plugins/mongodb/MongoDomainClassArtefactHandler.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="12" column="50" selection-start="374" selection-end="385" vertical-scroll-proportion="0.0" />
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/scripts/GenerateAllMongodb.groovy">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="64" column="0" selection-start="2351" selection-end="2351" vertical-scroll-proportion="0.0" />
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/java/grails/plugins/mongodb/MongoDomainClass.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="29" column="86" selection-start="1153" selection-end="1170" vertical-scroll-proportion="0.0" />
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/grails-app/mongo/org/acme/Project.groovy">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="9" column="6" selection-start="287" selection-end="287" vertical-scroll-proportion="0.10786802" />
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/test/integration/grails/plugins/mongodb/test/UnicodeTests.groovy">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="21" column="11" selection-start="696" selection-end="696" vertical-scroll-proportion="-0.034764826" />
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/grails-app/mongo/org/acme/Contact.groovy">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="7" column="6" selection-start="186" selection-end="186" vertical-scroll-proportion="0.15101522">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/test/integration/grails/plugins/mongodb/test/BasicPersistenceTests.groovy">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="6" column="13" selection-start="120" selection-end="120" vertical-scroll-proportion="0.022849463">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/groovy/grails/plugins/mongodb/MongoPluginSupport.groovy">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="376" column="8" selection-start="12496" selection-end="12496" vertical-scroll-proportion="0.0">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/grails-app/mongo/org/acme/Task.groovy">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="39" column="0" selection-start="696" selection-end="696" vertical-scroll-proportion="0.0" />
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/GormMongodbGrailsPlugin.groovy">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="30" column="60" selection-start="1358" selection-end="1358" vertical-scroll-proportion="0.0">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$SPRING_DIR$/mongodb/morphia/morphia/src/main/java/com/google/code/morphia/mapping/Mapper.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="207" column="18" selection-start="7466" selection-end="7466" vertical-scroll-proportion="-1.2662252">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$SPRING_DIR$/mongodb/morphia/morphia/src/main/java/com/google/code/morphia/DatastoreImpl.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="390" column="11" selection-start="12126" selection-end="12126" vertical-scroll-proportion="0.32470894">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="jar://$PROJECT_DIR$/lib/mongo-1.4.jar!/com/mongodb/DB.class">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="5" column="29" selection-start="165" selection-end="165" vertical-scroll-proportion="-0.046511628">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$SPRING_DIR$/mongodb/morphia/morphia/src/main/java/com/google/code/morphia/Datastore.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="114" column="3" selection-start="4945" selection-end="4945" vertical-scroll-proportion="0.81986755">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/test/integration/grails/plugins/mongodb/test/StaticMethodsTests.groovy">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="41" column="15" selection-start="1584" selection-end="1584" vertical-scroll-proportion="0.56626505">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </component>
+ <component name="masterDetails">
+ <states>
+ <state key="ArtifactsStructureConfigurable.UI">
+ <UIState>
+ <splitter-proportions>
+ <SplitterProportionsDataImpl>
+ <option name="proportions">
+ <list>
+ <option value="0.2" />
+ </list>
+ </option>
+ </SplitterProportionsDataImpl>
+ </splitter-proportions>
+ <settings />
+ </UIState>
+ </state>
+ <state key="Copyright.UI">
+ <UIState>
+ <splitter-proportions>
+ <SplitterProportionsDataImpl />
+ </splitter-proportions>
+ </UIState>
+ </state>
+ <state key="ProjectJDKs.UI">
+ <UIState>
+ <splitter-proportions>
+ <SplitterProportionsDataImpl>
+ <option name="proportions">
+ <list>
+ <option value="0.2" />
+ </list>
+ </option>
+ </SplitterProportionsDataImpl>
+ </splitter-proportions>
+ <last-edited>1.6</last-edited>
+ </UIState>
+ </state>
+ <state key="ScopeChooserConfigurable.UI">
+ <UIState>
+ <splitter-proportions>
+ <SplitterProportionsDataImpl />
+ </splitter-proportions>
+ <settings />
+ </UIState>
+ </state>
+ </states>
+ </component>
+</project>
+
6 application.properties
@@ -0,0 +1,6 @@
+#Grails Metadata file
+#Fri Jun 04 21:49:47 CEST 2010
+app.grails.version=1.3.1
+app.name=gorm-mongodb
+app.version=0.1
+plugins.tomcat=1.3.1
32 grails-app/conf/BuildConfig.groovy
@@ -0,0 +1,32 @@
+grails.project.class.dir = "target/classes"
+grails.project.test.class.dir = "target/test-classes"
+grails.project.test.reports.dir = "target/test-reports"
+//grails.project.war.file = "target/${appName}-${appVersion}.war"
+grails.project.dependency.resolution = {
+ // inherit Grails' default dependencies
+ inherits( "global" ) {
+ // uncomment to disable ehcache
+ // excludes 'ehcache'
+ }
+ log "warn" // log level of Ivy resolver, either 'error', 'warn', 'info', 'debug' or 'verbose'
+ repositories {
+ grailsPlugins()
+ grailsHome()
+ grailsCentral()
+
+ // uncomment the below to enable remote dependency resolution
+ // from public Maven repositories
+ //mavenLocal()
+ //mavenCentral()
+ //mavenRepo "http://snapshots.repository.codehaus.org"
+ //mavenRepo "http://repository.codehaus.org"
+ //mavenRepo "http://download.java.net/maven/2/"
+ //mavenRepo "http://repository.jboss.com/maven2/"
+ }
+ dependencies {
+ // specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.
+
+ // runtime 'mysql:mysql-connector-java:5.1.5'
+ }
+
+}
5 grails-app/conf/Config.groovy
@@ -0,0 +1,5 @@
+mongodb {
+ host = '192.168.1.36'
+ port = 27017
+ database = 'test'
+}
32 grails-app/conf/DataSource.groovy
@@ -0,0 +1,32 @@
+dataSource {
+ pooled = true
+ driverClassName = "org.hsqldb.jdbcDriver"
+ username = "sa"
+ password = ""
+}
+hibernate {
+ cache.use_second_level_cache=true
+ cache.use_query_cache=true
+ cache.provider_class='net.sf.ehcache.hibernate.EhCacheProvider'
+}
+// environment specific settings
+environments {
+ development {
+ dataSource {
+ dbCreate = "create-drop" // one of 'create', 'create-drop','update'
+ url = "jdbc:hsqldb:mem:devDB"
+ }
+ }
+ test {
+ dataSource {
+ dbCreate = "update"
+ url = "jdbc:hsqldb:mem:testDb"
+ }
+ }
+ production {
+ dataSource {
+ dbCreate = "update"
+ url = "jdbc:hsqldb:file:prodDb;shutdown=true"
+ }
+ }
+}
11 grails-app/conf/UrlMappings.groovy
@@ -0,0 +1,11 @@
+class UrlMappings {
+ static mappings = {
+ "/$controller/$action?/$id?"{
+ constraints {
+ // apply constraints here
+ }
+ }
+ "/"(view:"/index")
+ "500"(view:'/error')
+ }
+}
26 grails-app/mongo/org/acme/Contact.groovy
@@ -0,0 +1,26 @@
+package org.acme
+
+import com.google.code.morphia.annotations.Entity
+import com.google.code.morphia.annotations.Id
+import com.google.code.morphia.utils.AbstractMongoEntity
+
+@Entity
+class Contact extends AbstractMongoEntity {
+
+ String name
+ String company
+
+ static constraints = {
+ company nullable: true
+ }
+
+ public String toString ( ) {
+ return "Contact{" +
+ "id='" + id + '\'' +
+ "name='" + name + '\'' +
+ ", company='" + company + '\'' +
+ '}' ;
+ }
+}
+
+
19 grails-app/mongo/org/acme/NotMongoDB.groovy
@@ -0,0 +1,19 @@
+package org.acme
+
+class NotMongoDB {
+
+ String name
+ Integer age
+ Date lastUpdated
+
+ static constraints = {
+ name blank: false
+ }
+
+ public String toString ( ) {
+ return "NotMongoDB{" +
+ "name='" + name + '\'' +
+ ", age=" + age +
+ ", lastUpdated=" + lastUpdated +
+ '}' ;
+ }}
51 grails-app/mongo/org/acme/Project.groovy
@@ -0,0 +1,51 @@
+package org.acme
+
+import com.google.code.morphia.annotations.Reference
+import com.google.code.morphia.annotations.Entity
+import com.google.code.morphia.annotations.Transient
+import com.google.code.morphia.annotations.Embedded
+import com.google.code.morphia.annotations.Id
+
+@Entity
+class Project {
+
+ @Id String id
+
+ String name
+ Date startDate
+ String frequency
+
+ Date dateCreated
+ Date lastUpdated
+
+ @Embedded
+ Task mainTask
+
+ @Reference
+ Contact manager
+
+ @Transient
+ String pass = "pass"
+
+ static constraints = {
+ id nullable: true
+ name blank: false
+ startDate nullable: true
+ frequency nullable: true
+ manager nullable: true
+ mainTask nullable: true
+ }
+
+ public String toString ( ) {
+ return "Project{" +
+ "id='" + id + '\'' +
+ ", name='" + name + '\'' +
+ ", startDate=" + startDate +
+ ", frequency='" + frequency + '\'' +
+ ", dateCreated=" + dateCreated +
+ ", lastUpdated=" + lastUpdated +
+ ", mainTask=" + mainTask +
+ ", manager=" + manager +
+ ", pass='" + pass + '\'' +
+ '}' ;
+ }}
69 grails-app/mongo/org/acme/Task.groovy
@@ -0,0 +1,69 @@
+package org.acme
+
+import com.google.code.morphia.annotations.Entity
+import com.google.code.morphia.annotations.Id
+import com.google.code.morphia.annotations.Transient
+
+@Entity
+class Task {
+
+ @Id
+ String taskId
+
+ String projectId
+ String name
+
+ Date startDate
+ Date completionDate
+ Integer estimatedHours
+ Integer actualHours
+
+ String description
+
+ Date dateCreated
+ Date lastUpdated
+
+ @Transient
+ String pass = "pass"
+
+ static constraints = {
+ projectId blank: true
+ description nullable: true
+ name blank: false
+ actualHours nullable: true
+ startDate nullable: true
+ completionDate nullable: true
+ }
+
+ def beforeSave = {
+ println "Task before save: $taskId"
+ }
+
+ def afterSave = {
+ println "Task after save: $taskId"
+ }
+
+ def beforeDelete = {
+ println "Task before delete: $taskId"
+ }
+
+ def afterDelete = {
+ println "Task after delete: $taskId"
+ }
+
+
+ public String toString ( ) {
+ return "Task{" +
+ "taskId='" + taskId + '\'' +
+ ", projectId='" + projectId + '\'' +
+ ", name='" + name + '\'' +
+ ", startDate=" + startDate +
+ ", completionDate=" + completionDate +
+ ", estimatedHours=" + estimatedHours +
+ ", actualHours=" + actualHours +
+ ", description='" + description + '\'' +
+ ", dateCreated=" + dateCreated +
+ ", lastUpdated=" + lastUpdated +
+ ", pass='" + pass + '\'' +
+ '}' ;
+ }}
54 grails-app/views/error.gsp
@@ -0,0 +1,54 @@
+<html>
+ <head>
+ <title>Grails Runtime Exception</title>
+ <style type="text/css">
+ .message {
+ border: 1px solid black;
+ padding: 5px;
+ background-color:#E9E9E9;
+ }
+ .stack {
+ border: 1px solid black;
+ padding: 5px;
+ overflow:auto;
+ height: 300px;
+ }
+ .snippet {
+ padding: 5px;
+ background-color:white;
+ border:1px solid black;
+ margin:3px;
+ font-family:courier;
+ }
+ </style>
+ </head>
+
+ <body>
+ <h1>Grails Runtime Exception</h1>
+ <h2>Error Details</h2>
+
+ <div class="message">
+ <strong>Error ${request.'javax.servlet.error.status_code'}:</strong> ${request.'javax.servlet.error.message'.encodeAsHTML()}<br/>
+ <strong>Servlet:</strong> ${request.'javax.servlet.error.servlet_name'}<br/>
+ <strong>URI:</strong> ${request.'javax.servlet.error.request_uri'}<br/>
+ <g:if test="${exception}">
+ <strong>Exception Message:</strong> ${exception.message?.encodeAsHTML()} <br />
+ <strong>Caused by:</strong> ${exception.cause?.message?.encodeAsHTML()} <br />
+ <strong>Class:</strong> ${exception.className} <br />
+ <strong>At Line:</strong> [${exception.lineNumber}] <br />
+ <strong>Code Snippet:</strong><br />
+ <div class="snippet">
+ <g:each var="cs" in="${exception.codeSnippet}">
+ ${cs?.encodeAsHTML()}<br />
+ </g:each>
+ </div>
+ </g:if>
+ </div>
+ <g:if test="${exception}">
+ <h2>Stack Trace</h2>
+ <div class="stack">
+ <pre><g:each in="${exception.stackTraceLines}">${it.encodeAsHTML()}<br/></g:each></pre>
+ </div>
+ </g:if>
+ </body>
+</html>
BIN  grails-gorm-mongodb-0.1.zip
Binary file not shown
BIN  lib/hibernate-core-3.3.1.GA.jar
Binary file not shown
BIN  lib/mongo-1.4.jar
Binary file not shown
BIN  lib/morphia-0.93-mod.jar
Binary file not shown
19 plugin.xml
@@ -0,0 +1,19 @@
+<plugin name='gorm-mongodb' version='0.1' grailsVersion='1.3.1 &gt; *'>
+ <author>Juri Kuehn</author>
+ <authorEmail>juri.kuehn at gmail.com</authorEmail>
+ <title>Grails MongoDB plugin</title>
+ <description>GORM Layer for the superfast, highly scalable, schemafree, document oriented database MongoDB</description>
+ <documentation>http://grails.org/plugin/gorm-mongodb</documentation>
+ <resources>
+ <resource>BuildConfig</resource>
+ <resource>Config</resource>
+ <resource>DataSource</resource>
+ <resource>UrlMappings</resource>
+ <resource>org.acme.Contact</resource>
+ <resource>org.acme.NotMongoDB</resource>
+ <resource>org.acme.Project</resource>
+ <resource>org.acme.Task</resource>
+ </resources>
+ <dependencies />
+ <behavior />
+</plugin>
39 scripts/CreateMongodbClass.groovy
@@ -0,0 +1,39 @@
+import grails.util.GrailsNameUtils
+import org.springframework.core.io.FileSystemResource
+
+/*
+* Copyright 2004-2005 the original author or authors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/**
+ * Gant script that creates a Grails domain class
+ *
+ * @author Graeme Rocher
+ *
+ * @since 0.4
+ */
+
+includeTargets << grailsScript("_GrailsInit")
+includeTargets << grailsScript("_GrailsCreateArtifacts")
+
+target ('default': "Creates a new MongoDB mapped class") {
+ depends(checkVersion, parseArguments)
+
+ promptForName(type: "MongoDB class")
+
+ def name = argsMap["params"][0]
+ createArtifact(name: name, suffix: "", type: "MongoDBClass", path: "grails-app/mongo")
+ createIntegrationTest(name: name, suffix: "")
+}
73 scripts/GenerateAllMongodb.groovy
@@ -0,0 +1,73 @@
+import grails.util.GrailsNameUtils
+import org.codehaus.groovy.grails.scaffolding.DefaultGrailsTemplateGenerator
+
+/*
+* Copyright 2004-2005 the original author or authors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/**
+ * Gant script that generates a CRUD controller and matching views for a given domain class
+ *
+ * @author Graeme Rocher
+ *
+ * @since 0.4
+ */
+
+includeTargets << grailsScript("_GrailsCreateArtifacts")
+includeTargets << grailsScript("_GrailsGenerate")
+
+generateViews = true
+generateController = true
+
+target ('default': "Generates a CRUD interface (controller + views) for a domain class") {
+ depends( checkVersion, parseArguments, packageApp )
+ promptForName(type: "Domain Class")
+
+ try {
+ generateForName = argsMap["params"][0]
+ generateForOneMongoDb()
+ }
+ catch(Exception e) {
+ logError("Error running generate-all", e)
+ exit(1)
+ }
+}
+
+target(generateForOneMongoDb: "Generates controllers and views for only one mongodb domain class.") {
+ depends(loadApp)
+
+ def name = generateForName
+ name = name.indexOf('.') > -1 ? name : GrailsNameUtils.getClassNameRepresentation(name)
+ def domainClass = grailsApp.getMongoDomainClass(name)
+
+ if(domainClass) {
+ def templateGenerator = new DefaultGrailsTemplateGenerator(classLoader)
+
+ event("StatusUpdate", ["Generating views for domain class ${domainClass.fullName}"])
+ templateGenerator.generateViews(domainClass, basedir)
+ event("GenerateViewsEnd", [domainClass.fullName])
+ event("StatusUpdate", ["Generating controller for domain class ${domainClass.fullName}"])
+ templateGenerator.generateController(domainClass, basedir)
+ createUnitTest(name: domainClass.fullName, suffix: "Controller", superClass: "ControllerUnitTestCase")
+ event("GenerateControllerEnd", [domainClass.fullName])
+
+// generateForDomainClass(domainClass)
+ event("StatusFinal", ["Finished generation for domain class ${domainClass.fullName}"])
+ }
+ else {
+ event("StatusFinal", ["No domain class found for name ${name}. Please try again and enter a valid domain class name"])
+ }
+}
+
10 scripts/_Install.groovy
@@ -0,0 +1,10 @@
+//
+// This script is executed by Grails after plugin was installed to project.
+// This script is a Gant script so you can use all special variables provided
+// by Gant (such as 'baseDir' which points on project base dir). You can
+// use 'ant' to access a global instance of AntBuilder
+//
+// For example you can create directory under project tree:
+//
+// ant.mkdir(dir:"${basedir}/grails-app/jobs")
+//
5 scripts/_Uninstall.groovy
@@ -0,0 +1,5 @@
+//
+// This script is executed by Grails when the plugin is uninstalled from project.
+// Use this script if you intend to do any additional clean-up on uninstall, but
+// beware of messing up SVN directories!
+//
10 scripts/_Upgrade.groovy
@@ -0,0 +1,10 @@
+//
+// This script is executed by Grails during application upgrade ('grails upgrade'
+// command). This script is a Gant script so you can use all special variables
+// provided by Gant (such as 'baseDir' which points on project base dir). You can
+// use 'ant' to access a global instance of AntBuilder
+//
+// For example you can create directory under project tree:
+//
+// ant.mkdir(dir:"${basedir}/grails-app/jobs")
+//
479 src/groovy/grails/plugins/mongodb/MongoPluginSupport.groovy
@@ -0,0 +1,479 @@
+package grails.plugins.mongodb
+
+import org.codehaus.groovy.grails.commons.GrailsApplication
+import org.springframework.context.ApplicationContext
+import org.codehaus.groovy.grails.support.SoftThreadLocalMap
+import com.mongodb.Mongo
+import org.codehaus.groovy.grails.commons.GrailsDomainClassProperty
+import org.codehaus.groovy.grails.plugins.DomainClassPluginSupport
+import org.springframework.beans.BeanUtils
+import org.codehaus.groovy.grails.web.binding.DataBindingUtils
+import org.codehaus.groovy.grails.web.binding.DataBindingLazyMetaPropertyMap
+import org.springframework.validation.BeanPropertyBindingResult
+import org.springframework.validation.Errors
+import org.codehaus.groovy.grails.web.context.ServletContextHolder
+import com.google.code.morphia.Morphia
+import com.google.code.morphia.Datastore
+import com.google.code.morphia.query.Query
+import java.beans.Introspector
+
+/**
+ * Author: Juri Kuehn
+ * Date: 30.05.2010
+ */
+class MongoPluginSupport {
+
+ static final PROPERTY_INSTANCE_MAP = new SoftThreadLocalMap()
+ public static final String MORPHIA_ATTRIBUTE = "morphiaDS"
+
+ public static final String EVENT_BEFORE_SAVE = "beforeSave"
+ public static final String EVENT_AFTER_SAVE = "afterSave"
+ public static final String EVENT_BEFORE_DELETE = "beforeDelete"
+ public static final String EVENT_AFTER_DELETE = "afterDelete"
+
+ // for dynamic finders
+ static final COMPARATORS = Collections.unmodifiableList([
+ "IsNull",
+ "IsNotNull",
+ "LessThan",
+ "LessThanEquals",
+ "GreaterThan",
+ "GreaterThanEquals",
+ "NotEqual",
+ "Size",
+ "All",
+ "InList",
+ "NotInList",
+ "NotBetween",
+ "Between" ])
+ static final COMPARATORS_RE = COMPARATORS.join("|")
+ static final DYNAMIC_FINDER_RE = /(\w+?)(${COMPARATORS_RE})?((And)(\w+?)(${COMPARATORS_RE})?)?/
+// static final DYNAMIC_FINDER_RE = /(\w+?)(${COMPARATORS_RE})?((And|Or)(\w+?)(${COMPARATORS_RE})?)?/
+
+ static enhanceDomainClass(MongoDomainClass domainClass, GrailsApplication application, ApplicationContext ctx) {
+ addStaticMethods(application, domainClass, ctx)
+ addInstanceMethods(application, domainClass, ctx)
+ addDynamicFinderSupport(application, domainClass, ctx)
+
+ addValidationMethods(application, domainClass, ctx)
+ }
+
+ private static addInstanceMethods(GrailsApplication application, MongoDomainClass dc, ApplicationContext ctx) {
+ def metaClass = dc.metaClass
+ def domainClass = dc
+
+ metaClass.save = {->
+ save(null)
+ }
+
+ metaClass.save = {Map args = [:] ->
+ // todo: add support for failOnError:true in grails 1.2 (GRAILS-4343)
+ if (validate()) {
+ // only process if beforeSave didnt return false
+ if (!triggerEvent(EVENT_BEFORE_SAVE, delegate)) {
+ autoTimeStamp(application, delegate)
+ if (getDatastoreForOperation(application).save(delegate)) {
+ triggerEvent(EVENT_AFTER_SAVE, delegate) // call only on successful save
+ }
+ }
+
+ return delegate
+ }
+
+ return null
+ }
+
+ metaClass.delete = { ->
+ triggerEvent(EVENT_BEFORE_DELETE, delegate)
+ getDatastoreForOperation(application).delete(delegate)
+ triggerEvent(EVENT_AFTER_DELETE, delegate)
+ }
+
+ metaClass.delete = { Map dontcare -> // in case flush:true is passed in
+ delete()
+ }
+ }
+
+ private static addStaticMethods(GrailsApplication application, MongoDomainClass dc, ApplicationContext ctx) {
+ def final metaClass = dc.metaClass
+ def final domainClass = dc
+
+ metaClass.static.get = { Serializable docId ->
+ try {
+ return getDatastoreForOperation(application).get(domainClass.clazz, docId.toString())
+ } catch (Exception e) {
+ // fall through to return null
+ }
+ return null
+ }
+
+ // Foo.exists(1)
+ metaClass.static.exists = {Serializable docId ->
+ get(docId) != null
+ }
+
+ // cannot use Serializeable here, because Map implements it too
+ metaClass.static.delete = { String docId ->
+ getDatastoreForOperation(application).delete(domainClass.clazz, docId.toString())
+ }
+
+ metaClass.static.delete = { Map filter ->
+ Datastore ds = getDatastoreForOperation(application)
+ Query query = ds.find(domainClass.clazz)
+
+ filter.each { k, v ->
+ query.filter(k.toString(), v)
+ }
+
+ ds.delete(query)
+ }
+
+ metaClass.static.count = {
+ return (getDatastoreForOperation(application).getCount(domainClass.clazz) as Long)
+ }
+
+ /**
+ * return only the first object, if any
+ */
+ metaClass.static.find = { Map filter = [:], Map queryParams = [:] ->
+ queryParams['max'] = 1
+
+ def res = findAll(filter, queryParams).toList()
+ return res?res[0]:null
+ }
+
+ metaClass.static.findAll = { Map filter = [:], Map queryParams = [:] ->
+ Query query = getDatastoreForOperation(application).find(domainClass.clazz)
+ configureQuery query, queryParams
+
+ filter.each { k, v ->
+ query.filter(k.toString(), v)
+ }
+
+ return query.fetch()
+ }
+
+ metaClass.static.list = { Map queryParams = [:] ->
+ findAll([:], queryParams)
+ }
+
+ metaClass.static.getDatastore = {
+ getDatastoreForOperation(application)
+ }
+
+ metaClass.static.getDatastore = {
+ getDatastoreForOperation(application)
+ }
+ }
+
+ public static void configureQuery(Query query, Map queryParams) {
+ // @todo be more graceful
+ def sort = queryParams.remove('sort')?.toString()
+ def limit = (int)(queryParams.remove('max') ?: 25)
+ def offset = (int)(queryParams.remove('offset') ?: 0)
+
+ if (sort) query.order(sort)
+ query.limit(limit)
+ query.offset(offset)
+ }
+
+ private static addDynamicFinderSupport(GrailsApplication application, MongoDomainClass dc, ApplicationContext ctx) {
+ def metaClass = dc.metaClass
+ def domainClass = dc
+
+ // This adds basic dynamic finder support.
+ metaClass.static.methodMissing = { method, args ->
+ def m = method =~ /^find(All)?By${DYNAMIC_FINDER_RE}$/
+ if (m) {
+ def fields = []
+ def comparator = m[0][3]
+ // How many arguments do we need to pass for the given
+ // comparator?
+ def numArgs = getArgCountForComparator(comparator)
+
+ fields << [field:Introspector.decapitalize(m[0][2]),
+ args:args[0..<numArgs], // @todo move args out of here, it'll stay for newMethod in memory unused
+ argCount:numArgs,
+ comparator:comparator]
+
+ // Strip out that number of arguments from the ones
+ // we've been passed.
+ args = args[numArgs..<args.size()]
+
+ // If we have a second clause, evaluate it now.
+ def join = m[0][5]
+
+ if (join) {
+ comparator = m[0][7]
+ numArgs = getArgCountForComparator(comparator)
+ fields << [field: Introspector.decapitalize(m[0][6]),
+ args:args[0..<numArgs],
+ argCount:numArgs,
+ comparator:comparator]
+
+ // remove args for second parameter
+ args = args[numArgs..<args.size()]
+ }
+
+ final int expectedMinArgsCount = (int)fields.inject(0) { acc, val -> acc+val.argCount }
+ // cache new behavior
+ def newMethod = { Object[] varArgs ->
+ def localArgs = varArgs ? varArgs[0] : []
+ if (localArgs.size() < expectedMinArgsCount) throw new MissingMethodException(method, delegate, varArgs)
+
+ def filter = [:]
+ def field1ArgCount = fields[0].argCount
+ updateFilter(filter, fields[0].field, fields[0].comparator, localArgs[0..<field1ArgCount])
+ if (fields.size()>1) {
+ updateFilter(filter, fields[1].field, fields[1].comparator, localArgs[field1ArgCount..<(field1ArgCount+fields[1].argCount)])
+ }
+
+ // put options to the map
+ Map queryParams
+ if (localArgs.size() > expectedMinArgsCount && localArgs[expectedMinArgsCount] instanceof Map)
+ queryParams = localArgs[expectedMinArgsCount]
+ else
+ queryParams = [:]
+
+ // return the iterator for this collection
+ return findAll(filter, queryParams)
+ }
+
+ // register new cached behavior on metaclass to speed up next invokation
+ domainClass.metaClass.static."$method" = newMethod
+
+ // Check whether we have any options, such as "sort".
+ def queryParams = [:]
+ if (args) {
+ if(args[0] instanceof Map) {
+ queryParams = args[0]
+ }
+ }
+
+
+ def finalArgs = fields.collect { it.args }.flatten()
+ finalArgs << queryParams
+
+ // invoke new behavior
+ return newMethod(finalArgs)
+
+
+ } else {
+ throw new MissingMethodException(method, delegate, args)
+ }
+ }
+ }
+
+ private static addValidationMethods(GrailsApplication application, MongoDomainClass dc, ApplicationContext ctx) {
+ def metaClass = dc.metaClass
+ def domainClass = dc
+
+ metaClass.static.getConstraints = {->
+ domainClass.constrainedProperties
+ }
+
+ metaClass.getConstraints = {->
+ domainClass.constrainedProperties
+ }
+
+ metaClass.constructor = {Map map ->
+ def instance = ctx.containsBean(domainClass.fullName) ? ctx.getBean(domainClass.fullName) : BeanUtils.instantiateClass(domainClass.clazz)
+ DataBindingUtils.bindObjectToDomainInstance(domainClass, instance, map)
+ DataBindingUtils.assignBidirectionalAssociations(instance, map, domainClass)
+ return instance
+ }
+ metaClass.setProperties = {Object o ->
+ DataBindingUtils.bindObjectToDomainInstance(domainClass, delegate, o)
+ }
+ metaClass.getProperties = {->
+ new DataBindingLazyMetaPropertyMap(delegate)
+ }
+
+ metaClass.hasErrors = {-> delegate.errors?.hasErrors() }
+
+ def get
+ def put
+ try {
+ def rch = application.classLoader.loadClass("org.springframework.web.context.request.RequestContextHolder")
+ get = {
+ def attributes = rch.getRequestAttributes()
+ if (attributes) {
+ return attributes.request.getAttribute(it)
+ } else {
+ return PROPERTY_INSTANCE_MAP.get().get(it)
+ }
+ }
+ put = {key, val ->
+ def attributes = rch.getRequestAttributes()
+ if (attributes) {
+ attributes.request.setAttribute(key, val)
+ } else {
+ PROPERTY_INSTANCE_MAP.get().put(key, val)
+ }
+ }
+ } catch (Throwable e) {
+ get = { PROPERTY_INSTANCE_MAP.get().get(it) }
+ put = {key, val -> PROPERTY_INSTANCE_MAP.get().put(key, val) }
+ }
+
+ metaClass.getErrors = {->
+ def errors
+ def key = "org.codehaus.groovy.grails.ERRORS_${delegate.class.name}_${System.identityHashCode(delegate)}"
+ errors = get(key)
+ if (!errors) {
+ errors = new BeanPropertyBindingResult(delegate, delegate.getClass().getName())
+ put key, errors
+ }
+ errors
+ }
+
+ metaClass.setErrors = {Errors errors ->
+ def key = "org.codehaus.groovy.grails.ERRORS_${delegate.class.name}_${System.identityHashCode(delegate)}"
+ put key, errors
+ }
+
+ metaClass.clearErrors = {->
+ delegate.setErrors(new BeanPropertyBindingResult(delegate, delegate.getClass().getName()))
+ }
+
+ if (!metaClass.respondsTo(dc.getReference(), "validate")) {
+ metaClass.validate = {->
+ DomainClassPluginSupport.validateInstance(delegate, ctx)
+ }
+ }
+ }
+
+ private static Object autoTimeStamp(GrailsApplication application, Object domain) {
+
+ MongoDomainClass dc = (MongoDomainClass) application.getArtefact(MongoDomainClassArtefactHandler.TYPE, domain.getClass().getName())
+ if (dc) {
+ def metaClass = dc.metaClass
+
+ MetaProperty property = metaClass.hasProperty(dc, GrailsDomainClassProperty.DATE_CREATED)
+ def time = System.currentTimeMillis()
+ if (property && domain[property.name] == null) {
+ def now = property.getType().newInstance([time] as Object[])
+ domain[property.name] = now
+ }
+
+ property = metaClass.hasProperty(dc, GrailsDomainClassProperty.LAST_UPDATED)
+ if (property) {
+ def now = property.getType().newInstance([time] as Object[])
+ domain[property.name] = now
+ }
+ }
+
+ return domain
+ }
+
+ private static String getDocumentId(MongoDomainClass dc, Object domain) {
+ def id = dc.getIdentifier()
+ if (id) {
+ domain[id.name]
+ }
+ }
+
+ private static Datastore getDatastoreForOperation(GrailsApplication application) {
+ Datastore morphiaDS = getDatastore(application)
+ if (!morphiaDS) throw new Exception("Morphia instance could not be set up. Plugin did not initialize correctly")
+ morphiaDS
+ }
+
+ public static Datastore getDatastore(GrailsApplication application, forceReload = false) {
+ def servletCtx = ServletContextHolder.getServletContext()
+ if (servletCtx == null) {
+ println "Grails has not finished loading, cannot register MongoDB Morphia Datastore"
+ return
+ }
+ Datastore morphiaDS = null
+ if (!forceReload) morphiaDS = (Datastore)servletCtx.getAttribute(MORPHIA_ATTRIBUTE)
+ if (morphiaDS) return morphiaDS
+
+ // no datastore initialized yet or reload is requested, do this now
+
+ // get configureation
+ def ds = application.config.mongodb
+ String host = ds?.host ?: "localhost"
+ Integer port = ds?.port ?: 27017
+ String database = ds?.database ?: application.metadata["app.name"]
+ String username = ds?.username ?: "" // not used yet
+ String password = ds?.password ?: "" // not used yet
+
+ // create mongo instance and datastore
+ Mongo db = new Mongo(host, port)
+ def morphia = new Morphia()
+
+ application.MongoDomainClasses.each { dc ->
+ println "adding domain " + dc.getClazz() + " to morphia"
+ morphia.map(dc.getClazz())
+ }
+
+ morphiaDS = morphia.createDatastore(db, database)
+ servletCtx.setAttribute(MORPHIA_ATTRIBUTE, morphiaDS)
+ return morphiaDS
+ }
+
+ /**
+ * call event on domain class
+ * if event closure returns a boolean false this method
+ * returns true, false otherwise
+ *
+ * @param event
+ * @param entity
+ * @return
+ */
+ private static boolean triggerEvent(String event, entity) {
+ def result = false
+ if (entity?.metaClass) {
+ if(entity.metaClass.hasProperty(entity, event)) {
+ def callable = entity."$event"
+ if(callable instanceof Closure) {
+ callable.resolveStrategy = Closure.DELEGATE_FIRST
+ callable.delegate = entity
+ result = callable.call()
+ if (result instanceof Boolean) result = !result
+ else {
+ result = false
+ }
+ }
+ }
+ }
+ return result
+ }
+
+ public static updateFilter(Map filter, String field, String comparator, values) {
+ // default to equals
+ switch(comparator) {
+ case "IsNull": filter["$field exists"] = 0; break
+ case "IsNotNull": filter["$field exists"] = 1; break
+ case "Size": filter["$field size"] = values[0]; break
+ case "All": filter["$field all"] = values[0]; break
+ case "Between":
+ filter["$field >="] = values[0];
+ filter["$field <="] = values[1]; break
+ case "NotBetween":
+ filter["$field <"] = values[0];
+ filter["$field >"] = values[1]; break
+ case "InList": filter["$field in"] = values[0]; break
+ case "NotInList": filter["$field nin"] = values[0]; break
+ case "LessThan": filter["$field <"] = values[0]; break
+ case "LessThanEquals": filter["$field <="] = values[0]; break
+ case "GreaterThan": filter["$field >"] = values[0]; break
+ case "GreaterThanEquals": filter["$field >="] = values[0]; break
+ case "NotEqual": filter["$field !="] = values[0]; break
+ default: filter["$field ="] = values[0]; break // equal
+ }
+ }
+
+ private static int getArgCountForComparator(String comparator) {
+ if (comparator == "Between" || comparator == "NotBetween") {
+ return 2
+ }
+ else if (["IsNull", "IsNotNull"].contains(comparator)) {
+ return 0
+ }
+ else {
+ return 1
+ }
+ }
+}
228 src/java/grails/plugins/mongodb/MongoDomainClass.java
@@ -0,0 +1,228 @@
+package grails.plugins.mongodb;
+
+import com.google.code.morphia.annotations.Entity;
+import com.google.code.morphia.annotations.Id;
+import com.google.code.morphia.mapping.MappingException;
+import com.google.code.morphia.utils.ReflectionUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.codehaus.groovy.grails.commons.AbstractGrailsClass;
+import org.codehaus.groovy.grails.commons.GrailsDomainClass;
+import org.codehaus.groovy.grails.commons.GrailsDomainClassProperty;
+import org.codehaus.groovy.grails.commons.GrailsDomainConfigurationUtil;
+import org.codehaus.groovy.grails.exceptions.GrailsDomainException;
+import org.codehaus.groovy.grails.validation.ConstrainedProperty;
+import org.springframework.beans.BeanUtils;
+import org.springframework.validation.Validator;
+
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Field;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Author: Juri Kuehn
+ * Date: 30.05.2010
+ */
+public class MongoDomainClass extends AbstractGrailsClass implements GrailsDomainClass {
+ private static final Log log = LogFactory.getLog(MongoDomainClass.class);
+
+ Map<String, GrailsDomainClassProperty> propertyMap = new HashMap<String, GrailsDomainClassProperty>();
+ private GrailsDomainClassProperty[] propertiesArray;
+ private GrailsDomainClassProperty[] persistentPropertyArray;
+
+ private Map<String, ConstrainedProperty> constraints = new HashMap<String, ConstrainedProperty>();
+ private Validator validator;
+
+ private MongoDomainClassProperty identifier;
+ private MongoDomainClassProperty version = null; // no versioning
+
+ public MongoDomainClass(Class artefactClass) {
+ super(artefactClass, "");
+
+ Entity entityAnnotation = (Entity) artefactClass.getAnnotation(Entity.class);
+ if (entityAnnotation == null) {
+ throw new GrailsDomainException("Class [" + artefactClass.getName() + "] is not annotated with com.google.code.morphia.annotations.Entity!");
+ }
+
+ evaluateClassProperties(artefactClass);
+
+ // process the constraints
+ try {
+ this.constraints = GrailsDomainConfigurationUtil.evaluateConstraints(getClazz(), this.persistentPropertyArray);
+ } catch (Exception e) {
+ log.error("Error reading class [" + getClazz() + "] constraints: " + e.getMessage(), e);
+ }
+ }
+
+ private void evaluateClassProperties(Class artefactClass) {
+ Map<String, GrailsDomainClassProperty> persistentProperties = new HashMap<String, GrailsDomainClassProperty>();
+
+ Field[] classFields = ReflectionUtils.getDeclaredAndInheritedFields(artefactClass, true);
+ for (Field field : classFields) {
+ PropertyDescriptor descriptor = null;
+ try {
+ descriptor = new PropertyDescriptor(field.getName(), artefactClass);
+ } catch (IntrospectionException e) {
+ log.error("Could not create PropertyDescriptor for class " + artefactClass.getName() + " field " + field.getName());
+ continue;
+ }
+ if (GrailsDomainConfigurationUtil.isNotConfigurational(descriptor)) {
+ final MongoDomainClassProperty property = new MongoDomainClassProperty(this, field, descriptor);
+
+ // property.isAnnotatedWith(Id.class) does not recognize inherited field and their annotations
+ if (field.getAnnotation(Id.class) != null) {
+ this.identifier = property;
+ } else {
+ propertyMap.put(descriptor.getName(), property);
+ if (property.isPersistent()) {
+ persistentProperties.put(descriptor.getName(), property);
+ }
+ }
+ }
+ }
+
+ // if we don't have an annotated identifier
+ // @todo try to find fields with the simple names and use them...
+ if (this.identifier == null) {
+ throw new MappingException("You need to set the morphia Id annotation upon your id field on class " + getClazz().getName());
+ }
+
+ if (this.identifier.getType() != String.class) {
+ throw new GrailsDomainException("Identity property in domain class [" + getFullName() + "] must be a String.");
+ }
+
+ this.identifier.setIdentity(true);
+
+ // convert to arrays for optimization - as used by grails
+ propertiesArray = propertyMap.values().toArray(new GrailsDomainClassProperty[propertyMap.size()]);
+ persistentPropertyArray = persistentProperties.values().to