| [ |
| { |
| "bintrayPackage": { |
| "name": "actuator-ui", |
| "repo": "plugins", |
| "owner": "dmahapatro", |
| "desc": "Grails actuator-ui plugin", |
| "labels": [ |
| "spring-boot-actuator", |
| "health-check" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/dmahapatro/grails-actuator-ui/issues", |
| "latestVersion": "1.1", |
| "updated": "2016-09-04T04:00:40.855Z", |
| "systemIds": [ |
| "org.grails.plugins:actuator-ui" |
| ], |
| "vcsUrl": "https://github.com/dmahapatro/grails-actuator-ui" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<div id=\"preamble\">\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p><span class=\"image\"><a class=\"image\" href=\"https://travis-ci.org/dmahapatro/grails-actuator-ui\"><img src=\"https://travis-ci.org/dmahapatro/grails-actuator-ui.svg?branch=master\" alt=\"Build Status\"></a></span>\n<span class=\"image\"><a class=\"image\" href=\"https://bintray.com/dmahapatro/plugins/actuator-ui/_latestVersion\"><img src=\"https://api.bintray.com/packages/dmahapatro/plugins/actuator-ui/images/download.svg\" alt=\"download\"></a></span></p>\n</div>\n<div class=\"paragraph\">\n<p><a href=\"http://docs.spring.io/autorepo/docs/spring-boot/current/reference/htmlsingle/#production-ready\">Spring Actuator</a> is a tool which monitors application’s <code>health</code>, <code>metrics</code> and lots of other metadata information about the application.\nThis plugin projects those information in a UI which makes it very user friendly to know the status of the application.</p>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_demo\">Demo</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p><a href=\"https://www.youtube.com/watch?v=huhC1LV5I8Q\">DEMO</a></p>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_prerequisites\">Prerequisites</h2>\n<div class=\"sectionbody\">\n<div class=\"ulist\">\n<ul>\n<li>\n<p>For Grails 3.0.* version 0.2 can be used</p>\n</li>\n<li>\n<p>For Grails 3.1.* version 1.0 should be used</p>\n</li>\n</ul>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_configuration\">Configuration</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p><code>build.gradle</code></p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-groovy\" data-lang=\"groovy\">repositories {\n maven {\n url \"http://dl.bintray.com/dmahapatro/plugins\"\n }\n}\n\ndependencies {\n ...\n compile \"org.grails.plugins:actuator-ui:1.1\"\n}</code></pre>\n</div>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_how_to\">How To</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>To access the actuator endpoints you can simply hit <code>/actuator/dashboard</code> at root context.</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-groovy\" data-lang=\"groovy\">http://localhost:8080/sample/actuator/dashboard</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>where <code>/sample</code> is the root context of the application. For a base Grails app where root context is <code>/</code>, the url will be</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-groovy\" data-lang=\"groovy\">http://localhost:8080/actuator/dashboard</code></pre>\n</div>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_secured\">Secured</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Actuator UI is targeted for Admins and normal users. Taking ROLE into consideration this plugin can be easily integrated with spring security core plugin. For example with a mapping like the below in <code>application.yml</code> would secure <code>/actuator/dashboard</code> endpoint.</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-yaml\" data-lang=\"yaml\">grails:\n plugin:\n springsecurity:\n userLookup:\n userDomainClassName: auth.User\n authorityJoinClassName: auth.UserRole\n authority:\n className: auth.Role\n controllerAnnotations:\n staticRules:\n - pattern: '/actuatordashboard/**'\n access: ['hasRole(\"ROLE_ADMIN\")']\n - pattern: '/actuator/**'\n access: ['hasRole(\"ROLE_ADMIN\")']</code></pre>\n</div>\n</div>\n<div class=\"sect2\">\n<h3 id=\"_avatar_support\">Avatar support</h3>\n<div class=\"paragraph\">\n<p>Actuator-ui ships with Gravatar plugin. It will render a gravatar image under the following circumstances:</p>\n</div>\n<div class=\"ulist\">\n<ul>\n<li>\n<p>Spring Security is installed</p>\n</li>\n<li>\n<p>The user is logged in</p>\n</li>\n</ul>\n</div>\n<div class=\"paragraph\">\n<p>Gravatar is enabled for actuator-ui by default. To disable Gravatar in actuator-ui, you should add the following to application’s <code>application.yml</code>.</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-yaml\" data-lang=\"yaml\">grails:\n plugin:\n actuator:\n gravatar:\n disabled: true</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>To modify the default rating and gravatar fallback image please refer to the <a href=\"https://github.com/rpalcolea/grails-gravatar\">Gravatar Plugin Documentation</a></p>\n</div>\n<div class=\"admonitionblock note\">\n<table>\n<tr>\n<td class=\"icon\">\n<div class=\"title\">Note</div>\n</td>\n<td class=\"content\">\n<strong>When <code>spring security</code> and <code>gravatar</code> are enabled, the plugin grabs the username to look for the gravatar. In this case the username should be a valid email registered in Gravatar otherwise it will fallback to the default gravatar image.</strong>\n</td>\n</tr>\n</table>\n</div>\n</div>\n<div class=\"sect2\">\n<h3 id=\"_sample\">Sample</h3>\n<div class=\"paragraph\">\n<p>Sample apps with Spring Security Core integration:</p>\n</div>\n<div class=\"ulist\">\n<ul>\n<li>\n<p>Run <a href=\"https://github.com/dmahapatro/grails-actuator-ui/tree/master/actuator-ui-app\">actuator-ui-app</a> available as sub project in this plugin repository.</p>\n</li>\n<li>\n<p>Run <a href=\"https://bitbucket.org/bgoetzmann/odelia-gina-actuator/overview\">sample app</a> created by Bertrand Goetzmann.</p>\n</li>\n</ul>\n</div>\n</div>\n<div class=\"sect2\">\n<h3 id=\"_v1_1\">v1.1</h3>\n<div class=\"ulist\">\n<ul>\n<li>\n<p>Gravatar support added for logged in user.</p>\n</li>\n</ul>\n</div>\n</div>\n<div class=\"sect2\">\n<h3 id=\"_v1_0\">v1.0</h3>\n<div class=\"ulist\">\n<ul>\n<li>\n<p>Grails upgraded to v3.1.10</p>\n</li>\n</ul>\n</div>\n</div>\n<div class=\"sect2\">\n<h3 id=\"_v0_2\">v0.2</h3>\n<div class=\"ulist\">\n<ul>\n<li>\n<p>Integrated console plugin. A link is provided in the header bar to open console via console plugin. Appropriate version of console plugin has to be installed in the app which uses this plugin. If console plugin is added as a dependency then actuator dashboard should show console link next to the logged in user in top right corner.</p>\n</li>\n<li>\n<p>Items are searchable now. Search for a particular bean, mapping, calls etc.</p>\n</li>\n<li>\n<p>Paginated list of items.</p>\n</li>\n</ul>\n</div>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_todo\">TODO</h2>\n<div class=\"sectionbody\">\n<div class=\"ulist\">\n<ul>\n<li>\n<p>Add charts on Garbage Collection metrics.</p>\n</li>\n<li>\n<p>Add support for custom address and port.</p>\n</li>\n</ul>\n</div>\n</div>\n</div>" |
| }, |
| { |
| "displayName": "airbrake", |
| "bintrayPackage": { |
| "name": "airbrake-grails", |
| "repo": "plugins", |
| "owner": "bostanio", |
| "desc": "Airbrake Client for Grails", |
| "labels": [ |
| "airbrake" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/cavneb/airbrake-grails/issues", |
| "latestVersion": "1.0.0.RC1", |
| "updated": "2016-03-31T13:31:55.050Z", |
| "systemIds": [ |
| "org.grails.plugins:airbrake-grails" |
| ], |
| "vcsUrl": "https://github.com/cavneb/airbrake-grails" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Airbrake Plugin for Grails</h1>\n<p>This is the notifier plugin for integrating grails apps with <a href=\"http://airbrake.io\">Airbrake</a>.</p>\n<p>When an uncaught exception occurs, Airbrake will POST the relevant data to the Airbrake server specified in your environment.</p>\n<h2>Installation & Configuration</h2>\n<p>Add the following to your <code>BuildConfig.groovy</code></p>\n<pre><code>compile ":airbrake:0.9.4"\n</code></pre>\n<p>Once the plugin is installed, you need to provide your Api Key in <code>Config.groovy</code> file:</p>\n<pre><code class=\"language-groovy\">grails.plugins.airbrake.apiKey = 'YOUR_API_KEY'\n</code></pre>\n<h2>Usage</h2>\n<p>Once you have installed and configured the plugin there is nothing else to do. Uncaught exceptions will be logged by log4j and those errors will be reported to Airbrake. However, the plugin also exposes a few other ways to send errors to airbrake.</p>\n<h3>Logging Errors with Exceptions</h3>\n<p>Manually logging messages at the error level and including an Exception triggers an error notification to airbrake:</p>\n<pre><code class=\"language-groovy\">class SomeController\n\tdef someAction() {\n\t\ttry {\n\t\t\tsomethingThatThrowsAnException()\n\t\t} catch(e) {\n\t\t\tlog.error('An error occured', e)\n\t\t}\n\t}\n</code></pre>\n<p>(See the section below on configuring the plugin to including errors without exceptions.)</p>\n<h3>AirbakeService</h3>\n<p>The plugin also exposes an <code>airbrakeService</code> which can be dependency injected into your Grails classes. The service allows you to send error notifications directly to Airbrake without logging anything to log4j. It has a <code>notify</code> method that takes a <code>Throwable</code> parameter and an optional Map of arguemnts. The next example shows both in use:</p>\n<pre><code class=\"language-groovy\">class SomeController\n\tdef airbrakeService\n\t\n\tdef someAction() {\n\t\ttry {\n\t\t\tsomethingThatThrowsAnException()\n\t\t} catch(e) {\n\t\t\tairbrakeService.notify(e, [errorMessage: 'An error occurred'])\n\t\t}\n\t}\n\n\tdef anotherAction() {\n\t\tif (somethingWentWrong()) {\n\t\t\tairbrakeService.notify(null, [errorMessage: 'Something went wrong'])\n\t\t}\n\t}\n</code></pre>\n<h2>Advanced Configuration</h2>\n<p>The Api Key is the minimum requirement to report errors to Airbrake. However, the plugin supports several other configuration options. The full list of configuration options is:</p>\n<pre><code class=\"language-groovy\">grails.plugins.airbrake.apiKey\ngrails.plugins.airbrake.enabled\ngrails.plugins.airbrake.env\ngrails.plugins.airbrake.includeEventsWithoutExceptions\ngrails.plugins.airbrake.paramsFilteredKeys\ngrails.plugins.airbrake.sessionFilteredKeys\ngrails.plugins.airbrake.cgiDataFilteredKeys\ngrails.plugins.airbrake.host\ngrails.plugins.airbrake.port\ngrails.plugins.airbrake.secure\ngrails.plugins.airbrake.async\ngrails.plugins.airbrake.asyncThreadPoolSize\ngrails.plugins.airbrake.stackTraceFilterer\ngrails.plugins.airbrake.excludes\n</code></pre>\n<h3>Enabling/Disabling Notifications</h3>\n<p>By default all errors are sent to Airbrake. However, you can disable error notifications (essentially disabling the plugin) by setting <code>grails.plugins.airbrake.enabled = false</code>. For example to disable error notificaitons in development and test environments you might have the following in <code>Config.groovy</code>:</p>\n<pre><code class=\"language-groovy\">grails.plugins.airbrake.apiKey = 'YOUR_API_KEY'\nenvironments {\n\tdevelopment {\n\t\tgrails.plugins.airbrake.enabled = false\n\t}\n\ttest {\n\t\tgrails.plugins.airbrake.enabled = false\n\t}\n</code></pre>\n<h4>Disabling Notifications by Exception Type</h4>\n<p>For example, to disable notifications caused by <code>IllegalArgumentException</code> and <code>IllegalStateException</code>, configure</p>\n<pre><code class=\"language-groovy\">grails.plugins.airbrake.excludes = ['java.lang.IllegalArgumentException', 'java.lang.IllegalStateException']\n</code></pre>\n<p>each entry in the list will be converted to a <code>Pattern</code> and matched against the exception class name, so the following\nwould also exclude these two exceptions:</p>\n<pre><code class=\"language-groovy\">grails.plugins.airbrake.excludes = ['java.lang.Illegal.*Exception']\n</code></pre>\n<h4>Runtime Enabling/Disabling</h4>\n<p>If you wish to enable/disable notifications at runtime you have a couple of options</p>\n<ul>\n<li>Call the service method <code>airbrakeService.setEnabled(boolean enabled)</code></li>\n<li>Invoke the <code>setEnabled</code> action of <code>AirbrakeTestController</code>. This action expects a single parameter either <code>enabled=true</code> or <code>enabled=false</code></li>\n</ul>\n<h3>Setting the Environment</h3>\n<p>By default, the environment name used in Airbrake will match that of the current Grails environment. To change this default, set the env property:</p>\n<pre><code class=\"language-groovy\">grails.plugins.airbrake.env = grails.util.Environment.current.name[0..0] // Airbrake env name changed from default value of Development/Test/Production to D/T/P\n</code></pre>\n<h3>Including all events logged at the Error level</h3>\n<p>By default only uncaught errors or errors logged with an exception are reported to Airbrake. It is often convenient to loosen that restriction so that all messages logged at the <code>Error</code> level are reported to Airbrake. This often most useful in <code>src/java</code> or <code>src/groovy</code> classes that can more easily have a log4j logger than get accees to the dependency injected <code>airbrakeService</code>.</p>\n<p>With the following line in <code>Config.groovy</code>:</p>\n<pre><code class=\"language-groovy\">grails.plugins.airbrake.includeEventsWithoutExceptions = true\n</code></pre>\n<p>then logged errors get reported to Airbrake:</p>\n<pre><code class=\"language-groovy\">@Log4j\nclass SomeGroovyClass {\n\tdef doSomething() {\n\t\tif (somethingWentWrong()) {\n\t\t\tlog.error('Something went wrong')\n\t\t}\n\t}\n}\n</code></pre>\n<p>Note: It might be reasonable to have this setting true by default but for backwards compatibility with previous versions of te plugin the default is false.</p>\n<h3>Filtering Parameters sent to Airbrake</h3>\n<p>To prevent certain parameters from being sent to Airbrake you can configure a list of parameter names to filter out. The configuration settings <code>paramsFilteredKeys</code>, <code>sessionFilteredKeys</code> and <code>cgiFilteredKeys</code> filter the params, session and cgi data sent to Airbrake.\nFor example to prevent any web request parameter named 'password' from being included in the notification to Airbrake you would use the following configuration:</p>\n<pre><code class=\"language-groovy\">grails.plugins.airbrake.paramsFilteredKeys = ['password']\n</code></pre>\n<p>Each configuration option also supports regular expression matching on the keys. For example the following configuration would prevent all session data from being sent to Airbrake:</p>\n<pre><code class=\"language-groovy\">grails.plugins.airbrake.sessionFilteredKeys = ['.*']\n</code></pre>\n<h3>Custom Airbrake Host, Port and Scheme</h3>\n<p>If you are running the Airbrake server locally (or a clone thereof, e.g. Errbit), you will need to customise the server URL, port, scheme, etc.\nFor example to change the server host and port, add the following configuration parameters:</p>\n<pre><code class=\"language-groovy\">grails.plugins.airbrake.host = 'errbit.example.org'\ngrails.plugins.airbrake.port = 8080\n</code></pre>\n<h3>Adding Custom Data to Error Notifications</h3>\n<h3>Supplying User Data</h3>\n<p>Airbrake allows certain User data to be supplied with the notice. To set the current users data to be included in all notifications use the <code>airbrakeService.addNoticeContext</code> method to set a map of userData.\nThe supported keys are <code>id</code>, <code>name</code>, <code>email</code> and <code>username</code></p>\n<pre><code class=\"language-groovy\">airbrakeService.addNoticeContext(id: '1234', name: 'Bugs Bunny', email: 'bugs@acme.com', username: 'bugs')\n</code></pre>\n<p>In most web apps the simplest way to provide this context is in a Grails filter. For example if you are using <code>SpringSecurity</code> add the following <code>AirbrakeFilter.groovy</code> in <code>grails-app/conf</code></p>\n<pre><code class=\"language-groovy\">class AirbrakeFilters {\n def airbrakeService\n def springSecurityService\n\n def filters = {\n all(uri: '/**') {\n before = {\n def user = springSecurityService.currentUser\n if (user) {\n airbrakeService.addNoticeContext(user: [id: user.id, name: user.name, email: user.email, username: user.username ])\n }\n }\n }\n }\n}\n</code></pre>\n<h2>Synchronous/Asynchronous notifications</h2>\n<p>By default, notifications are sent to Airbrake asynchronously using a thread-pool of size 5. To change the size of this thread\npool set the following config parameter:</p>\n<pre><code class=\"language-groovy\">// double the size of the pool\ngrails.plugins.airbrake.asyncThreadPoolSize = 10\n</code></pre>\n<p>To have the notifications sent synchronously, set the async parameter to false:</p>\n<pre><code class=\"language-groovy\">// send notifications synchronously\ngrails.plugins.airbrake.async = false\n</code></pre>\n<h3>Custom Asynchronous Handler</h3>\n<p>To send the notifications asynchronously using a custom handler, use the async configuration option.\nThis configuration takes a closure with two parameters the <code>Notice</code> to send and the <code>grailsApplication</code>. The asynchronous handler should simply call <code>airbrakeService.sendNotice(notice)</code> to deliver the notification.</p>\n<p>This plugin does not introduce a default choice for processing notices asynchronously. You should choose a method that suits your application.\nYou could just create a new thread or use a scheduler/queuing plugin such as <a href=\"http://grails.org/plugin/quartz\">Quartz</a> or <a href=\"http://grails.org/plugin/jesque\">Jesque</a></p>\n<p>For example if you are using the Quartz plugin you can send notifications asynchronously using the following setting in <code>Config.groovy</code></p>\n<pre><code class=\"language-groovy\">grails.plugins.airbrake.async = { notice, grailsApplication ->\n AirbrakeNotifyJob.triggerNow(notice: notice)\n}\n</code></pre>\n<p>and the <code>AirbrakeNotifyJob</code> is defined in <code>grails-app\\jobs</code> something like this:</p>\n<pre><code class=\"language-groovy\">class AirbrakeNotifyJob {\n def airbrakeService\n\n def execute(JobExecutionContext context) {\n Notice notice = context.mergedJobDataMap.notice\n if (notice) {\n airbrakeService.sendNotice(notice)\n }\n }\n}\n</code></pre>\n<h3>Stack Trace Filtering</h3>\n<p>By default all stack traces are filtered using an instance of <code>org.codehaus.groovy.grails.exceptions.DefaultStackTraceFilterer</code> to remove common Grails and java packages.\nTo provide custom stack trace filtering simple configure an instance of a class that implements the interface <code>org.codehaus.groovy.grails.exceptions.StackTraceFilterer</code> in <code>Config.groovy</code></p>\n<pre><code class=\"language-groovy\">grails.plugins.airbrake.stackTraceFilterer = new MyCustomStackTraceFilterer()\n</code></pre>\n<h2>Compatibility</h2>\n<p>This plugin is compatible with Grails version 2.0 or greater. A backport to Grails 1.3 is available on the [grails-1.3 branch] (https://github.com/cavneb/airbrake-grails/tree/grails-1.3).</p>\n<h2>Release Notes</h2>\n<ul>\n<li>0.7 - 2012/09/21\n<ul>\n<li>Added support for filtering parameters, session and cgiData. #2</li>\n</ul>\n</li>\n<li>0.7.1 - 2012/09/21\n<ul>\n<li>Change supported Grails version to 2.0.0. #3</li>\n</ul>\n</li>\n<li>0.7.2 - 2012/09/24\n<ul>\n<li>Added User Agent, Hostname and user data to notifications</li>\n</ul>\n</li>\n<li>0.8 - 2012/10/16\n<ul>\n<li>Simpler configuration (Breaking change)</li>\n<li>Default notification environment to current Grails environment. #9</li>\n<li>Support for notifying caught exceptions. #15</li>\n<li>Support for notifying all messages logged at the error level (with or without exceptions)</li>\n<li>Simpler api for providing user data</li>\n<li>Full class names in stacktrace. #11</li>\n</ul>\n</li>\n<li>0.8.1 - 2012/10/19\n<ul>\n<li>Better error message for uncaught exceptions. #18</li>\n</ul>\n</li>\n<li>0.9.0 - 2012/10/29\n<ul>\n<li>Support for sending notifications to Airbrake asynchronously</li>\n<li>Added method to AirbrakeService set notification context information that will be used for any reported errors</li>\n<li>Simpler api to provide User Data. No need to implement UserDataService instead just set the context. (Breaking Change)</li>\n<li>All request headers now included when reporting an error.</li>\n</ul>\n</li>\n<li>0.9.1 - 2012/11/30\n<ul>\n<li>Notifications sent to Airbrake asynchronously by default using a thread pool of configurable size #20</li>\n<li>By default stack traces are filtered #19</li>\n<li>New configuration option to support custom stack trace filtering</li>\n<li>New configuration options for filtering params, session and cgi data independently</li>\n</ul>\n</li>\n<li>0.9.2 - 2013/1/19\n<ul>\n<li>Support for Grails 2.2 and Groovy 2.0 #27</li>\n</ul>\n</li>\n<li>0.9.3 - 2013/05/10\n<ul>\n<li>New feature to enable/disable notification send while the plugin is running #31</li>\n<li>New configuration option to filter exceptions by name or pattern #34</li>\n<li>Bug fix. Don't send notifications synchronously by default #26</li>\n<li>Bug fix. Handle empty backtrace more gracefully for Errbit #33</li>\n<li>Thanks to @domurtag for all the fixes</li>\n</ul>\n</li>\n<li>0.9.4 - 2013/06/25\n<ul>\n<li>Bug fix. AirbrakeNotifier.notify no longer throws under any circumstance.</li>\n</ul>\n</li>\n</ul>\n<h2>Contributing</h2>\n<ol>\n<li>Fork it</li>\n<li>Create your feature branch (<code>git checkout -b my-new-feature</code>)</li>\n<li>Commit your changes (<code>git commit -am 'Added some feature'</code>)</li>\n<li>Push to the branch (<code>git push origin my-new-feature</code>)</li>\n<li>Create new Pull Request</li>\n</ol>\n<h1>Kudos</h1>\n<p>The origin version of this plugin was written by Phuong LeCong (<a href=\"https://github.com/plecong/grails-airbrake\">https://github.com/plecong/grails-airbrake</a>).\nSince then it has undergone significant refactoring and updates inspired by the Ruby Airbrake gem (<a href=\"https://github.com/airbrake/airbrake\">https://github.com/airbrake/airbrake</a>)</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "ajax-tags", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Grails ajax-tags plugin", |
| "labels": [ |
| "ajax" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails3-plugins/ajax-tags/issues", |
| "latestVersion": "1.0.0", |
| "updated": "2016-04-01T15:35:44.151Z", |
| "systemIds": [ |
| "org.grails.plugins:ajax-tags" |
| ], |
| "vcsUrl": "https://github.com/grails3-plugins/ajax-tags" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": null |
| }, |
| { |
| "displayName": "ajax-dependency-selection", |
| "bintrayPackage": { |
| "name": "ajaxdependancyselection", |
| "repo": "maven", |
| "owner": "vahid", |
| "desc": "Grails ajaxdependancyselection plugin", |
| "labels": [ |
| "ajax" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/vahidhedayati/ajaxdependancyselection/issues", |
| "latestVersion": "1.3", |
| "updated": "2016-06-28T14:58:54.722Z", |
| "systemIds": [ |
| "org.grails.plugins:ajaxdependancyselection" |
| ], |
| "vcsUrl": "https://github.com/vahidhedayati/ajaxdependancyselection" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>ajaxdependancyselection</h1>\n<h3>Side note - similar / related projects</h3>\n<ul>\n<li>\n<p><a href=\"https://github.com/vahidhedayati/ajaxdependancyselection\">ajaxdependancyselection (this)</a></p>\n</li>\n<li>\n<p><a href=\"https://github.com/vahidhedayati/grails-boselecta-plugin\">grails-boselecta-plugin</a></p>\n</li>\n</ul>\n<p>Ajaxdependancyselection is a Grails plugin which makes use of jquery to provide either select or auto complete form fields. This can be any combination of either fully dependent objects or full dependent as well as no reference bindings.</p>\n<p>A common problem when it comes to making a website is having objects that are independant and when a user selects an option what to do next ? do you refresh the page to update the next set of values or look into some jquery/java scripts to auto update the next set of select option.</p>\n<h2>Installation:</h2>\n<p>Add plugin Dependency :</p>\n<pre><code> compile ":ajaxdependancyselection:0.45-SNAPSHOT4"\n</code></pre>\n<p><a href=\"https://github.com/vahidhedayati/ajaxdependancyselection/tree/grails2\">codebase for grails 2.X</a></p>\n<p>Dependency (Grails 3.X) :</p>\n<pre><code> compile "org.grails.plugins:ajaxdependancyselection:1.3" \n</code></pre>\n<p><a href=\"https://github.com/vahidhedayati/ajaxdependancyselection/\">codebase for grails 2.X</a></p>\n<h3>0.43 + Security Configuration:</h3>\n<p>In order to ensure you only allow this plugin to search desired domainClasses as well as restricted to only search/collect fields that will be used within the plugin calls. Simply add something like this below to your Config.groovy. Covering the full domainClass and its packaging convention the search/collect fields you wish to call from within the plugin calls. This now means anything outside of this scope should fail if anyone attempts to break out of the plugin..</p>\n<pre><code class=\"language-groovy\">ads {\n\tsecurity = "enabled"\n\twhitelist = [\n\t\t\t[dc:'ajaxdependancyselectexample.MyContinent', collect:'id', search:'continentName'],\n\t\t\t[dc:'ajaxdependancyselectexample.MyCountry', collect:'id', search:'countryName'],\n\t\t\t[dc:'ajaxdependancyselectexample.MyCity', collect:'id', search:'cityName']\n\t]\n}\n</code></pre>\n<h2>Autocomplete requirements:</h2>\n<p>To use the autocomplete features simply enable this taglib call:</p>\n<pre><code class=\"language-gsp\"><ads:loadjui/>\n</code></pre>\n<p>Within your layout/main.gsp or a gsp page that uses autoComplete and requires jquery-ui</p>\n<p>You can also add:</p>\n<pre><code class=\"language-gsp\">loadjui='enable'\n</code></pre>\n<p>To any ads:autoComplete tags and you should only need to call it once on a given page. So on one of the ads:autoComplete calls should suffice.</p>\n<h5>Websocket multi-select + auto complete(html5)</h5>\n<p><a href=\"https://github.com/vahidhedayati/grails-boselecta-plugin\">boselecta</a>, no jquery and no jquery-ui used. Secure information flow. downside - client needs to have websocket supported browser.</p>\n<h2>version info:</h2>\n<pre><code>0.45-SNAPSHOT4/1.0 - various issues https://github.com/vahidhedayati/testads5/issues/1#issuecomment-113842538\n0.45-SNAPSHOT3 - reverted returnPrimarySearch due to filtering issues\n0.45-SNAPSHOT2 - added showSearchField='|' and whatever character to split collect/search fields for auto complete - user request.\n\n0.45/1.0 - Fixed jquey-ui image issues, fixed controller action selection. hardcoded jquery removed from _selectJs.gsp\n0.44 - a println left in security - as part of upgrade to grails3 (now working) all code has been reviewed and a major tidy up lock down carried out.\n\n0.43 - Security configuration added, you can now define which domainClasses are searchable and what fields can be searched. I can see the initial primary selection still works but this is due to entire list being returned - beyond this nothing else will work if security enabled and locked down. Review instructions on security at the very top of this README.\n\n0.42-SNAPSHOT3 & SNAPSHOT2 : https://github.com/vahidhedayati/ajaxdependancyselection/issues/9\n\n0.42-SNAPSHOT1 : https://github.com/vahidhedayati/ajaxdependancyselection/issues/8\n\n0.42-SNAPSHOT: https://github.com/vahidhedayati/ajaxdependancyselection/issues/7\n\n\n0.42 - \thttps://github.com/vahidhedayati/ajaxdependancyselection/issues/7#issuecomment-55927174 as per request - primaryList\n\t\tcan now be provided via main call i.e. controller providing the list to the taglib, domain can be set to \n\t\tan invalid value. Please refer to example6.gsp within ajaxdependancyselectexample project.\n\t\t\n\t\t\n0.41 - \tmultiple added to all select calls so multiple=true or false can be defined (optional)\n\t\tmultiple="multiple" multiple="false" multiple="true"\n\t\tfixed issue for require required - both now accepted.\n\t\t\n0.40 - \t0.39 was incomplete - a few issues with primary/secondary selection - EDIT mode. should now be fixed.\n\n0.39 -\tsecondaryValue='2' attribute added to selectPrimary/selectSecondary. Related to this question: \n\t\thttp://stackoverflow.com/questions/23220436/ajax-dependency-selection-plugin/24745037\n\t\t\n\n0.38 - \tappendName appendValue values not being passed from tagLib to services..\n\n0.37 -\tselectJs files updated logic added to if autocomp is set in \n\t\tany ads:selectPrimary/Secondary then it will look for autocompleteSecondary \n\t\ttag to fullfill autocomplete refer to selectauto3.gsp\n\t\t\n0.36 -\tminor bug in selectController '' used instead of "" for attrs.id so id was being shown as attrs.id\n \n0.35 - \tMade values updated default values optional - if appendValue is given in ads:select then it will set appendName to default value\n \t\n0.34 - \tNow supporting multiple dependency calls, in a given ads:select you can now declare upto 5 depended object bound to a\n \t\tprimary or secondary selection.\n \t\t\n0.33 - \tToo minor to mention\n0.32 - \tFurther tidyup of duplicate javascripts, cleaner calls made within taglib and reduction of duplicate gsp pages, issue\n\t\twith return results in controller displayed undefined when no results found - fixed.\n\t\t\n0.31 - \tTidyup of javascript calls within taglib, fixed secondaryNR filter2 issues - filtering now working across all select functions\n\n0.30 - \tIssues with filtering and end box with no filter not displaying values - tidyup\n\n0.29 - \tFilterDisplay and filterType intro - user override of action controllers for filtering js and controller/actions added\n\n0.28 - \tTidy up - and further work on specific filtering for selectSecondary\n\n0.27 - \tFiltering of selectPrimary\n\n0.26 - \tAdded selectAutoComplete\n\n0.23 - \tRemoved null from values updated (default additional selection field added when values update), this now means user has to \n\t\tstill choose this value\n\t\t \n0.22 - Added required by default set to required for all taglib calls. \n\n0.19 - Broken build - there were issues with the tidyup I did with selectSecondary, totally forgot it was being used by \n\t\t\tselectPrimary. 0.20 should be fine\n\n</code></pre>\n<h2>Example site:</h2>\n<p>Using this plugin with the grails framework you are able to achieve this without all of the complications. Refer to this sample project which makes use of all of the examples below with some objects already pre-added to the sample projecet. Found here in this sample project:</p>\n<p><a href=\"https://github.com/vahidhedayati/ajaxdependancyselectexample\">Example grails project grails 2.4.2</a></p>\n<p><a href=\"https://github.com/vahidhedayati/testads5\">Example grails project grails 2.5</a></p>\n<p><a href=\"https://github.com/vahidhedayati/testad\">Example grails project grails 2.4.4</a></p>\n<p><a href=\"https://github.com/vahidhedayati/testads\">Example grails project grails 3.0.1</a></p>\n<p>for <a href=\"http://grails.org/plugin/ajaxdependancyselection\">grails ajaxdependancyselection plugin</a>.<a href=\"https://github.com/vahidhedayati/ajaxdependancyselection/issues\">Issues can be reported here</a>. For further documentation and examples, check out the <a href=\"https://github.com/vahidhedayati/ajaxdependancyselection/wiki\">wiki</a></p>\n<p>I have included the text and html samples from all of the examples in the example site. Use Europe/United Kingdom/London or Oxford for a full completed example within the above example project when loading it up.</p>\n<h2>General note over naming conventions.</h2>\n<p>In the examples provided domainClasses has been defined as countryName cityName and so forth, this was really an example to show it can be any naming convention besides the standard id, name column naming convention. Feel free to name things as you desire i.e. this is not a requirement of the plugin.</p>\n<h2>Taglibs provided:</h2>\n<pre><code>ads:selectPrimary\nads:selectSecondary\nads:selectAutoComplete\nads:autocomplete\nads:autoCompletePrimary\nads:autoCompleteSecondary\nads:selectPrimaryNR\nads:selectSecondaryNR\nads:autoCompleteSecondaryNR\nads:selectController\nads:autoCompleteHeader\n\nads:selectPrimary - custom controller/action sample\nads:selectPrimary/Secondary Filtering\nads:selectPrimary/Secondary support for domain3 domain4 domain5 domain6 domain7 and domain8 which can all be added: \n\t\t\t\t\t\t\t-- to any selectPrimary or Secondary call, each domain is a bound object\n\t\t\t\t\t\t\t-- This means if a Country has many cities and many mayors upon country update relevant cities and mayors are loaded\n\t\t\t\t\t\t\t-- extend this now across upto domain8 for each object initiall called\n\t\t\t\t\t\t\tPlease read below on the how to and refer to the example site for a very basic demo.\n</code></pre>\n<h3>ads:selectPrimary</h3>\n<h6>(relationship: fully dependent ) in conjunction with ads:selectSecondary</h6>\n<h6>refer to above notes on jquery requirements</h6>\n<h6>Fully dependent domainClasses:</h6>\n<pre><code>class PrimaryDomain {\n\tString name\n\tstatic hasMany = [ secondarydomain: SecondaryDomain ]\n}\n\nclass SecondaryDomain {\n\tString name\n\tstatic belongsTo = [ primarydomain: PrimaryDomain ]\n}\n</code></pre>\n<p>Bindid would be:</p>\n<pre><code>bindid="primarydomain.id"\n</code></pre>\n<p>This you would use ads:selectPrimary the bindid is primarydomain.id the field highlighted in bold above as the bindid</p>\n<pre><code class=\"language-gsp\"> <ads:selectPrimary id="MyContinent1" name="MyContinent1"\n domain='ajaxdependancyselectexample.MyCountry'\n searchField='countryName'\n collectField='id'\n \n domain2='ajaxdependancyselectexample.MyCity'\n bindid="mycountry.id"\n searchField2='cityName'\n collectField2='id'\n\n\t\t multiple='true'\n\t\t \n noSelection="['': 'Please choose Country']" \n setId="MyCity1"\n value=''/>\n</code></pre>\n<p><a href=\"https://github.com/vahidhedayati/ajaxdependancyselection/wiki/ads:selectPrimary---entire-input-values\">Entire input with explaination</a></p>\n<p>Now this can be either passed toa normal select or to a ads:selectSecondary where if if you have further dependency you wish to interogate.</p>\n<p>So in the case of Country city, the above is fine to call to a city select area that is a simple call like this:</p>\n<pre><code class=\"language-gsp\">\t<g:select \n\tid="MyCountry" \n\tname="MyCity1"\n\toptionKey="id"\n\toptionValue="name" \n\tfrom="[]" \n\trequired="required" \n\tnoSelection="['': 'Please choose Country']" />\n \n</code></pre>\n<p>If however this was a multi nested dependency situation you could proceed to selectSecondary where this will update either a final call just like per above or call selectSecondary over and over again until nesting is completed with final select as above. again ensure you are making proper calls your optionKey and Value needs to match your own table naming convention or in simple terms</p>\n<pre><code><option value=YourDefindOptionKey>YourDefinedOptionValue</option>\n</code></pre>\n<p>is what is represented on the html end</p>\n<h3>ads:selectSecondary</h3>\n<h6>(relationship: fully dependent ) in conjunction with ads:selectPrimary</h6>\n<h6>refer to above notes on jquery requirements</h6>\n<p>This is a tag that can be used over and over again to go through nested situations, you can also use the selectSecondaryNR features to interact from selectPrimary or selectSecondary, this will be final part of document\nBack to ads:selectSecondary example:</p>\n<pre><code class=\"language-gsp\"><ads:selectSecondary id="MyCountry11" name="MyCountry11"\n domain2='ajaxdependancyselectexample.MyCity'\n bindid="mycountry.id"\n searchField2='cityName'\n collectField2='id'\n \n \n appendValue=''\n appendName='Updated'\n \n \n multiple='true'\n \n noSelection="['': 'Please choose Continent']" \n setId="MyCity11"\n value="${params.MyCountry11}"/>\n</code></pre>\n<p><a href=\"https://github.com/vahidhedayati/ajaxdependancyselection/wiki/ads:selectSecondary-entire-input\">ads:selectSecondary entire input and explaination</a></p>\n<p>##ads:selectAutoComplete</p>\n<p>This is a new feature from 0.26+, it allows you to set up a select box from which auto complete values are generated depending on what user selects.</p>\n<pre><code class=\"language-gsp\"><ads:selectAutoComplete \n id="MyContinent2" \n id2="MyCountry2" \n name="MyContinent2"\n domain="ajaxdependancyselectexample.MyContinent"\n searchField="continentName"\n collectField="id"\n primarybind="mycontinent.id"\n domain2="ajaxdependancyselectexample.MyCountry"\n searchField2="countryName"\n collectField2="id"\n \n appendValue=""\n appendName="values updated"\n noSelection="['': 'Please choose Continent']" \n setId="MyCountry121"\n hidden='hidden3'\n hidden2='hidden4'\n value=""/>\n</code></pre>\n<p><a href=\"https://github.com/vahidhedayati/ajaxdependancyselection/wiki/From-Select-to-AutoComplete\">Explaination/example found here</a></p>\n<p>###ads:selectPrimary/Secondary to ads:autoCompleteSecondary\nIf you want to pass from selections to auto complete then from 0.37+ release you should be able to pass parameter autocomp="1" to any of the ads:select methods followed by a call to ads:autocompleteSecondary.. <a href=\"https://github.com/vahidhedayati/ajaxdependancyselection/wiki/from-selection-to-autocomplete---how-to\">from-selection-to-autocomplete---how-to</a></p>\n<p>###ads:autocomplete\nThis is a simple auto complete tag lib that allows you to auto complete from a single table, refer to above notes on jquery & jquery-ui requirements</p>\n<pre><code class=\"language-gsp\"><ads:autocomplete id="primarySearch" name="myId"\ndomain='ajaxdependancyselectexample.MyCountry'\nsearchField='countryName'\ncollectField='id'\nvalue=''/>\n<input type=submit value=go> </form>\n</code></pre>\n<p><a href=\"https://github.com/vahidhedayati/ajaxdependancyselection/wiki/autoComplete-full-input\">all ads:autocomplete calls</a></p>\n<p>###ads:autoCompletePrimary</p>\n<pre><code class=\"language-gsp\"><ads:autoCompletePrimary id="primarySearch1" \nname="NAMEOFcontinentName"\ndomain='ajaxdependancyselectexample.MyContinent'\nsearchField='continentName'\ncollectField='id'\n\nmultiple='false'\n\nsetId="secondarySearch2"\nhidden='hidden3'\nvalue=''/>\n</code></pre>\n<p><a href=\"https://github.com/vahidhedayati/ajaxdependancyselection/wiki/autoCompletePrimary---full-detail\">autoCompletePrimay explained</a></p>\n<p>###ads:autoCompleteSecondary</p>\n<pre><code class=\"language-gsp\"><ads:autoCompleteSecondary id="secondarySearch2" \nname="NAMEOFcountryName" \ndomain='ajaxdependancyselectexample.MyCountry' \nprimarybind='mycontinent.id' \nhidden='hidden3' \nhidden2='hidden4' \nmultiple='false'\nsearchField='countryName' \ncollectField='id'\nsetId="secondarySearch3" \nvalue=''/>\n</code></pre>\n<p><a href=\"https://github.com/vahidhedayati/ajaxdependancyselection/wiki/ads:autoCompleteSecondary-full-detail\">autoCompleteSecondary explained</a></p>\n<p>###ads:selectPrimaryNR</p>\n<h6>No reference mapping</h6>\n<pre><code class=\"language-groovy\">\tclass PrimaryDomain {\n \t\tString name\n \t\tstatic hasMany = [ secondarydomain: SecondaryDomain ]\n\t}\n\n\tclass SecondaryDomain {\n \t\tString name\n\t\tstatic belongsTo = [PrimaryDomain ]\n\t}\n</code></pre>\n<p>Now within your call the bindid would be:</p>\n<pre><code>bindid="secondarydomain"\n</code></pre>\n<p>This you would use ads:selectPrimaryNR the bindid is secondarydomain the field highlighted in bold above as the bindid</p>\n<p>Notice in the PrimaryNR the bindid is the primary hasMany mapping and has no .id</p>\n<p>Example call:</p>\n<p><a href=\"https://github.com/vahidhedayati/ajaxdependancyselection/wiki/ads:selectPrimaryNR-Full-details\">ads:selectPrimaryNR-Full-details</a></p>\n<p>###ads:selectSecondaryNR</p>\n<p><a href=\"https://github.com/vahidhedayati/ajaxdependancyselection/wiki/ads:selectSecondaryNR--full-details\">ads:selectSecondaryNR--full-details</a></p>\n<p>###ads:autoCompleteSecondaryNR\n<a href=\"https://github.com/vahidhedayati/ajaxdependancyselection/wiki/ads:autoCompleteSecondaryNR-full-details\">ads:autoCompleteSecondaryNR-full-details</a></p>\n<h3>ads:selectController</h3>\n<h6>Controller action discovery, refer to above notes on jquery requirements</h6>\n<p>This will display all your controllers then let you Choose available actions of this controller:\nhttps://github.com/vahidhedayati/ajaxdependancyselectexample/blob/master/grails-app/views/myContinent/example.gsp\nLine 210 onwards has an example.Typically maybe used for identifying controller name and its available actions to store against something maybe for your own custom authentication control that binds all this with something else.</p>\n<p>Here are the values explained:</p>\n<p><a href=\"https://github.com/vahidhedayati/ajaxdependancyselection/wiki/ads:selectController-full-details\">ads:selectController-full-details</a></p>\n<p>This now gets passed to a standard select call where it has an id of "ControllerActions":</p>\n<p><a href=\"https://github.com/vahidhedayati/ajaxdependancyselection/wiki/gccontroller-actions-or-reciever-selection-box\">gccontroller-actions-or-reciever-selection-box</a></p>\n<p>The from on this is set to [] which gets filled in by ads:selectController setId return call.</p>\n<h2>ads:autoCompleteHeader</h2>\n<h6>Loads in the ajaxLoader if your site is not already doing it</h6>\n<pre><code><ads:autoCompleteHeader />\n</code></pre>\n<h2>ads:selectPrimary - Custom</h2>\n<h6>Customising your own calls:</h6>\n<p>This is covered in the sample project labelled as custom example. Create your own controller which is set to do a custom verification:</p>\n<pre><code class=\"language-groovy\">\tdef selectCountries() {\n\t\tif (params.id) {\n\t\t\tprintln params\n\t\t\tString continentName = params.searchField\n\t\t\tLong continentId = params.id as Long\n\t\t\tMyContinent continent = MyContinent.get(continentId)\n\n\t\t\t/* Either this method or below method which is much shorter\n\t\t\tdef primarySelectList = []\n\t\t\tMyCountry.findAllByMycontinentAndCountryNameLike(continent, "F%").each {\n\t\t\t\tdef primaryMap = [:]\n\t\t\t\tprimaryMap.put('id', it.id)\n\t\t\t\tprimaryMap.put('name', it.countryName)\n\t\t\t\tprimarySelectList.add(primaryMap)\n\t\t\t}\n\t\t\trender primarySelectList as JSON\n\t\t\t*/\n\t\t\t\n\t\t\t// Shorter method\n\t\t\tdef countries=MyCountry.findAllByMycontinentAndCountryNameLike(continent, "F%")\n\t\t\tdef results = countries.collect {[\t'id': it.id, 'name': it.countryName ]}.unique()\n\t\t\trender results as JSON\n\t\t}\n\t}\n\n</code></pre>\n<p>Create a call for this:</p>\n<pre><code class=\"language-gsp\"><ads:selectPrimary id="MyContinent2" name="MyContinent2"\ndomain="ajaxdependancyselectexample.MyContinent"\nsearchField="continentName"\ncollectField="id"\n\ncontroller="MyContinent"\naction="selectCountries"\n\ndomain2="ajaxdependancyselectexample.MyCountry"\nbindid="mycontinent.id"\nsearchField2="countryName"\nappendValue=""\nappendName="values updated"\ncollectField2="id"\nnoSelection="['': 'Please choose Continent']" \nsetId="MyCountry121"\nvalue=""/>\n \n \n \n<g:select name="MyCountry" id="MyCountry121" from="[]" required="required" \nnoSelection="['': 'Please choose Continent']" />\n</code></pre>\n<p>I will be updating this so that less input is required when custom action controller is defined.</p>\n<h2>ads:selectPrimary/Secondary Filtering</h2>\n<h6>Filtering can be hard coded per select call or can be left for the user to filter output of a selectbox. this can be either useful if you only want to show specific results from selection for specific user or possibly when you wish user to speed up selection process and let them control the output of the selectbox.</h6>\n<p>Most basic example is a hard coded version: /ajaxdependancyselectionexample/myContinent/norefselectSecondaryFilteringFixed.gsp and or https://github.com/vahidhedayati/ajaxdependancyselection/wiki/Nested-Selection-from-fully-fixed-search-all-that-way-including-a-secondaryNR</p>\n<p>This is where you start with your <ads:selectPrimary filter="something" filter2="another"\nThis will now filter results for primary matching against something and the next secondary call to filter against another</p>\n<p>On your next <ads:selectSeconday you simply call filter2="somethingelse"</p>\n<p>This will now pass this filter to next object being completed and all the way to last standard call which will end in standard <g:select box but will still be filtered.</p>\n<p>The other way is to enable filtering and let user control the filter, to do this simply switch filter="_ON" in each <ads:selectPrimary/Secondary call</p>\n<p>In primary it is just as simple as switching it on, within secondary calls it gets a little more complex.</p>\n<h6>Primary & PrimaryNR in full:</h6>\n<p>To enable user driver filtering - add this</p>\n<pre><code class=\"language-gsp\">filter="_ON"\nhidden="hiddenFieldForPrimary"\n</code></pre>\n<p>To enable hard coded filtering add this:</p>\n<pre><code class=\"language-gsp\">filter="SOMETHING"\n</code></pre>\n<p>With either a fixed filter above or dynamic user controlled followed by: Only needed if you want to define you next select filter physically</p>\n<pre><code class=\"language-gsp\">filter2="B"\t\t\t\t\t\n</code></pre>\n<p>Optional stuff:\t\nput this in so with filtering no results are shown if user does not match or as it starts and only show matching results in select to what user inputs</p>\n<pre><code class=\"language-gsp\">filterDisplay="none" \t\t\t\n</code></pre>\n<p>Values are : S E A - Start of Record End of Record or by default if not defined Any part of record i.e. wild card search.</p>\n<pre><code class=\"language-gsp\">filterType ="A" \t\t\t\n</code></pre>\n<p>Override optional stuff:</p>\n<p>if you wish to point the filtering actions to another location at the moment default autoComplete controller from plugin</p>\n<pre><code class=\"language-gsp\">filterController="YourController" \t\n</code></pre>\n<p>if you wish to define your own action for the above controller call</p>\n<pre><code class=\"language-gsp\">filteraction="your action"\n</code></pre>\n<p>Default is loadFilterWord this loads up the user input box for end user filtering</p>\n<pre><code class=\"language-gsp\">filteraction="loadFilterWord"\n\n</code></pre>\n<p>The action that returns the primary list the default value is as defined</p>\n<pre><code class=\"language-gsp\">filteraction2="returnPrimarySearch"\n\n</code></pre>\n<p>Config.groovy overrides:</p>\n<pre><code class=\"language-groovy\">ajaxdependancyselection.filterField='/autoComplete/filterField'\najaxdependancyselection.selectBasicJS='/autoComplete/selectJs'\n</code></pre>\n<h6>Secondary & Secondary NR in full:</h6>\n<p>To enable user driver filtering - add this</p>\n<pre><code class=\"language-gsp\">filter="_ON"\nhidden="hiddenFieldForPrimary"\n</code></pre>\n<p>To enable hard coded filtering for the next field add this: Only needed if you want to define you next select filter physically</p>\n<pre><code class=\"language-gsp\">filter2="SOMETHING"\t\t\t\t\t\t\t\n</code></pre>\n<p>Optional stuff: put this in so with filtering no results are shown if user does not match or as it starts and only show matching results in</p>\n<pre><code class=\"language-gsp\">filterDisplay="none"\t\t\n</code></pre>\n<p>select to what user inputs: Values are : S E A - Start of Record End of Record or by default if not defined Any part of record i.e. wild card search.</p>\n<pre><code class=\"language-gsp\">filterType ="A" \t\t\t\n</code></pre>\n<h3>Override optional stuff:</h3>\n<p>If you wish to point the filtering actions to another location at the moment default autoComplete controller from plugin</p>\n<pre><code class=\"language-gsp\">filterController="YourController" \t\n</code></pre>\n<p>If you wish to define your own action for the above controller call</p>\n<pre><code class=\"language-gsp\">filteraction="your action"\t\t\t\t\t\t\t\t\n</code></pre>\n<p>Default is loadFilterWord this loads up the user input box for end user filtering</p>\n<pre><code class=\"language-gsp\">filteraction="loadFilterWord2"\t\t\n</code></pre>\n<p>The action that returns the secondary search whilst filter results</p>\n<pre><code class=\"language-gsp\">filteraction2="secondarySearch"\t\t\n</code></pre>\n<p>Config.groovy overrides:</p>\n<pre><code class=\"language-groovy\">ajaxdependancyselection.filterField='/autoComplete/filterField'\najaxdependancyselection.selectSecondaryJsFilter='/autoComplete/selectJs1' {Secondary default}\najaxdependancyselection.selectSecondaryJsFilter='/autoComplete/selectJsNr1' {SecondaryNR default}\n</code></pre>\n<p><a href=\"https://github.com/vahidhedayati/ajaxdependancyselection/wiki/Select-Box-Filtering-results-userdefined-or-fixed-filtering\">For other examples of filtering, check out</a> or the filtering example page within the example project site.</p>\n<h2>ads:selectPrimary/Secondary Multi domainClass loading:</h2>\n<h6>Feature since 0.34</h6>\n<p>This allows you to load up domain3, domain4, domain5, domain6, domain7, domain8 per Primary or Secondary Call.\nEach of them can then have the same nesting meaning some wild dependencies can be created and complex selecting provided.</p>\n<p>The how to:</p>\n<pre><code class=\"language-gsp\"><ads:selectPrimary id="MyDepartments" name="MyDepartments"\ndomain='ajaxdependancyselectexample.Departments'\nsearchField='name'\ncollectField='id'\nnoSelection="['': 'Please choose Department']" \n\ndomain2='ajaxdependancyselectexample.Employee'\nbindid="department.id"\nsearchField2='name'\ncollectField2='id'\nsetId="employeeID"\n\n\ndomain3='ajaxdependancyselectexample.Documents'\nbindid3="department.id"\nsearchField3='name'\ncollectField3='id'\nsetId3="documentsId"\nfilter3="L"\n\nvalue=''/>\n\n<g:select name="employee" id="employeeID" optionKey="id" optionValue="name" from="[]" \nrequired="required" noSelection="['': 'Please choose department']" />\n\n<g:select name="document" id="documentsId" optionKey="id" optionValue="name" from="[]" \nrequired="required" noSelection="['': 'Please choose department']" />\n</code></pre>\n<p>The Primary block or Secondary Block simply create a new element that kind of follows the domain2 object\nbut in short everything ends with the correct numbering sequence. As you can see the bindings employeeID and documentsId got updated with relevant values that were depedent upong primary selection.</p>\n<p>Take a look at the multidomain example in the wiki or within the example project where it covers:</p>\n<h5>Example1: Simple multi domain dependency call one object two dependencies with filtering on one of the calls</h5>\n<h5>Example2: Simple multi domain dependency call one object two dependencies with no filtering</h5>\n<h5>Example3: Multi domain dependency call to domain3 and domain4</h5>\n<h5>Example4: Multi domain dependency call to domain3 and domain4 with domain4 then having its own multi depenency relatiobship</h5>\n<p>This last example shown here:</p>\n<p>Please note only the first computer from each initial department selected has any further values.</p>\n<pre><code class=\"language-gsp\"><form method=post action=example5>\n\n<ads:selectPrimary id="MyDepartments141" name="MyDepartments141"\ndomain='ajaxdependancyselectexample.Departments'\nsearchField='name'\ncollectField='id'\nnoSelection="['': 'Please choose Department']" \n\ndomain2='ajaxdependancyselectexample.Employee'\nbindid="department.id"\nsearchField2='name'\ncollectField2='id'\nsetId="employeeID141"\n\ndomain3='ajaxdependancyselectexample.Documents'\nbindid3="department.id"\nsearchField3='name'\ncollectField3='id'\nsetId3="documentsId141"\n\ndomain4='ajaxdependancyselectexample.Computers'\nbindid4="department.id"\nsearchField4='pcName'\ncollectField4='id'\nsetId4="computersId141"\nvalue=''/>\n\n<g:select name="employee" id="employeeID141" optionKey="id" optionValue="name" from="[]" \nrequired="required" noSelection="['': 'Please choose department']" />\n<g:select name="document" id="documentsId141" optionKey="id" optionValue="name" from="[]" \nrequired="required" noSelection="['': 'Please choose department']" />\n\n\n\n<ads:selectSecondary id="computersId141" name="computersId141"\n\ndomain2='ajaxdependancyselectexample.Os'\nbindid="computers.id"\nsearchField2='osName'\ncollectField2='id'\nsetId="Os13"\n\ndomain3='ajaxdependancyselectexample.Users'\nbindid3="computers.id"\nsearchField3='userName'\ncollectField3='id'\nsetId3="userId13"\n\nappendValue=''\nappendName='Updated'\n\nnoSelection="['': 'Please choose Department']" \n\nvalue="${params.computersId141}"/>\n\n\n<g:select name="Os" id="Os13" optionKey="id" optionValue="pcName" from="[]" \nrequired="required" noSelection="['': 'Please choose Computer']" />\n\n<g:select name="users" id="userId13" optionKey="id" optionValue="userName" \nfrom="[]" required="required" noSelection="['': 'Please choose computer']" />\n\n<input type=submit value=go>\n</form>\n\t\t\n</code></pre>\n<h3>0.40+ Edit an existing page using ajaxdependancyselection.</h3>\n<p>This may be rather difficult but if the values are then stored on DB and you wish to further edit the defined stored values you now can from version 0.40+.\nPlease refer to https://github.com/vahidhedayati/ajaxdependancyselectexample/blob/master/grails-app/views/myContinent/testedit.gsp. This page has fixed values defined with an additional variable defined within selectPrimary/Secondary:</p>\n<pre><code class=\"language-gsp\">value='2'\nsecondaryValue='2'\n</code></pre>\n<p>Although in the given gsp example page the values are hardcoded, in real life those be the values returned from db</p>\n<pre><code class=\"language-gsp\">value="${mydomainClass.primaryValue}"\nsecondaryValue="${mydomainClass.secondaryValue}"\n</code></pre>\n<p>So in selectPrimary/selectSecondary you define both the value and secondaryValue and the plugin will assign them to the relevant boxes. please follow the example to get an idea</p>\n<h3>END OF MAIN DOCUMENTATION</h3>\n<h3>--------------------------</h3>\n<h5>Further Examples below</h5>\n<h3>Example no reference domain classes:</h3>\n<p>Here are two domain classes with a no reference set up and require ads:selectSecondaryNR feature:</p>\n<pre><code class=\"language-groovy\">class MyCity {\nString cityName\n MyCountry mycountry\n static hasMany=[myborough: MyBorough]\n String toString() { "${cityName}"}\n}\n\nclass MyBorough {\n String actualName\n static belongsTo = [MyCity]\n String toString() { "${actualName}" }\n}\n\n</code></pre>\n<h3>Examples of primary to secondary then to seoncdaryNR</h3>\n<p>This non working gsp has some examples: https://github.com/vahidhedayati/ajaxdependancyselectexample/blob/master/grails-app/views/myContinent/noRefAutoComplete.gsp</p>\n<p>Here is the GSP making a nested call where an element has a no reference relationship, the gsp page in the example called norefselectionext.gsp goes back out of a NR relationship and calls Streets domain after borough to then load up a further relationsip</p>\n<p><a href=\"https://github.com/vahidhedayati/ajaxdependancyselection/wiki/select-primary-to-secondary-then-to-seoncdaryNR-nested-call\">select-primary-to-secondary-then-to-seoncdaryNR-nested-call</a></p>\n<h3>Examples Auto Complete Secondary to secondaryNR</h3>\n<p><a href=\"https://github.com/vahidhedayati/ajaxdependancyselectexample/blob/master/grails-app/views/myContinent/noRefAutoComplete.gsp\">This non working gsp has some examples</a></p>\n<p><a href=\"https://github.com/vahidhedayati/ajaxdependancyselection/wiki/autocomplete-primary-to-secondary-to-secondaryNR-nested-call\">autocomplete-primary-to-secondary-to-secondaryNR-nested-call</a></p>\n<h2>Thanks for contributions from</h2>\n<p>Alidad's <a href=\"https://github.com/alidadasb/CountryCityAutoComplete\">CountryCityAutoComplete project</a> which inspired this plugin.</p>\n<p>Burt Beckwith for helping clean up the code.</p>\n<p>Domurtag for identifying and helping improve plugin documentation and features.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "alexa-skills", |
| "repo": "alexa-skills", |
| "owner": "rvanderwerf", |
| "desc": "This is a Grails 3.x plugin to help make Amazon Alexa Skills / Speechlets", |
| "labels": [ |
| "amazon", |
| "alexa" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "", |
| "latestVersion": "0.1.2", |
| "updated": "2017-11-07T07:29:01.366Z", |
| "systemIds": [ |
| "org.grails.plugins:alexa-skills" |
| ], |
| "vcsUrl": "https://github.com/rvanderwerf/grails-alexa-skills" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<p>This is the Alexa skills Plugin!</p>\n<p>This plugin helps you create Speechlets/Skills on Grails. It will create a starter class for you\nso you can get running quickly making your own skills.</p>\n<h1>Installation</h1>\n<p>add the following to the dependencies {} block to your build.gradle:</p>\n<pre><code>dependencies {\n compile "org.grails.plugins:alexa-skills:0.1.2"\n}\n</code></pre>\n<p>also if you have issues resolving the plugin, try adding my bintray repo (NOT to buildscript block but the lower one):</p>\n<pre><code>\nrepositories {\n maven { url "http://dl.bintray.com/rvanderwerf/alexa-skills" }\n maven {\n url "http://dl.bintray.com/vanderfox/alexa-skills-kit-java" \n }\n}\n\n\n</code></pre>\n<h1>How it works</h1>\n<p>run 'grails create-speechlet <classPrefix>'\nThis will create a speechlet class file located in grails-app/speechlets. Do not use the suffix 'Speechlet' because that will be automatically appended to the name.</p>\n<h1>Configuration</h1>\n<p>Here's the config values you can set in application.yml or application.groovy:</p>\n<p><strong>alexaSkills.supportedApplicationIds (String)</strong></p>\n<ul>\n<li>this is a comma delimited list of application Ids you speechlet will recognize.</li>\n<li>you can get ID this under Skills->create on developer.amazon.com</li>\n</ul>\n<p><strong>alexaSkills.disableVerificationCheck (boolean)</strong></p>\n<ul>\n<li>if you are debugging and sending in canned request (see 'serializeRequests') via CURL turn this on</li>\n<li>be very careful not to disable this in a public service as it turns off all checking the request is really coming from Amazon.</li>\n</ul>\n<p><strong>alexaSkills.serializeRequests (boolean)</strong></p>\n<ul>\n<li>if you are having problems wondering what is going on with your skill or want to capture a request and replay it in CURL it will write them to disk</li>\n</ul>\n<p><strong>alexaSkills.serializeRequestsOutputPath (boolean)</strong></p>\n<ul>\n<li>if you turn on serialization requests this is the path the files will be saved to. The files will be names in the format:</li>\n<li>files will be saved in the format speechlet-${System.currentTimeMillis()}.out</li>\n</ul>\n<h1>Recommended usage with a Controller</h1>\n<pre><code>class TestController {\n\n def speechletService\n def testSpeechlet\n\n\n def index() {\n speechletService.doSpeechlet(request,response, testSpeechlet)\n }\n\n}\n</code></pre>\n<p>Here you see the speechlet is turned into a Spring bean, and you invoke the speechlet service and pass it in.\nLikely we could turn the speechlet artefact class into a controller itself in the future to skip this.\nIf you are using Spring security, make sure to whitelist the urlmapping for the index.</p>\n<h3>Blog Article from Grails Team Blog on how to make this all work</h3>\n<h2>Introduction</h2>\n<img src=\"http://grailsblog.ociweb.com/images/alexa/building-spoken-language-apps-and-experiences-for-amazon-echo-16-638.jpg\" class=\"float-left\"/>\n<p>Recently I gave a talk at GR8Conf.eu about building applications for the Amazon Alexa platform. I talked about using Groovy\nwith Lambdas to demonstrate Skills (Alexa Apps) as well as using Grails. I'll give this talk again at GR8Conf.us at the end of\nJuly and have even more good stuff to show. On top of that, after working on this for months I have the material to have an\nAlexa workshop at GR8Conf.us(Thanks to Collin Harrington for helping with the idea). Good Times! I wanted to write a post as a step-by step on using a plugin I've recently developed\nas to help you crank out Alexa apps(skills or speechlets). Amazon has a promotion right now, if you submit a new skill to their library,\nyou can win a free T-Shirt, so maybe you can make something cool with this and get one! You do not even need an Amazon device: you\ncan point your browser to https://echosim.io to use their emulator. <img src=\"http://grailsblog.ociweb.com/images/alexa/echosim.png\" class=\"float-right\"/></p>\n<p>Let me first get started to explain how these things work and a little about the devices. Starting a couple years ago, Amazon released\na home device/speaker thing called the Echo. It's a household helper device with very nice multi-directional microphones, and a nice speaker\nfor playing music. At first I didn't get one or understand it: it sounded like a useless toy to me. However peers gobbled them up and\nstarted playing around with them. They weren't building apps for it, but raved about how cool it was and how it helped automate their\nhome and do useful things. Then they started saying they loved it so much they were buying more units and putting them all over their house.\nNow my attention was had - of course the first thing that pops into my head was 'how can I get Groovy to work with this thing?'</p>\n<img src=\"http://grailsblog.ociweb.com/images/alexa/amazon-echo-3-638.jpg\" class=\"float-left\"/>\n<p>The first examples they give are all about AWS Lambda functions in Node - however they aren't fantastic on Java because they have a hard limit of 50mb\njars you can upload. Surely you can't fit all of grails and dependencies in there to do much. Still we gave it a shot - I followed\nBenoit H\ufffd\ufffd\ufffd\ufffddiard's <a href=\"https://skillsmatter.com/skillscasts/7291-serverless-microservices-using-aws-lambda-and-groovy\">presentation</a> on Groovy with Lambdas from GGX 2015. I sat down with a buddy of mine, Lee Fox (He will be at GR8Conf.us), and we hammed out a bunch of ideas\nwe could build with it - in Groovy of course!</p>\n<p>The first app we got working was a simple Twitter app that combined Groovy, Spring Social and Skills to make a skill that would connect to\nTwitter and search for tweets, as well as give updates to your timeline. You can find the code <a href=\"https://github.com/rvanderwerf/alexa-twitter-groovy\">here</a>. Good! Now we're getting somewhere. I did a little digging and found\nthey have some servlet support to make a stand along web service - now we can get Grails involved and make this less hideous.</p>\n<p>Next we took it a level up - we didn't want the user to have to hard-code their twitter API keys to run the app, and you can't publish a skill that\npulls down someone else's twitter info. So we build a Grails app that used Spring Security, Oath plugin, and Spring Security UI to allow a UI\nthat lets you register and enter your own twitter keys for your account. Source for that is <a href=\"https://github.com/rvanderwerf/twitterAuth\">here</a>.</p>\n<p>After that it was time to make a plugin to help you make these skills - that I published while I was out at GR8Conf.eu <a href=\"https://github.com/rvanderwerf/grails-alexa-skills\">here</a>.\nIt works similar to the Quartz plugin in that you have a CLI command to create a working template of a Skill to get you started. I will show you here how to build\na skill using the Grails plugin to get you started making your own Skills in a short about of time.</p>\n<h2>How Alexa service Works</h2>\n<p>The devices themselves, (which are currently the Echo, Tap, Dot, and FireTV) don't do a whole lot. They even publish the source to the devices\nfor you to look at if you choose <a href=\"https://www.amazon.com/gp/help/customer/display.html?nodeId=201626480\">here</a>. The magic resides on the amazon side that handles all the voice recognition and handling of requests.\nBasically what happens is the user initiates a action (skill) on the device, and it goes to the alexa service to figure out what you want to do.\nWhen your app is invoked, it calls back to your app via a JSON HTTPS call and initiates a series of Intents to make your app do things. Your app simple waits for the call\nand takes appropriate action (via JSON) to do what you want. It's up to you as the developer to make it do something useful.</p>\n<img src=\"http://grailsblog.ociweb.com/images/alexa/building-spoken-language-apps-and-experiences-for-amazon-echo-18-638.jpg\" class=\"center\" />\n<p>The picture above give you an idea of how it works (from Amazon's site). Let's go over Intents and Sample utterances to have a better idea of what's going on.</p>\n<h2>Intents</h2>\n<p>Intents are sort of like simplified Intents on android if you have every done Android coding. They signal an intention for a command to run to do something.</p>\n<p>Let's look at an example one to get an idea:</p>\n<pre><code>{\n "intents": [\n {\n "intent": "ResponseIntent",\n "slots": [\n {\n "name": "Answer",\n "type": "AMAZON.LITERAL"\n }\n ]\n },\n {\n "intent": "QuestionCountIntent",\n "slots": [\n {\n "name": "Count",\n "type": "AMAZON.NUMBER"\n }\n ]\n },\n {\n "intent": "AMAZON.HelpIntent"\n }\n ]\n}\n</code></pre>\n<p>Here this application can trigger 3 intents: ResponseIntent, QuestionCountIntent, and HelpIntent. You use JSON to tell it what these are.\nYou can define 'slots' which is the expected responses which are comprised of a name and Type. There are pre-defined data types you can use\nto help amazon parse what is said (Number for example knows the user is going to say a number. Literal is a simple String. Some intents don't need anything\nas they are 'built in' like the help intent (no inputs).</p>\n<p>A little bit about slots - they are entirely optional. You can do things like define a list of allowed responses (custom slots) that are valid things for the user to say.\nIn this case the ResponseIntent is free form, and we sort out what we want to do by parsing the string we get from Amazon (translated via TTS).</p>\n<h2>Sample Utterances</h2>\n<p>Let's look at another example:</p>\n<pre><code>ResponseIntent {test|Answer}\nResponseIntent {last player|Answer}\nResponseIntent {test test|Answer}\nResponseIntent {test test test|Answer}\nResponseIntent {test test test test|Answer}\nQuestionCountIntent {Count} questions\n</code></pre>\n<p>Here we see the intent each utterances (what the person says) and map it to an intent. Amazon will generate common words like conjunctions and ignored things on their\nend so you don't have to mess with handling things like 'and', 'the', 'or' etc. Variables are surrounded by {}. You can use the | operator to specify alternate options.\nIf you want to say something to your skill, it must match the pattern here. For this case, we want to parse multi-world answers to a question.\nBasically here we support one, two, three of four word responses - anything else will be cut off/ignored. The last item allows the user to answer how many questions they want to be asked.</p>\n<h2>Requirements</h2>\n<ul>\n<li>A publicly available container(Self running Grails jar, Tomcat, Elastic Beanstalk, etc) to launch your app with HTTPS on port 443 (no way around this). Can be self-signed for DEV mode only.</li>\n<li>If you want to use audio snippets via SSML they must be hosted as above but with a recognized CA (no self-signed). S3 Static HTTPS buckets are easiest.</li>\n<li>SSL Certificate common name MUST match hostname (even for self-signed DEV certs)</li>\n</ul>\n<h2>Let's make a Grails app using the plugin and I will explain more as we go</h2>\n<p>The plugin is for Grails 3.x only. Let's create a new app first:</p>\n<pre><code>grails create-app skillsTest\n</code></pre>\n<p>Now lets open build.gradle and add the plugin into the dependencies {} closure:</p>\n<pre><code>compile "org.grails.plugins:alexa-skills:0.1.1"\n</code></pre>\n<p>Now let's create a skill from the command line:</p>\n<pre><code>grails create-speechlet SkillsTest\n| Rendered template Speechlet.groovy to destination grails-app/speechlets/skillstest/SkillsTestSpeechlet.groovy\n</code></pre>\n<p>Now let's see what it's created in grails-app/speechlets:</p>\n<pre><code>\n@Slf4j\nclass SkillsTestSpeechlet implements GrailsConfigurationAware, Speechlet {\n\n def grailsApplication\n\n Config grailsConfig\n def speechletService\n\n\n def index() {\n speechletService.doSpeechlet(request,response, this)\n }\n\n /**\n * This is called when the session is started\n * Add an initialization setup for the session here\n * @param request SessionStartedRequest\n * @param session Session\n * @throws SpeechletException\n */\n public void onSessionStarted(final SessionStartedRequest request, final Session session)\n throws SpeechletException {\n log.info("onSessionStarted requestId={}, sessionId={}", request.getRequestId(),\n session.getSessionId())\n\n }\n\n /**\n * This is called when the skill/speechlet is launched on Alexa\n * @param request LaunchRequest\n * @param session Session\n * @return\n * @throws SpeechletException\n */\n public SpeechletResponse onLaunch(final LaunchRequest request, final Session session)\n throws SpeechletException {\n log.info("onLaunch requestId={}, sessionId={}", request.getRequestId(),\n session.getSessionId())\n\n return getWelcomeResponse()\n }\n\n /**\n * This is the method fired when an intent is called\n *\n * @param request IntentRequest intent called from Alexa\n * @param session Session\n * @return SpeechletResponse tell or ask type\n * @throws SpeechletException\n */\n public SpeechletResponse onIntent(final IntentRequest request, final Session session)\n throws SpeechletException {\n log.info("onIntent requestId={}, sessionId={}", request.getRequestId(),\n session.getSessionId())\n\n log.debug("invoking intent:${intentName}")\n PlainTextOutputSpeech speech = new PlainTextOutputSpeech()\n // Create the Simple card content.\n SimpleCard card = new SimpleCard(title:"Twitter Search Results")\n def speechText = "I will say something"\n def cardText = "I will print something"\n // Create the plain text output.\n speech.setText(speechText)\n card.setContent(cardText)\n SpeechletResponse.newTellResponse(speech, card)\n\n }\n /**\n * Grails config is injected here for configuration of your speechlet\n * @param co Config\n */\n void setConfiguration(Config co) {\n this.grailsConfig = co\n }\n\n /**\n * this is where you do session cleanup\n * @param request SessionEndedRequest\n * @param session\n * @throws SpeechletException\n */\n public void onSessionEnded(final SessionEndedRequest request, final Session session)\n throws SpeechletException {\n log.info("onSessionEnded requestId={}, sessionId={}", request.getRequestId(),\n session.getSessionId())\n // any cleanup logic goes here\n }\n\n SpeechletResponse getWelcomeResponse() {\n String speechText = "Say something when the skill starts"\n\n // Create the Simple card content.\n SimpleCard card = new SimpleCard(title: "YourWelcomeCardTitle", content: speechText)\n\n // Create the plain text output.\n PlainTextOutputSpeech speech = new PlainTextOutputSpeech(text:speechText)\n\n // Create reprompt\n Reprompt reprompt = new Reprompt(outputSpeech: speech)\n\n SpeechletResponse.newAskResponse(speech, reprompt, card)\n }\n\n /**\n * default responder when a help intent is launched on how to use your speechlet\n * @return\n */\n SpeechletResponse getHelpResponse() {\n String speechText = "Say something when the skill need help"\n // Create the Simple card content.\n SimpleCard card = new SimpleCard(title:"YourHelpCardTitle",\n content:speechText)\n // Create the plain text output.\n PlainTextOutputSpeech speech = new PlainTextOutputSpeech(text:speechText)\n // Create reprompt\n Reprompt reprompt = new Reprompt(outputSpeech: speech)\n SpeechletResponse.newAskResponse(speech, reprompt, card)\n }\n\n /**\n * if you are using account linking, this is used to send a card with a link to your app to get started\n * @param session\n * @return\n */\n SpeechletResponse createLinkCard(Session session) {\n\n String speechText = "Please use the alexa app to link account."\n // Create the Simple card content.\n LinkAccountCard card = new LinkAccountCard()\n // Create the plain text output.\n PlainTextOutputSpeech speech = new PlainTextOutputSpeech(text:speechText)\n log.debug("Session ID=${session.sessionId}")\n // Create reprompt\n Reprompt reprompt = new Reprompt(outputSpeech: speech)\n SpeechletResponse.newTellResponse(speech, card)\n }\n\n}\n\n</code></pre>\n<p>Also the plugin will generate a Controller class embedded in your Speechlet file. If you are using Spring Security, you will want to make sure that uri is\nassessable to the outside to the Alexa service can contact it (there are some requirements I'll fill you in on later):</p>\n<pre><code>\n/**\n * this controller handles incoming requests - be sure to white list it with SpringSecurity\n * or whatever you are using\n */\n@Controller\nclass SkillsTestController {\n\n def speechletService\n def skillsTestSpeechlet\n\n\n def index() {\n speechletService.doSpeechlet(request,response, skillsTestSpeechlet)\n }\n\n}\n\n</code></pre>\n<p>The speechlet artefact will be registered as a Spring bean so it's automatically injected. There is also a service the plugin provides to handle the boring\nstuff like verifying the request, checking the app ID (more on that later) and the plumbing that calls your skill.</p>\n<h2>Built-in Events</h2>\n<p>Looking at the code example above, you can see it made several methods for you. These are part of the skill(speechlet) lifecycle.\nThe first one is:</p>\n<h3>onSessionStarted</h3>\n<p>This allows you to store variables for the duration of the session (the interactions as a whole of the app for that time). You can do\nsome setup here and store variables you can use later. This is technically optional for you to implement.</p>\n<h3>onLaunch</h3>\n<p>This is called when you invoke the skill. When you say 'Alexa open skillTest' etc this is you chance to say an opening message about your app, what it does, or what they will\nneed to do.</p>\n<h3>onIntent</h3>\n<p>This is the meat and is required to be implemented. When your sample utterances maps to an Intent when the user says something this is invoked.\nHere you should generate a card that will appear in the Alexa app on your phone (you can also get to this on your local network via browser by going to 'echo.amazon.com'.\nCards are similar to Android cards (more popular in Android Wear) that simply show a message to the user they can see what is going on. You can make several kinds\nof cards which are Simple, Standard, and LinkAccount. Here we have a switch statement to figure out what Intent to process and call the code for the appropriate intent.</p>\n<h3>onSessionEnded</h3>\n<p>This is the last one, optional, where you can clean up and session resources you might have created like database records for the run.</p>\n<p>I've added a few other helper methods to see how to render a help response, link an account, and get some setup details from the Grails config. As a first pass, just try to get the default template working, then start to change things like changing the text, add an Intent, etc.</p>\n<h2>Set up your app on Amazon Developer Portal</h2>\n<p>This is separate from AWS. I am not aware of any APIs that will create all of this for you so you have to sign up for an account and do this by hand for each skill you want to run.</p>\n<img src=\"http://grailsblog.ociweb.com/images/alexa/developerportal-1.png\"/>\n<ul>\n<li>\n<p>Pull down the 'twitterAuth' app <a href=\"https://github.com/rvanderwerf/twitterAuth\">here</a> to get some Intents/Sample utterances to try. They are located in src/main/resources.</p>\n</li>\n<li>\n<p>Sign up for the Amazon developer program <a href=\"https://developer.amazon.com\">here</a> if you haven't already</p>\n</li>\n<li>\n<p>Click on Apps and Services -> Alexa</p>\n</li>\n<li>\n<p>Click on Alexa Skill Kit / Get Started -> Add New Skill</p>\n</li>\n</ul>\n<img src=\"http://grailsblog.ociweb.com/images/alexa/developerportal2.png\"/>\n<ul>\n<li>Pick any name and any invocation name you want to start the app on your Echo / Alexa Device</li>\n</ul>\n<img src=\"http://grailsblog.ociweb.com/images/alexa/developerportal3.png\"/>\n<ul>\n<li>\n<p>Copy the contents of src/main/resources/IntentSchema.json into Intent Schema.</p>\n</li>\n<li>\n<p>Don't fill in anything for slots</p>\n</li>\n<li>\n<p>Under Sample Utterances, copy the contents of the file src/main/resources/SampleUtterances.txt</p>\n</li>\n</ul>\n<img src=\"http://grailsblog.ociweb.com/images/alexa/developerportal4.png\"/>\n<ul>\n<li>\n<p>Under configuration Copy the url for /twitterAuth/twitter/index for the endpoint for your server (Choose amazon https not ARN). Click next</p>\n</li>\n<li>\n<p>Leave 'enable account linking' turned off.</p>\n</li>\n<li>\n<p>For domain list, enter a domain that matches your SSL cert the oauth tokens will be valid for. You may use a self-signed cert for development mode, but if you want to\npublish your skill, your server will need to be running a real recognized certificate (a cheap option is RapidSSL).</p>\n</li>\n<li>\n<p>Enter the url for the privacy policy on your server. It can be any valid web page, a link will show during account linking in the alexa app</p>\n</li>\n<li>\n<p>Hit Save</p>\n</li>\n<li>\n<p>Click on SSL Certificate. If you have a self-signed cert (will only work for DEV mode) paste it here under 'I will upload a self-signed certificate in X.509 format.'</p>\n</li>\n<li>\n<p>Hit Save and go to Test page and hit Save</p>\n</li>\n</ul>\n<img src=\"http://grailsblog.ociweb.com/images/alexa/developerportal5.png\"/>\n<ul>\n<li>Go to Privacy and Compliance, and fill out the info there (It's required)</li>\n</ul>\n<p>Now note the application ID it gives you. You will need to add this to the application.groovy/yml file so the application will know the app ID and accept it.</p>\n<p>Copy the application ID on the first tab 'SKILL INFORMATION', and paste that into application.groovy</p>\n<pre><code>alexaSkills.supportedApplicationIds="amzn1.echo-api.request.8bd8f02f-5b71-4404-a121-1b0385e56123,amzn1.echo-sdk-ams.app.84d004e5-e084-4087-a8c3-a80b12fd2009,amzn1.echo-sdk-ams.app.dc1dea0e-ab91-446d-a1c7-460df5e83489"\nalexaSkills.disableVerificationCheck = true // helpful for debugging or replay a command via curl\nalexaSkills.serializeRequests = true // this logs the requests to disk to help you debug\nalexaSkills.serializeRequestsOutputPath = "/tmp/"\n</code></pre>\n<p>Build and deploy your war file to your server (btw it must be port 443 HTTPS, no exceptions)</p>\n<h2>Test your app</h2>\n<p>Now try it on your Echo/Alexa device. Say either 'start' or 'open' and the invocation name you gave the app and follow the prompts! You can also use the test function on the portal itself.</p>\n<h2>Debugging</h2>\n<p>Debugging can be very frustrating. Make sure to turn your log level to debug. In the Grails config, the there is an option called 'serializeRequests' and a output path for them.\nThis allows you to capture the request that came from Amazon. If you are trying to test a fix for a bug, you can replay this via CURL. The files will look like this:</p>\n<pre><code>-rw-r--r-- 1 tomcat tomcat 598 Jun 6 22:45 speechlet-1465249551692.out\n-rw-r--r-- 1 tomcat tomcat 636 Jun 6 22:45 speechlet-1465249557538.out\n-rw-r--r-- 1 tomcat tomcat 598 Jun 6 22:46 speechlet-1465249601675.out\n-rw-r--r-- 1 tomcat tomcat 636 Jun 6 22:46 speechlet-1465249607216.out\n</code></pre>\n<p>The build-in security provided by the plugin and underlying library will now allow you to reuse a request because the hash ahd timestamps are too old (to prevent this type of attack called a 'replay attack'). You can disable this check for dev purposes with the 'disableVerificationCheck' Grails config value.\nNow you can replay a file via CURL back to your server to avoid the whole voice interaction to test that one case (and test it locally!):</p>\n<pre><code>curl -vX POST http://localhost:8080/test/index -d @speechlet-14641464378122470.out --header "Content-Type: application/json"\n</code></pre>\n<p>If you save enough requests of a normal interaction, you could write some functional tests that replay this as part of a test suite or just be able to dev against them locally a bit.</p>\n<h2>Advanced stuff - full UI with Spring Security, OAuth</h2>\n<p>If your want a UI for the user and use account linking, an easy path is to add Spring Security, Spring Security UI, Spring Security OAuth grails plugins.\nYou can see an example of how to do this <a href=\"https://github.com/rvanderwerf/twitterAuth\">here</a>.</p>\n<h2>Advanced stuff - say sample audio clips in your skill</h2>\n<p>There is a supported markup called SSML which allows up to 90 seconds of low quality mp3 sound clips to play. Their settings/requirements are quick picky to work:</p>\n<ul>\n<li>Must be hosted on a recognized CA HTTPS port 443 server (I use S3 static website for this)</li>\n<li>Must be 16khz, 48 kb/s MP3 files</li>\n<li>Use the open source tool 'ffmpeg' to encode them - these settings work: 'ffmpeg -y -i -ar 16000 -ab 48k -codec:a libmp3lame -ac 1 file.mp3'</li>\n<li>See the <a href=\"https://github.com/rvanderwerf/heroQuiz\">heroQuiz</a> app for an example of playback sounds being used.</li>\n</ul>\n<h3>Example SSML:</h3>\n<pre><code> <speak>\n <audio src="\\"https://s3.amazonaws.com/vanderfox-sounds/groovybaby1.mp3\\"/"> ${speechText}\n </audio>\n </speak>\n</code></pre>\n<h2>Useful links</h2>\n<ul>\n<li>Emulator: <a href=\"https://echosim.io\">https://echosim.io</a></li>\n<li>Account Linking: <a href=\"https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/linking-an-alexa-user-with-a-user-in-your-system\">https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/linking-an-alexa-user-with-a-user-in-your-system</a></li>\n<li>Getting Started Guide: <a href=\"https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/getting-started-guide\">https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/getting-started-guide</a></li>\n<li>Custom Skill Overview: <a href=\"https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/overviews/understanding-custom-skills\">https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/overviews/understanding-custom-skills</a></li>\n<li>Defining the Voice Interface: <a href=\"https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/defining-the-voice-interface\">https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/defining-the-voice-interface</a></li>\n<li>Voice Design Handbook: <a href=\"https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/alexa-skills-kit-voice-design-handbook\">https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/alexa-skills-kit-voice-design-handbook</a></li>\n<li>Custom Skill JSON reference: <a href=\"https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/alexa-skills-kit-interface-reference\">https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/alexa-skills-kit-interface-reference</a></li>\n<li>SSML Reference: <a href=\"https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/speech-synthesis-markup-language-ssml-reference\">https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/speech-synthesis-markup-language-ssml-reference</a></li>\n</ul>\n<hr />\n<h2>Conclusion</h2>\n<p>The Alexa service is a great invention that is catching on. Google and Apple are dipping their toes into the market. I see the star trek experience in the home\nbeing a reality for everyone in a few years. Already my wife uses it (who swore she never would), and my 4 year old asks it to tell her jokes all the time. I use it to control my lights very often. The sky is the limit, and these tools can be useful in the workplace too. Get out there and build some neat stuff for Alexa with Grails!</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "angular-annotate-asset-pipeline", |
| "repo": "asset-pipeline", |
| "owner": "craigburke", |
| "desc": "AngularJS Annotate for Asset Pipeline 2.0+", |
| "labels": [ |
| "angular-1" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/craigburke/angular-annotate-asset-pipeline/issues", |
| "latestVersion": "2.4.1", |
| "updated": "2016-05-13T16:12:37.000Z", |
| "systemIds": [ |
| "com.craigburke.angular:angular-annotate-asset-pipeline" |
| ], |
| "vcsUrl": "https://github.com/craigburke/angular-annotate-asset-pipeline" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/com/craigburke/angular/angular-annotate-asset-pipeline/maven-metadata.xml", |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "angular-scaffolding", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Provides scaffolding for AngularJS 1.x applications", |
| "labels": [ |
| "angular-1" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/grails-angular-scaffolding/issues", |
| "latestVersion": "2.0.1", |
| "updated": "2023-03-07T06:34:49.000Z", |
| "systemIds": [ |
| "org.grails.plugins:angular-scaffolding" |
| ], |
| "vcsUrl": "https://github.com/grails/grails-angular-scaffolding" |
| }, |
| "documentationUrl": "https://grails.github.io/grails-angular-scaffolding/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/grails/plugins/angular-scaffolding/maven-metadata.xml", |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "angular-template-asset-pipeline", |
| "repo": "asset-pipeline", |
| "owner": "craigburke", |
| "desc": "AngularJS Templates for Asset Pipeline 2.0+", |
| "labels": [ |
| "angular-1", |
| "asset-pipeline" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/craigburke/angular-template-asset-pipeline/issues", |
| "latestVersion": "2.4.0", |
| "updated": "2017-07-03T19:47:23.923Z", |
| "systemIds": [ |
| "com.craigburke.angular:angular-template-asset-pipeline" |
| ], |
| "vcsUrl": "https://github.com/craigburke/angular-template-asset-pipeline" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/com/craigburke/angular/angular-template-asset-pipeline/maven-metadata.xml", |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "angular2-scaffolding", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Provides scaffolding for Angular 2 applications", |
| "labels": [ |
| "angular-2" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/grails-angular2-scaffolding/issues", |
| "latestVersion": "1.0.0.RC1", |
| "updated": "2017-03-27T17:02:14.861Z", |
| "systemIds": [ |
| "org.grails.plugins:angular2-scaffolding" |
| ], |
| "vcsUrl": "https://github.com/grails-plugins/grails-angular2-scaffolding" |
| }, |
| "documentationUrl": "https://grails-plugins.github.io/grails-angular-scaffolding/latest/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails 3 Angular Scaffolding Plugin</h1>\n<p><a href=\"https://travis-ci.org/grails-plugins/grails-angular-scaffolding\"><img src=\"https://travis-ci.org/grails-plugins/grails-angular-scaffolding.svg?branch=master\" alt=\"Build Status\" /></a></p>\n<p>A plugin for generating client side assets based on domain classes</p>\n<h2>Documentation</h2>\n<p>Latest: https://grails-plugins.github.io/grails-angular-scaffolding/latest\nSnapshot: https://grails-plugins.github.io/grails-angular-scaffolding/snapshot</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "angularjs-scaffolding", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Provides scaffolding for AngularJS 1.x applications", |
| "labels": [ |
| "angular-1" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/grails-angularjs-scaffolding/issues", |
| "latestVersion": "1.0.3", |
| "updated": "2017-04-11T14:05:27.613Z", |
| "systemIds": [ |
| "org.grails.plugins:angularjs-scaffolding" |
| ], |
| "vcsUrl": "https://github.com/grails-plugins/grails-angularjs-scaffolding" |
| }, |
| "documentationUrl": "https://grails-plugins.github.io/grails-angularjs-scaffolding/latest/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails 3 AngularJS Scaffolding Plugin</h1>\n<p><a href=\"https://travis-ci.org/grails-plugins/grails-angularjs-scaffolding\"><img src=\"https://travis-ci.org/grails-plugins/grails-angularjs-scaffolding.svg?branch=master\" alt=\"Build Status\" /></a></p>\n<p>A plugin for generating client side assets based on domain classes</p>\n<h2>Documentation</h2>\n<p>http://grails-plugins.github.io/grails-angularjs-scaffolding/latest</p>\n" |
| }, |
| { |
| "deprecated": "Source repository is archived and no Grails >= 3 plugin library published. This entry should probably be removed from the registry.", |
| "bintrayPackage": { |
| "name": "anthofo.plugins:json-annotations-marshaller", |
| "repo": "plugins", |
| "owner": "anthofo", |
| "desc": "Grails json-annotations-marshaller plugin", |
| "labels": [ |
| "json" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/anthofo/grails3-json-annotations-marshaller/issues", |
| "latestVersion": "1.0", |
| "updated": "2016-03-31T16:14:33.462Z", |
| "systemIds": [ |
| |
| ], |
| "vcsUrl": "https://github.com/anthofo/grails3-json-annotations-marshaller" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>json-apis</h1>\n<h2>Grails plugin for managing multiple JSON apis using domain class annotations</h2>\n<p>The goal of this plugin is to help convert Grails domain classes into various\nJSON representations needed in different parts of your web application or to\nsupport various API versions.</p>\n<p>Features:</p>\n<ul>\n<li>Allows you to declare multiple named JSON configurations for different use cases</li>\n<li>Configuration is very straightforward: all that is required is to mark domain class\nproperties with a single annotation naming the configurations under which that\nproperty should be included in the serialized JSON object</li>\n<li>Works for collections as well as <code>belongsTo</code> properties</li>\n<li>Enables developers to avoid the circular object reference problem elegantly by\ndefining appopriate namespaces - this way it is possible to start the serialization\neither in a parent or child entity, depending on the use case</li>\n<li>Works for objects serialized inside a <a href=\"http://grails.org/doc/latest/guide/theWebLayer.html#moreOnJSONBuilder\">JSON builder</a></li>\n<li>Uses the Grails' <code>ObjectMarshaller</code> mechanism under the hood</li>\n<li>Detects API changes during development time live reloads</li>\n</ul>\n<h2>Example of use</h2>\n<p>Several API variants can be easily defined in domain classes by annotating properties with\n<code>JsonApi</code> and providing a list of API profile names under which that property should appear in the\nresulting JSON. Marking a property with the <code>JsonApi</code> annotation but providing no API names will\ninclude that property in all APIs. The database identity property will always be included\nautomatically. One could for instance define the following domain class:</p>\n<pre><code class=\"language-groovy\">import grails.plugins.jsonapis.JsonApi\n\nclass User {\n\t@JsonApi\n\tString screenName\n\n\t@JsonApi('userSettings')\n\tString email\n\n\t@JsonApi(['userSettings', 'detailedInformation'])\n\tString twitterUsername\n}\n</code></pre>\n<p>Then in the controller one would call the desired named JsonApi configuration to get only\nthe fields defined for that API. The following code:</p>\n<pre><code class=\"language-groovy\">JSON.use("detailedInformation")\nrender person as JSON\n</code></pre>\n<p>...would convert the <code>person</code> object into JSON containing the <code>id</code>, <code>screenName</code> and <code>twitterUsername</code>\nproperties but not the <code>email</code>. It works for collections as well, converting each collection\nmember using the same API profile that was used to convert the parent:</p>\n<pre><code class=\"language-groovy\">static hasMany = [\n\tpets: Pet\n]\n@JsonApi('detailedInformation')\nSet pets\n</code></pre>\n<p>To include a domain object's parent in a JSON API, declare a <code>belongsTo</code> property explicitly\nand annotate it with <code>JsonApi</code> (but be careful not to create circular paths by including both\nends of a <code>belongsTo</code>/<code>hasMany</code> pair):</p>\n<pre><code class=\"language-groovy\">static belongsTo = [\n\tuser:User\n]\n\n@JsonApi('petDetails') \nUser user\n</code></pre>\n<p>JSONBuilder is supported, too:</p>\n<pre><code class=\"language-groovy\">JSON.use("userSettings")\nrender(contentType: "text/json") {\n user = User.first()\n pet = Pet.first()\n}\n</code></pre>\n<h2>Future plans</h2>\n<ul>\n<li>Detect circular APIs and display a warning on startup, perhaps disable them entirely</li>\n<li>Add a script/controller that would document the registered APIs in one or more formats</li>\n<li>Read the domain class annotations and produce configurations for those 3rd party JSON\nrenderers which currently seem to perform better than the native Grails implementation</li>\n</ul>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "application-config", |
| "repo": "plugins", |
| "owner": "neilab", |
| "desc": "Allows external configuration via grails.config.locations, JNDI, and system properties", |
| "labels": [ |
| "config" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/neilabdev/application-config/issues", |
| "latestVersion": "1.1.3", |
| "updated": "2018-08-08T12:58:00.158Z", |
| "systemIds": [ |
| "com.neilab.plugins:application-config" |
| ], |
| "vcsUrl": "https://github.com/neilabdev/application-config" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Application-Config</h1>\n<p><a href=\"https://travis-ci.org/neilabdev/application-config\"><img src=\"https://travis-ci.org/neilabdev/application-config.svg?branch=master\" alt=\"Build Status\" /></a></p>\n<p>This plugin based on the amazing work started in plugin <a href=\"http://plugins.grails.org/plugin/grails/external-config\">external-config</a> by <a href=\"https://github.com/snimavat\">Sudhir Nimavat</a> and <a href=\"https://github.com/tkvw\">Dennie de Lange</a>,\nwhich mimiced the Grails 2 way of handling external configurations defined in <code>grails.config.locations</code>; with the necessary additions to allow configurations via command line, system properties, and JNDI.</p>\n<h2>Contributors</h2>\n<ul>\n<li><a href=\"https://github.com/neilabdev\">neilabdev</a></li>\n</ul>\n<h2>Installation</h2>\n<p>Add dependency to your <code>build.gradle</code>:</p>\n<pre><code>dependencies {\n compile 'com.neilab.plugins:application-config:1.1.3'\n}\n</code></pre>\n<h2>Usage</h2>\n<p>When you add this plugin to your Grails build, it will automatically look for the property <code>grails.config.locations</code>. Define this in in either <code>application.yml</code> like this:</p>\n<pre><code>grails:\n config:\n locations:\n - classpath:myconfig.groovy\n - classpath:myconfig.yml\n - classpath:myconfig.properties\n - file:///etc/app/myconfig.groovy\n - file:///etc/app/myconfig.yml\n - file:///etc/app/myconfig.properties\n - ~/.grails/myconfig.groovy\n - ~/.grails/myconfig.yml\n - ~/.grails/myconfig.properties\n - file:${catalina.base}/myconfig.groovy\n - file:${catalina.base}/myconfig.yml\n - file:${catalina.base}/myconfig.properties\n</code></pre>\n<p>or in <code>application.groovy</code> like this:</p>\n<pre><code>grails.config.locations = [\n "classpath:myconfig.groovy",\n "classpath:myconfig.yml",\n "classpath:myconfig.properties",\n "file:///etc/app/myconfig.groovy",\n "file:///etc/app/myconfig.yml",\n "file:///etc/app/myconfig.properties",\n "~/.grails/myconfig.groovy",\n "~/.grails/myconfig.yml",\n "~/.grails/myconfig.properties",\n 'file:${catalina.base}/myconfig.groovy',\n 'file:${catalina.base}/myconfig.yml',\n 'file:${catalina.base}/myconfig.properties',\n]\n</code></pre>\n<p>You may also include external configs using '-D' arguments which match the system properties\nthe application is seeking, preceded by an application prefix determined by <em>info.app.name</em> in your default <em>application.yml</em>, <em>application.groovy</em> or "app" if none exists. By default the following should work:</p>\n<pre><code>-DappName.config="/path/to/config"\n-DappName.external.config="/path/to/config"\n-DappName.database.config="/path/to/config"\n-DappName.logging.config="/path/to/config"\n\n</code></pre>\n<p>or using JNDI variables <em>CONFIG</em>, <em>EXTERNAL_CONFIG</em>, <em>LOGGING_CONFIG</em>, <em>DATABASE_CONFIG</em> in tomcat for example:</p>\n<pre><code class=\"language-xml\"><Context path="" docBase="/path/to/app.war" reloadable="false">\n <Environment name="APP_CONFIG"\n value="file:/path/to/external_config.groovy"\n type="java.lang.String"/>\n <Environment name="DATABASE_CONFIG"\n value="file:/path/to/external_config.database.groovy"\n type="java.lang.String"/>\n</Context>\n</code></pre>\n<p>While no-longer necessary as of version 1.1.0 of <a href=\"http://plugins.grails.org/plugin/grails/external-config\">external-config</a>, which this fork is based, for comparability you may edit your Grails projects <code>Application.groovy</code> and implement the trait <code>com.neilab.plugins.config.ApplicationConfig</code> (formally ExternalConfig):</p>\n<pre><code>import com.neilab.plugins.config.ApplicationConfig\n\nclass Application extends GrailsAutoConfiguration implements ApplicationConfig {\n static void main(String[] args) {\n GrailsApp.run(Application, args)\n }\n}\n</code></pre>\n<p>This above is necessary only when <em>ApplicationConfigRunListener</em> is not executed, and personally have used it only when developing the plugin as an inline plugin where <em>SpringApplicationRunListener</em> was not loaded.</p>\n<h2>Notes</h2>\n<p>Notice, that <code>~/</code> references the users <code>$HOME</code> directory.\nNotice, that using a system property you should use single quotes because otherwise it's interpreted as a Gstring.</p>\n<p>The plugin will skip configuration files that are not found.</p>\n<p>For <code>.groovy</code> and <code>.yml</code> files the <code>environments</code> blocks in the config file are interpreted the same way, as in <code>application.yml</code> or <code>application.groovy</code>.</p>\n<p>Alternatively, you can make a gradle script to move the external configuration file to your classpath (e.g. /build/classes)</p>\n<p><strong>Using IntelliJ or gradle to specify configurations via system properties</strong></p>\n<p>When passing system properties via <em>VM Options</em> in IntelliJ or <em>-D</em> properties in gradle, it may be necessary to assign the parameters to the app via <em>bootRun</em> in your <em>build.gradle</em> configuration.</p>\n<pre><code class=\"language-groovy\">//build.gradle\nbootRun {\n systemProperties = System.properties\n}\n</code></pre>\n<h2>Scripts</h2>\n<p>This plugin also includes two scripts, one for converting yml config, to groovy config,\nand one for converting groovy config to yml config. These scripts are not guaranteed to be\nperfect, but you should report any edge cases for the yml to groovy config here:\nhttps://github.com/virtualdogbert/GroovyConfigWriter/issues</p>\n<p>Sample usage:</p>\n<pre><code>grails yml-to-groovy-config [ymlFile] [optional outputFile]\ngrails groovy-to-yml-config [ymlFile] [optional outputFile]\n</code></pre>\n" |
| }, |
| { |
| "deprecated": "This entry in the registry seems to be a duplicate of the entry named 'asset-pipeline-grails'. It should probably be removed from the registry to avoid confusion.", |
| "bintrayPackage": { |
| "name": "asset-pipeline", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Grails asset-pipeline plugin", |
| "labels": [ |
| "asset-pipeline" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/bertramdev/asset-pipeline/issues", |
| "latestVersion": "3.2.1", |
| "updated": "2017-01-26T14:06:25.984Z", |
| "systemIds": [ |
| "org.grails.plugins:asset-pipeline" |
| ], |
| "vcsUrl": "https://github.com/bertramdev/asset-pipeline" |
| }, |
| "documentationUrl": "https://bertramdev.github.io/asset-pipeline/", |
| "mavenMetadataUrl": null, |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "asset-pipeline-grails", |
| "repo": "asset-pipeline", |
| "owner": "bertramlabs", |
| "desc": "The Asset-Pipeline is a plugin used for managing and processing static assets in Grails applications. Asset-Pipeline functions include processing and minification of both CSS and JavaScript files. It is also capable of being extended to compile custom static assets, such as CoffeeScript.", |
| "labels": [ |
| "asset-pipeline" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/bertramdev/asset-pipeline/issues", |
| "latestVersion": "5.0.9", |
| "updated": "2025-04-13T23:19:59.000Z", |
| "systemIds": [ |
| "com.bertramlabs.plugins:asset-pipeline-grails" |
| ], |
| "vcsUrl": "https://github.com/bertramdev/asset-pipeline" |
| }, |
| "documentationUrl": "https://bertramdev.github.io/asset-pipeline/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/com/bertramlabs/plugins/asset-pipeline-grails/maven-metadata.xml", |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "asset-pipeline-handlebars-renderer", |
| "repo": "plugins", |
| "owner": "dpcasady", |
| "desc": "Grails asset pipeline handlebars templates renderer plugin", |
| "labels": [ |
| "asset-pipeline", |
| "handlebars" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/dpcasady/asset-pipeline-handlebars-renderer/issues", |
| "latestVersion": "0.1", |
| "updated": "2017-07-13T10:41:12.439Z", |
| "systemIds": [ |
| "org.grails.plugins:asset-pipeline-handlebars-renderer" |
| ], |
| "vcsUrl": "https://github.com/dpcasady/asset-pipeline-handlebars-renderer" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Asset Pipeline Handlebars Renderer Grails Plugin</h1>\n<p>This plugin provides for server side execution of <a href=\"http://handlebarsjs.com/\">Handlebars.js</a> templates. It is\nintended to compliment the <a href=\"https://github.com/bertramdev/asset-pipeline\">handlebars-asset-pipeline</a> plugin\nwhich compiles Handlebars templates into JavaScript for client side usage. The templates are compiled into Java\ncode using <a href=\"https://github.com/jknack/handlebars.java\">handlebars-java</a>.</p>\n<h2>Installation</h2>\n<p>Add to build.gradle</p>\n<pre><code>dependencies {\n compile "org.grails.plugins:asset-pipeline-handlebars-renderer:0.1"\n}\n</code></pre>\n<h2>Configuration</h2>\n<p>This plugin uses the same configuration as the <a href=\"https://github.com/bertramdev/asset-pipeline\">handlebars-asset-pipeline</a> plugin. Templates can be created in the standard assets/javascripts folder with an extension of .handlebars or .hbs. By default the <code>templateRoot</code> for your templates is specified as <code>templates</code>. This means that any handlebars file within assets/javascripts/templates/ will utilize its file name (without the extension) as its template name. So a template that lives at <code>assets/javascripts/templates/my_template.hbs</code> can be rendered as <code><handlebars:render template="my_template"/></code>.</p>\n<h2>Usage</h2>\n<p>A <code>handlebars:render</code> tag is provided to render handlebars templates similarly to how regular gsp templates are applied in views. Templates can be rendered inline:</p>\n<pre><code class=\"language-html\"><handlebars:render model="[name: 'bob']">\n <p>Hello {{name}}</p>\n</handlebars:render>\n</code></pre>\n<p>Or they can be stored in a separate file and referenced by name:</p>\n<pre><code class=\"language-html\"><handlebars:render template="home/hello" model="[name: 'bob']"/>\n</code></pre>\n<p>For the above example, (assuming the default <code>templateRoot</code>) the template would be located at <code>grails-app/assets/javascripts/templates/home/hello.hbs</code>.</p>\n<p>If no model is supplied then the default page bindings (page scope variables) are used:</p>\n<pre><code class=\"language-html\"><handlebars:render>\n Hello {{name}} from the controller\n</handlebars:render>\n</code></pre>\n<p>Behind the scenes, the taglib uses the <code>handlebarsService</code> to render templates. You can do the same if, for example, you want to render the template directly from a controller:</p>\n<pre><code class=\"language-groovy\">def handlebarsService\n\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ndef list() {\n render handlebarsService.apply("home/accounts", [accounts: Account.list()])\n}\n</code></pre>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "async", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Grails Async - Grails Async Libraries", |
| "labels": [ |
| "async" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/grails-async/issues", |
| "latestVersion": "5.0.2", |
| "updated": "2024-01-09T11:43:22.000Z", |
| "systemIds": [ |
| "org.grails.plugins:async" |
| ], |
| "vcsUrl": "https://github.com/grails/grails-async" |
| }, |
| "documentationUrl": "https://async.grails.org/latest/guide/index.html", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/grails/plugins/async/maven-metadata.xml", |
| "readme": "" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "asynchronous-mail", |
| "repo": "grails-asynchronous-mail", |
| "owner": "gpc", |
| "desc": "The plugin realises asynchronous mail sending. It stores messages in a DB and sends them asynchronously by a quartz job.", |
| "labels": [ |
| "async", |
| "mail" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/gpc/grails-asynchronous-mail/issues", |
| "latestVersion": "4.0.0", |
| "updated": "2026-01-05T12:51:15.000Z", |
| "systemIds": [ |
| "io.github.gpc:asynchronous-mail" |
| ], |
| "vcsUrl": "https://github.com/gpc/grails-asynchronous-mail" |
| }, |
| "documentationUrl": "https://github.com/gpc/grails-asynchronous-mail", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/io/github/gpc/asynchronous-mail/maven-metadata.xml", |
| "readme": "<p><a href=\"https://github.com/gpc/grails-asynchronous-mail\">See the README</a> on GitHub</p>" |
| }, |
| { |
| "comment": "Now lives in https://github.com/grails-plugins/", |
| "bintrayPackage": { |
| "name": "audit-logging", |
| "repo": "grails-audit-logging-plugin", |
| "owner": "grails-plugins", |
| "desc": "Grails Audit-Logging Plugin.", |
| "labels": [ |
| "auditing" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/grails-audit-logging-plugin/issues", |
| "latestVersion": "6.0.0", |
| "updated": "2025-10-20T12:53:14.971Z", |
| "systemIds": [ |
| "org.grails.plugins:audit-logging" |
| ], |
| "vcsUrl": "https://github.com/grails-plugins/grails-audit-logging-plugin" |
| }, |
| "documentationUrl": "https://grails-plugins.github.io/grails-audit-logging-plugin/latest/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails Audit Logging Plugin</h1>\n<p><a href=\"https://grails-plugins.github.io/grails-audit-logging-plugin/latest/\">Documentation</a></p>" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "audit-trail", |
| "repo": "grails-plugins", |
| "owner": "9ci", |
| "desc": "Audit Trails Grails Plugin", |
| "labels": [ |
| "auditing" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/9ci/grails-audit-trail/issues", |
| "latestVersion": "3.0.11", |
| "updated": "2020-05-06T09:27:41.033Z", |
| "systemIds": [ |
| "org.grails.plugins:audit-trail" |
| ], |
| "vcsUrl": "https://github.com/9ci/grails-audit-trail" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://circleci.com/gh/yakworks/view-tools\"><img src=\"https://img.shields.io/circleci/project/github/9ci/grails-audit-trail/master.svg?longCache=true&style=for-the-badge&logo=circleci\" alt=\"CircleCI\" /></a>\n<a href=\"http://9ci.com\"><img src=\"https://img.shields.io/badge/BUILT%20BY-9ci%20Inc-blue.svg?longCache=true&style=for-the-badge\" alt=\"9ci\" /></a>\n<img src=\"https://forthebadge.com/images/badges/built-with-love.svg\" height=\"28\">\n<a href=\"https://forthebadge.com\"><img src=\"https://forthebadge.com/images/badges/made-with-groovy.svg\" alt=\"forthebadge\" /></a>\n<img src=\"https://forthebadge.com/images/badges/gluten-free.svg\" height=\"28\">\n<a href=\"https://forthebadge.com\"><img src=\"https://forthebadge.com/images/badges/approved-by-george-costanza.svg\" alt=\"forthebadge\" /></a></p>\n<h2>Install</h2>\n<pre><code class=\"language-groovy\">compile "org.grails.plugins:audit-trail:3.0.11"\n\n</code></pre>\n<h1>Overview</h1>\n<p>This plugin lets you add an annotation to your domain classes so the necessary created/updated audit fields will get added. On save() the domain will get "stamped" after a new insert or update. This eliminates the need for setting up a base class.\nIt will automatically add fields based on your settings in Config.groovy.\nProvides an AST transformation annotation and hibernate events to take care of "stamping" for your gorm objects with the user who edited and/or created it as well as the edited and created dates.</p>\n<h1>Goals</h1>\n<ul>\n<li>DRY - setup config and then a single @gorm.AuditStamp on your domain will give the fields</li>\n<li>Eliminate the need for a base class to store audit fields</li>\n<li>Provide more the ability to configure the names of the date and user fields. It was a big break in our standard to use "dateCreated" and "lastUpdated"</li>\n<li>Keep the nullable:false constraint on the audit fields with the ability to configure and override it if need be.</li>\n<li>work with Joda or with normal Date</li>\n</ul>\n<h1>Using the @gorm.AuditStamp annotation</h1>\n<p>Add to your config.groovy each field you want added</p>\n<p>grails{\nplugin{\naudittrail{\t\ncreatedBy.field = "createdBy" //add whatever names you want used for the\neditedBy.field = "editedBy"\ncreatedDate.field = "createdDate"\neditedDate.field = "editedDate"\n}\n}\n}</p>\n<p>Add the annotation to your domain class</p>\n<pre><code>@gorm.AuditStamp\nclass Note{\n\tString note\n}\n</code></pre>\n<p>During compile time the AST transformation will add fields just as if you wrote your domain like so:</p>\n<pre><code>class Note{\n\tString note\n\t\n\tLong createdBy \n\tLong editedBy \n\tDate editedDate\n\tDate createdDate \n\t\n\tstatic constaints = {\n\t\tcreatedBy nullable:false,display:false,editable:false\n\t\teditedBy nullable:false,display:false,editable:false\n\t\teditedDate nullable:false,display:false,editable:false\n\t\tcreatedDate nullable:false,display:false,editable:false\n\t}\n\t\n\tdef beforeValidate() { //if this already existed then it just append the code\n\t\t//this sets the fields if this is a new (about to be inserted) instance \n\t\t...applicationContext.getBean('auditTrailHelper').initializeFields(this)\n\t}\n\t\n}\n</code></pre>\n<h2>No annotation</h2>\n<p>The annotation is just an AST transformation as a convenience. You can add the fields manually to your domains that match whats you have configured in config.grooy and the events will fire on those fields. This includes other hibernate/java entities.\nIt uses the AuditTrailInterceptor to stamp the fields on the hibernate objects if they exists.</p>\n<h1>Events and the interceptor</h1>\n<p>As seen in the above example, this allows you to keep your fields set to "nullable:false" since this annotation will add/append code to the beforeValidate() to make sure the fields are initialized properly. It also setups</p>\n<h2>Security</h2>\n<p>The plugin defaults to using Spring Security but it is not dependent on it. If no currentUserClosure</p>\n<h1>Configuration Options</h1>\n<p>The following show the options and defaults. For a field to be added by the annotation at least on config setting needs to be present.\nNOTE: Remember to clean and re-compile after changing the config settings. All of the mods to the domain happen with and AST at compile time.</p>\n<pre><code>grails{\n\tplugin{\n\t\taudittrail{\t\n\t\t\t// ** if field is not specified then it will default to 'createdBy'\n\t\t\tcreatedBy.field = "createdBy" // createdBy is default\n\t\t\t// ** fully qualified class name for the type\t\n\t\t\tcreatedBy.type = "java.lang.Long" //Long is the default\n\t\t\t// ** the constraints settings\n\t\t\tcreatedBy.constraints = "nullable:false,display:false,editable:false,bindable:false" \n\t\t\t// ** the mapping you want setup\n\t\t\tcreatedBy.mapping = "column: 'inserted_by'" //<-example as there are NO defaults for mapping\n\t\t\t\n\t\t\tcreatedDate.field = "createdDate"\n\t\t\tcreatedDate.type = "java.util.DateTime" \n\t\t\tcreatedDate.constraints = "nullable:false,display:false,editable:false,bindable:false" \n\t\t\tcreatedDate.mapping = "column: 'date_created'" //<-NOTE: example as there are NO defaults for mapping\n\t\t\t\n\t\t\tetc.....\n\t\t\t\n\t\t\t//custom closure to return the current user who is logged in\n\t\t\tcurrentUserClosure = {ctx->\n\t\t\t\t//ctx is the applicationContext\n\t\t\t\t//default is basically\n\t\t\t\treturn springSecurityService.principal?.id\n\t\t\t}\n\t\t\t//there are NO defaults for companyId.\n\t\t\tcompanyId.field = "companyId" //used for multi-tenant apps and is just the name of the field to use\n\t\t}\n</code></pre>\n<h2>Joda Time Example</h2>\n<p>this also shows how you can set your own currentUserClosure for stamping the user fields</p>\n<pre><code>grails{\n\tplugin{\n\t\taudittrail{\t\t\t\n\t\t\tcreatedBy.type = "java.lang.String" \n\t\t\n\t\t\teditedBy.type = "java.lang.String" \n\t\t\n\t\t\tcreatedDate.type = "org.joda.time.DateTime" \n\t\t\tcreatedDate.mapping = "type: org.jadira.usertype.dateandtime.joda.PersistentDateTime"\n\t\t\n\t\t\teditedDate.type = "org.joda.time.DateTime" \n\t\t\teditedDate.mapping = "type: org.jadira.usertype.dateandtime.joda.PersistentDateTime"\n\t\t\n\t\t\tcurrentUserClosure = {ctx->\n\t\t\t\treturn ctx.mySecurityService.currentUserLogin()\n\t\t\t}\n\t\t}\n\t}\n}\n</code></pre>\n<h1>Unit Testing</h1>\n<p>In Grails 2 the config is available in your unit tests so it makes setting things up a bit easier now.\ngrails.plugin.audittrail.AuditTrailHelper has a mockForUnitTest(config,userVal=1) to make unit testing easier.\npass userVal in as something else if you want some other default or some other type for your createdBy and editedBy.\nTake a look at the source if you want to see what its doing.</p>\n<pre><code>void testSave() {\n\tdef d = new TestDomain()\n\td.name = "test"\n\t//the AST from @gorm.AuditStamp adds a property "auditTrailHelper" to your domains\n\t//at run time it gets injected with the auditTrailHelper bean from the applicationContext\n\td.auditTrailHelper = AuditTrailHelper.mockForUnitTest(config)\n\td.save(failOnError:true)\n\tassert d.createdBy == 1 \n}\n</code></pre>\n<h1>changes from 1.2 -> 2.0 (many are breaking)</h1>\n<ul>\n<li>defaults on the added fields are now to set nullable:true and not have default values</li>\n<li>changed the name space in config from stamp.audit to grails.plugin.audittrail</li>\n<li>major config overhall so you can set types,constraints etc for each audit field</li>\n<li>there is now an ability to set your own currrentUserClosure and the dependency on SpringSecurity is gone.</li>\n</ul>\n<h1>changes in 2.0.4</h1>\n<ul>\n<li>added mockForUnitTest in AuditTrailHelper to make unit testing easier</li>\n<li>a transient auditTrailHelper to get the injected bean for each domain that is marked with @gorm.auditStamp. beforeValidate then calls this if its not null. This will make it easier to test</li>\n</ul>\n<h1>changes in 2.1</h1>\n<ul>\n<li>added default constraint for fields of bindable:false</li>\n<li>you can turn off audit trail for an instance by setting domainInstance.disableAuditTrailStamp = true</li>\n<li>refactor common stamp functions to AuditTrailHelper</li>\n</ul>\n<h3>Using AuditTrail in gradle multimodule projects</h3>\n<p>AuditTrail AST Transoformation reads audit trail related settings from application.groovy.\nAs long as the project with AuditStamp annotation is root gradle project, it works just fine.\nHowever when the project is a module of a multimodule gradle project, A system property needs to be set to aid AST tranformation class find the correct application.groovy from module directory.</p>\n<p>This can be achieved by setting the <code>module.path</code> in build.gradle of submodule as shown below.</p>\n<pre><code class=\"language-groovy\">compileGroovy {\n groovyOptions.fork = true\n String path = projectDir.absolutePath\n groovyOptions.forkOptions.jvmArgs = ['-Dmodule.path=' + path]\n}\n</code></pre>\n" |
| }, |
| { |
| "comment": "This entry in the registry is for the umbrella project for all the AWS plugins from agorapulse. Perhaps this entry is not necessary as each separate plugin also has its own entry?", |
| "bintrayPackage": { |
| "name": "aws-sdk", |
| "repo": "plugins", |
| "owner": "agorapulse", |
| "desc": "Grails AWS SDK plugin", |
| "labels": [ |
| "amazon", |
| "aws", |
| "cognito", |
| "dynamodb", |
| "kineses", |
| "s3", |
| "ses", |
| "sns", |
| "sqs", |
| "sts" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/agorapulse/grails-aws-sdk/issues", |
| "latestVersion": "2.4.15", |
| "updated": "2022-07-20T06:42:00.000Z", |
| "systemIds": [ |
| |
| ], |
| "vcsUrl": "https://github.com/agorapulse/grails-aws-sdk" |
| }, |
| "documentationUrl": "https://agorapulse.github.io/grails-aws-sdk/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>AWS SDK Grails Plugin</h1>\n<p><a href=\"https://travis-ci.org/agorapulse/grails-aws-sdk\"><img src=\"https://travis-ci.org/agorapulse/grails-aws-sdk.svg\" alt=\"Build Status\" /></a> <a href=\"https://bintray.com/agorapulse/plugins/aws-sdk-dynamodb/2.2.12/link\"><img src=\"https://api.bintray.com/packages/agorapulse/plugins/aws-sdk-dynamodb/images/download.svg?version=2.2.12\" alt=\"Download\" /></a></p>\n<h1>Introduction</h1>\n<p>The <a href=\"https://medium.com/@benorama/aws-sdk-plugins-for-grails-3-cc7f910fdc0d#.5gdwdxei3\">AWS SDK Plugins for Grails3</a> are a suite of plugins that adds support for the <a href=\"http://aws.amazon.com/\">Amazon Web Services</a> infrastructure services.</p>\n<p>The aim is to to get you started quickly by providing friendly lightweight utility <a href=\"http://grails.org\">Grails</a> service wrappers, around the official <a href=\"http://aws.amazon.com/sdkforjava/\">AWS SDK for Java</a> (which is great but very \ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdjava-esque\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd).\nSee <a href=\"https://medium.com/@benorama/aws-sdk-plugins-for-grails-3-cc7f910fdc0d#.5gdwdxei3\">this article</a> for more info.</p>\n<p>The following services are currently supported:</p>\n<ul>\n<li><a href=\"https://github.com/agorapulse/grails-aws-sdk/tree/master/grails-aws-sdk-cognito\">AWS SDK Cognito Grails Plugin</a></li>\n<li><a href=\"https://github.com/agorapulse/grails-aws-sdk/tree/master/grails-aws-sdk-dynamodb\">AWS SDK DynamoDB Grails Plugin</a></li>\n<li><a href=\"https://github.com/agorapulse/grails-aws-sdk/tree/master/grails-aws-sdk-kinesis\">AWS SDK Kinesis Grails Plugin</a></li>\n<li><a href=\"https://github.com/agorapulse/grails-aws-sdk/tree/master/grails-aws-sdk-s3\">AWS SDK S3 Grails Plugin</a></li>\n<li><a href=\"https://github.com/agorapulse/grails-aws-sdk/tree/master/grails-aws-sdk-ses\">AWS SDK SES Grails Plugin</a></li>\n<li><a href=\"https://github.com/agorapulse/grails-aws-sdk/tree/master/grails-aws-sdk-sns\">AWS SDK SNS Grails Plugin</a></li>\n<li><a href=\"https://github.com/agorapulse/grails-aws-sdk/tree/master/grails-aws-sdk-sqs\">AWS SDK SQS Grails Plugin</a></li>\n</ul>\n<p>Please check each README for usage info.</p>\n<h1>Testing</h1>\n<p><a href=\"https://medium.com/agorapulse-stories/how-to-unit-test-aws-services-with-localstack-and-testcontainers-1d39fe5dc6c2\">How to Unit Test AWS Services with LocalStack and Testcontainers</a></p>\n<h1>Bugs</h1>\n<p>To report any bug, please use the project <a href=\"http://github.com/agorapulse/grails-aws-sdk/issues\">Issues</a> section on GitHub.</p>\n<h1>Compatibilty</h1>\n<p>NOTE: For Grails 4 you should consider migrating to <a href=\"https://agorapulse.github.io/micronaut-aws-sdk/\">Micronaut AWS SDK</a> as Miconaut is now the first class citizen in Grails. Use <code>-micronaut-1.2</code> releases for Grails <code>4.0.x</code>.</p>\n<p>| Grails | Plugin |\n| ------------- |---------------|\n| 3.3.x, 4.x | 2.2.x |\n| 3.2.x | 2.1.x |\n| 2.x | 1.x |</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "aws-sdk-cognito", |
| "repo": "plugins", |
| "owner": "agorapulse", |
| "desc": "Grails AWS SDK Cognito plugin. Uses 'jitpack.io' maven repository.", |
| "labels": [ |
| "aws", |
| "cognito" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/agorapulse/grails-aws-sdk/issues", |
| "latestVersion": "2.4.15", |
| "updated": "2022-07-20T06:42:00.000Z", |
| "systemIds": [ |
| "com.github.agorapulse.grails-aws-sdk:aws-sdk-cognito" |
| ], |
| "vcsUrl": "https://github.com/agorapulse/grails-aws-sdk" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails AWS SDK Cognito Plugin</h1>\n<p>This repo has been migrated to the main <a href=\"https://github.com/agorapulse/grails-aws-sdk\">AWS SDK Grails Plugin</a> repo.</p>\n<p>Here his the <a href=\"https://github.com/agorapulse/grails-aws-sdk/tree/master/grails-aws-sdk-cognito\">latest version of it</a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "aws-sdk-dynamodb", |
| "repo": "plugins", |
| "owner": "agorapulse", |
| "desc": "Grails AWS SDK DynamoDB plugin. Uses 'jitpack.io' maven repository.", |
| "labels": [ |
| "aws", |
| "dynamodb" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/agorapulse/grails-aws-sdk/issues", |
| "latestVersion": "2.4.15", |
| "updated": "2022-07-20T06:42:00.000Z", |
| "systemIds": [ |
| "com.github.agorapulse.grails-aws-sdk:aws-sdk-dynamodb" |
| ], |
| "vcsUrl": "https://github.com/agorapulse/grails-aws-sdk" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails AWS SDK DynamoDB Plugin</h1>\n<p>This repo has been migrated to the main <a href=\"https://github.com/agorapulse/grails-aws-sdk\">AWS SDK Grails Plugin</a> repo.</p>\n<p>Here his the <a href=\"https://github.com/agorapulse/grails-aws-sdk/tree/master/grails-aws-sdk-dynamodb\">latest version of it</a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "aws-sdk-kinesis", |
| "repo": "plugins", |
| "owner": "agorapulse", |
| "desc": "Grails AWS SDK Kinesis plugin. Uses 'jitpack.io' maven repository.", |
| "labels": [ |
| "aws", |
| "kinesis" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/agorapulse/grails-aws-sdk/issues", |
| "latestVersion": "2.4.15", |
| "updated": "2022-07-20T06:42:00.000Z", |
| "systemIds": [ |
| "com.github.agorapulse.grails-aws-sdk:aws-sdk-kinesis" |
| ], |
| "vcsUrl": "https://github.com/agorapulse/grails-aws-sdk" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails AWS SDK Kinesis Plugin</h1>\n<p>This repo has been migrated to the main <a href=\"https://github.com/agorapulse/grails-aws-sdk\">AWS SDK Grails Plugin</a> repo.</p>\n<p>Here his the <a href=\"https://github.com/agorapulse/grails-aws-sdk/tree/master/grails-aws-sdk-kinesis\">latest version of it</a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "aws-sdk-s3", |
| "repo": "plugins", |
| "owner": "agorapulse", |
| "desc": "Grails AWS SDK S3 plugin. Uses 'jitpack.io' maven repository.", |
| "labels": [ |
| "aws", |
| "s3" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/agorapulse/grails-aws-sdk/issues", |
| "latestVersion": "2.4.15", |
| "updated": "2022-07-20T06:42:00.000Z", |
| "systemIds": [ |
| "com.github.agorapulse.grails-aws-sdk:aws-sdk-s3" |
| ], |
| "vcsUrl": "https://github.com/agorapulse/grails-aws-sdk" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails AWS SDK S3 Plugin</h1>\n<p>This repo has been migrated to the main <a href=\"https://github.com/agorapulse/grails-aws-sdk\">AWS SDK Grails Plugin</a> repo.</p>\n<p>Here his the <a href=\"https://github.com/agorapulse/grails-aws-sdk/tree/master/grails-aws-sdk-s3\">latest version of it</a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "aws-sdk-ses", |
| "repo": "plugins", |
| "owner": "agorapulse", |
| "desc": "Grails AWS SDK SES plugin", |
| "labels": [ |
| "aws", |
| "ses" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/agorapulse/grails-aws-sdk/issues", |
| "latestVersion": "2.4.15", |
| "updated": "2022-07-20T06:42:00.000Z", |
| "systemIds": [ |
| "com.github.agorapulse.grails-aws-sdk:aws-sdk-ses" |
| ], |
| "vcsUrl": "https://github.com/agorapulse/grails-aws-sdk" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails AWS SDK SES Plugin</h1>\n<p>This repo has been migrated to the main <a href=\"https://github.com/agorapulse/grails-aws-sdk\">AWS SDK Grails Plugin</a> repo.</p>\n<p>Here his the <a href=\"https://github.com/agorapulse/grails-aws-sdk/tree/master/grails-aws-sdk-ses\">latest version of it</a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "aws-sdk-sns", |
| "repo": "plugins", |
| "owner": "agorapulse", |
| "desc": "Grails AWS SDK SNS plugin", |
| "labels": [ |
| "aws", |
| "sns" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/agorapulse/grails-aws-sdk/issues", |
| "latestVersion": "2.4.15", |
| "updated": "2022-07-20T06:42:00.000Z", |
| "systemIds": [ |
| "com.github.agorapulse.grails-aws-sdk:aws-sdk-sns" |
| ], |
| "vcsUrl": "https://github.com/agorapulse/grails-aws-sdk" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails AWS SDK SNS Plugin</h1>\n<p>This repo has been migrated to the main <a href=\"https://github.com/agorapulse/grails-aws-sdk\">AWS SDK Grails Plugin</a> repo.</p>\n<p>Here his the <a href=\"https://github.com/agorapulse/grails-aws-sdk/tree/master/grails-aws-sdk-sns\">latest version of it</a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "aws-sdk-sqs", |
| "repo": "plugins", |
| "owner": "agorapulse", |
| "desc": "Grails AWS SDK SQS plugin", |
| "labels": [ |
| "aws", |
| "sqs" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/agorapulse/grails-aws-sdk/issues", |
| "latestVersion": "2.4.15", |
| "updated": "2022-07-20T06:42:00.000Z", |
| "systemIds": [ |
| "com.github.agorapulse.grails-aws-sdk:aws-sdk-sqs" |
| ], |
| "vcsUrl": "https://github.com/agorapulse/grails-aws-sdk" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails AWS SDK SQS Plugin</h1>\n<p>This repo has been migrated to the main <a href=\"https://github.com/agorapulse/grails-aws-sdk\">AWS SDK Grails Plugin</a> repo.</p>\n<p>Here his the <a href=\"https://github.com/agorapulse/grails-aws-sdk/tree/master/grails-aws-sdk-sqs\">latest version of it</a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "aws-sdk-sts", |
| "repo": "plugins", |
| "owner": "agorapulse", |
| "desc": "Grails AWS SDK STS plugin", |
| "labels": [ |
| "aws", |
| "sts" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/agorapulse/grails-aws-sdk/issues", |
| "latestVersion": "2.4.15", |
| "updated": "2022-07-20T06:42:00.000Z", |
| "systemIds": [ |
| "com.github.agorapulse.grails-aws-sdk:aws-sdk-sts" |
| ], |
| "vcsUrl": "https://github.com/agorapulse/grails-aws-sdk" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails AWS SDK STS Plugin</h1>\n<p>This repo has been migrated to the main <a href=\"https://github.com/agorapulse/grails-aws-sdk\">AWS SDK Grails Plugin</a> repo.</p>\n<p>Here his the <a href=\"https://github.com/agorapulse/grails-aws-sdk/tree/master/grails-aws-sdk-sts\">latest version of it</a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "babel-asset-pipeline", |
| "repo": "plugins", |
| "owner": "errbuddy", |
| "desc": "Babel.js transformation for Asset-pipeline", |
| "labels": [ |
| "asset-pipeline", |
| "babel" |
| ], |
| "licenses": [ |
| "BSD 2-Clause" |
| ], |
| "issueTrackerUrl": "https://github.com/errbuddy/babel-asset-pipeline/issues", |
| "latestVersion": "2.1.1", |
| "updated": "2017-08-08T12:32:15.738Z", |
| "systemIds": [ |
| "net.errbuddy.plugins:babel-asset-pipeline", |
| "net.errbuddy.plugins:add", |
| "net.errbuddy.plugins:react-asset-pipeline" |
| ], |
| "vcsUrl": "https://github.com/errbuddy/babel-asset-pipeline" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/errbuddy/babel-asset-pipeline\"><img src=\"https://travis-ci.org/errbuddy/babel-asset-pipeline.svg?branch=master\" alt=\"Build Status\" /></a></p>\n<h1>babel-asset-pipeline</h1>\n<p>babel.js transformation for asset-pipeline</p>\n<h1>usage</h1>\n<p>simply add</p>\n<pre><code>compile 'net.errbuddy.plugins:babel-asset-pipeline:2.0.6'\n</code></pre>\n<p>to dependencies</p>\n<p>and</p>\n<p>The plugin will *ONLY process *.es6 and *.jsx files if not configured to also process *.js files .</p>\n<h1>Configuration</h1>\n<p>All configuration has to be done under grails.assets.babel. if you experience issues (e.g. configuration options not being picked up when building war files) you should add the configration to build.gradle too.</p>\n<pre><code>grails:\n assets:\n babel:\n enabled: true,\n processor: 'direct'\n processJsFiles: false\n options: {blacklist: ['useStrict'], loose: 'all'}\n</code></pre>\n<h2>Options</h2>\n<pre><code>grails.assets.babel.enabled = true // boolean\n</code></pre>\n<p>default to true. enables the plugin</p>\n<pre><code>grails.assets.babel.processJsFiles = false // boolean\n</code></pre>\n<p>defaults to false. Whether to process JsAssetFiles (.js) too. <em>By default to Processor only touches Es6AssetFiles (.es6)!</em></p>\n<pre><code>grails.assets.babel.processor = 'direct'\n</code></pre>\n<p>defaults to direct which uses the "old" rhino->babel v5 Processor. see Processors section for other options</p>\n<pre><code>grails.assets.babel.options = [blacklist: ['useStrict'], loose: 'all'] // babel transfom options. see https://babeljs.io/docs/usage/options/ for more information\n</code></pre>\n<p>defaults to null. A Map of options passed to babels transform method. see https://babeljs.io/docs/usage/options/ for possible values. <em>only used for "direct" processor, otherwise ignored</em></p>\n<h2>Modules</h2>\n<pre><code>grails.assets.babel.options = [modules: 'amd', moduleIds: true]\n</code></pre>\n<p>When the <code>moduleIds</code> option is set the plugin provides Babel with a <code>moduleId</code> for each file. The ID is the relative path of the file inside <code>grails-app/assets/javascripts</code> with the file extension removed.</p>\n<pre><code>e.g.\n# File Path:\ngrails-app/assets/javascripts/foo/bar.js\n# Generated moduleId:\nfoo/bar\n</code></pre>\n<p>Note: Explicit module IDs are not available when generating CommonJS modules.</p>\n<h2>Processors</h2>\n<p>since version 2.0 babel-asset-pipeline comes with a new Processor which uses webpack to transpile es6 code. There is some really important things to keep in mind when switching this on:</p>\n<ul>\n<li>the asset-pipeline dependency managment is ignored completly but as webpack is used you can simply require or import stuff</li>\n<li>you have to setup your project appropriately (see section about Webpack on how to do it)</li>\n<li>you should use the babel:webpack tag see https://github.com/peh/babel-test-app/blob/master/grails-app/views/index.gsp</li>\n<li>the "options" Configuration option is ignored completly as all this is handled in the webpack config</li>\n</ul>\n<h2>Webpack</h2>\n<h3>Setup</h3>\n<p>To use webpack you will need some prerequesites. Firstly you need to have node installed.\nIf you do not want to install it manually or you don't want to manage node yourself <a href=\"https://github.com/srs/gradle-node-plugin/\">gradle-node-plugin</a> should exactly be what you are looking for.\nThe only thing you will have to manually do in this case is configure the node executable (see config section below).</p>\n<p>Secondly you have to install gradle-babel-asset-pipeline-helper with npm. this can be done by running <code>npm install --save gradle-babel-asset-pipeline-helper</code> (you may need to <code>npm init</code> first). <em>If you are using gradle-node-plugin you could copy https://github.com/peh/babel-test-app/blob/master/package.json to your project root and simply run <code>gradle npmInstall</code></em>\ngradle-babel-asset-pipeline-helper depends on everything that you will need to use webpack in your grails app and also comes with two default webpack configurations and run scripts that are being executed by the webpack processors.</p>\n<p>Lastly you should use <babel:webpack src="file.js" /> to reference your js files. This will come in handy if you are using the webpack dev server (otherwise it is not needed!)</p>\n<h3>Restarting the WebpackDevserver</h3>\n<p>In some cases it is needed to restart the devserver. Simply append ?restartWebpack=true to the url you are requesting. The Taglib will take care of killing and restarting the webpack devserver.</p>\n<h3>Configuration</h3>\n<p>There are a few additional configuration options you might need to touch</p>\n<pre><code>grails.assets.babel.processor = "webpack" // or "webpack-dev-server"\n</code></pre>\n<p>If you want to use Hot Module Reloading you can use webpack-dev-server. <em>You should only do that in development environments</em> for production you should always use webpack!</p>\n<pre><code>grails.assets.babel.nodeExec = "/usr/local/bin/node"\n</code></pre>\n<p>The node exectuable default to "/usr/local/bin/node". If you are on Windows or you are using <a href=\"https://github.com/srs/gradle-node-plugin/\">gradle-node-plugin</a> ( or<a href=\"https://github.com/creationix/nvm\">nvm</a>) you will have to change this to point to your local node exectuable</p>\n<p>For gradle-node-plugin users, node is installed in your projects local .gradle directory.</p>\n<pre><code>grails.assets.babel.externalWebpackConfig = null\n</code></pre>\n<p>This one is for advanced users only! By defining a different webpack config location you are overwriting the default configuration taken from gradle-babel-asset-pipeline-helper.\nThe default config is build using the <a href=\"https://github.com/peh/gradle-babel-asset-pipeline-helper/blob/master/babel-webpack.js#L29\">buildConfig function</a>.\nIf you want to use a custom one you can define a file here which is required by the package script.\nYour configuration should either be a webpack config object (see webpack documenation) or a function (which is recommended) which is then called with the same parameters the default build function is called with.\nThe default function should give you a fair idea on what the parameters are and how to use it properly.\nThis is usable for webpack-dev-server to but here it is important to stick closely to <a href=\"https://github.com/peh/gradle-babel-asset-pipeline-helper/blob/master/babel-webpack-dev-server.js#L38\">the default buildConfig()</a> as HMR is breaking pretty easy when something is not configured right.</p>\n<h3>Plugin Development</h3>\n<p>If you want to help extending this plugin you can get setup in minutes by:</p>\n<pre><code>git clone https://github.com/errbuddy/babel-asset-pipeline.git\ncd babel-asset-pipeline\n./gradlew npmInstall\n</code></pre>\n<p>Now your local environment has the required nodeJs version installed and you can start hacking. Feel free to create a PR for your changes</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "bootstrap-framework", |
| "repo": "gradle-plugins", |
| "owner": "kensiprell", |
| "desc": "Gradle plugin for integrating the Bootstrap Framework", |
| "labels": [ |
| "bootstrap", |
| "fontawesome" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/kensiprell/bootstrap-framework/issues", |
| "latestVersion": "1.0.3", |
| "updated": "2017-11-07T07:26:49.452Z", |
| "systemIds": [ |
| "com.siprell.plugins:bootstrap-framework" |
| ], |
| "vcsUrl": "https://github.com/kensiprell/bootstrap-framework" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h2>This plugin is no longer maintained.</h2>\n<h3>Gradle plugin for integrating the Bootstrap Framework and Font Awesome</h3>\n<p><a href=\"https://bintray.com/kensiprell/gradle-plugins/bootstrap-framework/_latestVersion\"><img src=\"https://api.bintray.com/packages/kensiprell/gradle-plugins/bootstrap-framework/images/download.svg\" alt=\"Download\" /></a></p>\n<p><a href=\"http://getbootstrap.com\">Bootstrap</a> bills itself as "the most popular HTML, CSS, and JS framework for developing responsive, mobile first projects on the web."</p>\n<p><a href=\"http://fortawesome.github.io/Font-Awesome/\">Font Awesome</a> is the "iconic font and CSS toolkit."</p>\n<p>If you have a question, suggestion, or want to report a bug, please submit an <a href=\"https://github.com/kensiprell/bootstrap-framework/issues\">issue</a>. I will reply as soon as I can.</p>\n<h3>Highlights</h3>\n<ul>\n<li>\n<p>The Bootstrap version can be configured in your application's <code>build.gradle</code> file, which means you do not have to install a different version of the plugin to get a different Bootstrap version, nor do you have to wait on a plugin update to use the latest Bootstrap release.</p>\n</li>\n<li>\n<p>The plugin can also manage Font Awesome files, including LESS support.</p>\n</li>\n<li>\n<p>The plugin supports the <a href=\"https://github.com/bertramdev/asset-pipeline-core\">asset-pipeline-core</a> plugin and its <a href=\"https://github.com/bertramdev/less-asset-pipeline\">less-asset-pipeline</a> module out of the box.</p>\n</li>\n</ul>\n<h3>Sample Application</h3>\n<p>This Grails <a href=\"https://github.com/kensiprell/bootstrap-framework-sample\">sample application</a> demonstrates how to use the plugin.</p>\n<h3>Installation</h3>\n<p>Add the following lines to your application's <code>build.gradle</code> file. The commented-out lines show the plugin default values, and if you are using Grails, they are not required for the plugin to work. See the <a href=\"https://github.com/kensiprell/bootstrap-framework#configuration-options\">Configuration Options</a> section for the details.</p>\n<pre><code>buildscript {\n ext {\n //bootstrapFramework = [\n // version : "3.3.5",\n // cssPath : "grails-app/assets/stylesheets",\n // jsPath : "grails-app/assets/javascripts",\n // useIndividualJs : false,\n // useLess : false,\n // invalidVersionFails : false,\n // fontAwesome : [\n // install : false\n // version : "4.3.0",\n // useLess : false\n // invalidVersionFails : false\n // ]\n //]\n }\n repositories {\n jcenter()\n }\n dependencies {\n classpath "com.siprell.plugins:bootstrap-framework:1.0.3"\n }\n}\n\napply plugin: "com.siprell.plugins.bootstrap-framework"\n</code></pre>\n<h3>Configuration Options</h3>\n<p>The following options can be configured in the <code>bootstrapFramework</code> Map.</p>\n<h4>bootstrapFramework.version</h4>\n<p>Use the property below to change the Bootstrap Framework version used by your application.</p>\n<pre><code>version : "3.3.1"\n</code></pre>\n<h4>bootstrapFramework.cssPath</h4>\n<p>Use the property below to define the location where the Bootstrap CSS, fonts, and LESS files are copied.</p>\n<pre><code>cssPath : "src/main/web-app/resources/css"\n</code></pre>\n<h4>bootstrapFramework.jsPath</h4>\n<p>Use the property below to define the location where the Bootstrap JavaScript files are copied.</p>\n<pre><code>jsPath : "src/main/web-app/resources/js"\n</code></pre>\n<h4>bootstrapFramework.useIndividualJs</h4>\n<p>If the property below is set to <code>true</code>, the plugin will copy all individual JavaScript files to <code>"${bootstrapFramework.jsPath}/bootstrap"</code>. Otherwise, it will only copy the <code>bootstrap.js</code> file to the directory.</p>\n<pre><code>useIndividualJs : true\n</code></pre>\n<h4>bootstrapFramework.useLess</h4>\n<p>If the property below is set to <code>true</code>, the plugin will copy all Bootstrap Framework LESS and mixin files to <code>"${bootstrapFramework.cssPath}/bootstrap/less"</code>.</p>\n<pre><code>useLess : true\n</code></pre>\n<h4>invalidVersionFails</h4>\n<p>The <code>invalidVersionFails</code> property can be configured individually for <code>bootstrapFramework</code> and <code>bootstrapFramework.fontAwesome</code>. When the property is at its default of <code>false</code> and you have entered an invalid version number, the plugin will search the <code>build/tmp</code> directory for other versions of the appropriate zip file and use the one with the highest version number. It will also display a warning message in the console.</p>\n<p>You can disable this behavior by setting this property to <code>true</code>. If the plugin cannot download the version you specified, it will throw an <code>org.gradle.api.InvalidUserDataException</code>.</p>\n<pre><code>bootstrapFramework = [\n invalidVersionFails : true\n fontAwesome : [\n install : true,\n invalidVersionFails : true\n ]\n]\n</code></pre>\n<h4>bootstrapFramework.fontAwesome.install</h4>\n<p>If <code>bootstrapFramework.fontAwesome.install</code> is set to <code>true</code>, the plugin will install the Font Awesome fonts using the default plugin version without LESS support.</p>\n<pre><code>bootstrapFramework = [\n fontAwesome : [\n install : true\n ]\n]\n</code></pre>\n<h4>bootstrapFramework.fontAwesome.version</h4>\n<p>You can change the Font Awesome version by setting the <code>bootstrapFramework.fontAwesome.version</code> property.</p>\n<pre><code>bootstrapFramework = [\n fontAwesome : [\n install : true\n version : "4.2.0"\n ] \n]\n</code></pre>\n<h4>bootstrapFramework.fontAwesome.useLess</h4>\n<p>You can add LESS support for Font Awesome by setting the <code>bootstrapFramework.fontAwesome.useLess</code> property.</p>\n<pre><code>bootstrapFramework = [\n fontAwesome : [\n install : true\n useLess : true\n ] \n]\n</code></pre>\n<h3>How the Plugin Works</h3>\n<p>The plugin downloads the appropriate Bootstrap or Font Awesome zip file and copies it to your application's <code>build/tmp</code> directory. The plugin will extract the necessary files and copy them to the directories defined by the <code>bootstrapFramework.cssPath</code> and <code>bootstrapFramework.jsPath</code> properties.</p>\n<p>The files are copied into the directory trees shown below. It is important that you do not put any files in the two <code>bootstrap</code> directories (<code>"${bootstrapFramework.cssPath}/bootstrap"</code> and <code>"${bootstrapFramework.jsPath}/bootstrap"</code>) or the <code>font-awesome</code> directory (<code>"${bootstrapFramework.cssPath}/font-awesome"</code>) because they will be overwritten.</p>\n<p>The <code>bootstrap-all.js</code>, <code>bootstrap-all.css</code>, <code>bootstrap-less.less</code>, <code>font-awesome-all.css</code>, and <code>font-awesome-less.less</code> files are generated for the asset-pipeline plugin if you are using Grails or the word "assets" is contained in the <code>bootstrapFramework.jsPath</code> property.</p>\n<p>Directory <code>bootstrapFramework.jsPath</code>:</p>\n<pre><code>| bootstrap-all.js\n|----bootstrap/\n| | affix.js\n| | alert.js\n| | bootstrap.js\n| | etc.\n</code></pre>\n<p>Directory <code>bootstrapFramework.cssPath</code>:</p>\n<pre><code>| bootstrap-all.css\n| bootstrap-less.less\n|----bootstrap/\n| |----css/\n| | | bootstrap-theme.css\n| | | bootstrap.css\n| |----fonts/\n| | | glyphicons-halflings-regular.eot\n| | | etc.\n| |----less/\n| | | alerts.less\n| | | badges.less\n| | | etc.\n| | |----mixins/\n| | | | alerts.less\n| | | | background-variant.less\n| | | | etc.\n| font-awesome-all.css\n| font-awesome-less.less\n|----font-awesome/\n| |----css/\n| | | font-awesome.css\n| |----fonts/\n| | | FontAwesome.otf\n| | | etc.\n| |----less/\n| | | animated.less\n| | | etc.\n</code></pre>\n<h3>User Task</h3>\n<p>You can use the task shown below to display the default Bootstrap Framework and Font Awesome versions used by the plugin.</p>\n<pre><code>./gradlew bootstrapFrameworkVersions\n</code></pre>\n<p>or</p>\n<pre><code>./gradlew bFV\n</code></pre>\n<p>The output will be similar to:</p>\n<pre><code>3.3.5 is the default Bootstrap Framework version.\n4.3.0 is the default Font Awesome version.\n</code></pre>\n<h3>Glyphicons</h3>\n<p>The Glyphicons icons are available as described in the <a href=\"http://getbootstrap.com/components/\">Bootstrap Components</a> section of the Bootstrap Framework documentation.</p>\n<h3>Asset Pipeline Usage</h3>\n<p>The remaining sections outline how to include Bootstrap Framework and Font Awesome in your application using the <code>asset-pipeline-core</code> plugin and its <code>less-asset-pipeline</code> module.</p>\n<h4>JavaScript</h4>\n<p>The instructions below assume the manifest file is in the <code>grails-app/assets/javascripts</code> directory.</p>\n<h5>Add all Bootstrap JavaScript Files</h5>\n<p>Add the line below to a manifest:</p>\n<pre><code>//= require bootstrap-all\n</code></pre>\n<p>Or add the line below to a GSP:</p>\n<pre><code><asset:javascript src="bootstrap-all.js"/>\n</code></pre>\n<h5>Add individual Bootstrap JavaScript files</h5>\n<p>Ensure you set the parameter below to true as described <a href=\"https://github.com/kensiprell/bootstrap-framework#bootstrapframeworkuseindividualjs\">above</a>:</p>\n<pre><code>bootstrapFrameworkUseIndividualJs = true\n</code></pre>\n<p>Add a line similar to the one below to a manifest:</p>\n<pre><code>//= require bootstrap/bootstrap-affix\n</code></pre>\n<p>Or add the line below to a GSP:</p>\n<pre><code><asset:javascript src="bootstrap/bootstrap-affix.js"/>\n</code></pre>\n<h4>Stylesheets</h4>\n<p>The instructions below assume the manifest file is in the <code>grails-app/assets/stylesheets</code> directory.</p>\n<h5>Add all Bootstrap and Font Awesome CSS Files</h5>\n<p>Add the lines below to a manifest:</p>\n<pre><code>*= require bootstrap-all\n*= require font-awesome-all\n</code></pre>\n<p>Or add the lines below to a GSP:</p>\n<pre><code><asset:stylesheet src="bootstrap-all.css"/>\n<asset:stylesheet src="font-awesome-all.css"/>\n</code></pre>\n<h5>Add individual Bootstrap CSS Files</h5>\n<p>Add the line below to a manifest:</p>\n<pre><code>*= require bootstrap/css/bootstrap-theme\n</code></pre>\n<p>Or add the line below to a GSP:</p>\n<pre><code><asset:stylesheet src="bootstrap/css/bootstrap-theme.css"/>\n</code></pre>\n<h3>LESS</h3>\n<h4>Add LESS Files</h4>\n<p>Add the lines below to a manifest:</p>\n<pre><code>*= require bootstrap-less\n*= require font-awesome-less\n</code></pre>\n<p>Or add the line below to a GSP:</p>\n<pre><code><asset:stylesheet src="bootstrap-less.css"/>\n<asset:stylesheet src="font-awesome-less.css"/>\n</code></pre>\n<h4>LESS Customizations</h4>\n<p>If LESS support is configured for either Bootstrap Framework or Font Awesome, the plugin will create the appropriate LESS file in your application's <code>bootstrapFramework.cssPath</code> directory. If you later decide not to use LESS, the plugin will delete the LESS and mixin files, but it will not delete the <code>bootstrap-less.less</code> or the <code>font-awesome-less.less</code> file. Should you decide to turn LESS support back on, your customized LESS files will still be available.</p>\n<p>Use <code>bootstrap-less.less</code> for customizing the Bootstrap Framework:</p>\n<pre><code>/*\n* This file is for your Bootstrap Framework less and mixin customizations.\n* It was created by the bootstrap-framework plugin.\n* It will not be overwritten.\n*\n* You can import all less and mixin files as shown below,\n* or you can import them individually.\n* See https://github.com/kensiprell/bootstrap-framework/blob/master/README.md#less\n*/\n\n@import "bootstrap/less/bootstrap.less";\n\n/*\n* Your customizations go below this section.\n*/\n</code></pre>\n<p>Use <code>font-awesome-less.less</code> for customizing Font Awesome:</p>\n<pre><code>* Font Awesome by Dave Gandy - http://fontawesome.io\n*\n* This file is for your Font Awesome less and mixin customizations.\n* It was created by the bootstrap-framework plugin.\n* It will not be overwritten.\n*\n* You can import all less and mixin files as shown below,\n* or you can import them individually.\n* See https://github.com/kensiprell/bootstrap-framework/blob/master/README.md#font-awesome-less\n*/\n\n@import "font-awesome/less/font-awesome.less";\n\n@fa-font-path: "/assets/font-awesome/fonts";\n\n/*\n* Your customizations go below this section.\n*/\n</code></pre>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "boselecta", |
| "repo": "maven", |
| "owner": "vahid", |
| "desc": "Websocket autocomplete/ multi dependency selection plugin for grails 3", |
| "labels": [ |
| "autocomplete" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/vahidhedayati/grails-boselecta-plugin/issues", |
| "latestVersion": "3.0.4", |
| "updated": "2016-04-13T21:40:52.542Z", |
| "systemIds": [ |
| "org.grails.plugins:boselecta" |
| ], |
| "vcsUrl": "https://github.com/vahidhedayati/grails-boselecta-plugin" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Boselecta plugin</h1>\n<h3>Side note - similar / related projects</h3>\n<ul>\n<li>\n<p><a href=\"https://github.com/vahidhedayati/ajaxdependancyselection\">ajaxdependancyselection</a></p>\n</li>\n<li>\n<p><a href=\"https://github.com/vahidhedayati/grails-boselecta-plugin\">grails-boselecta-plugin (this)</a></p>\n</li>\n</ul>\n<p>Grails plugin that uses default WebSocket technology to interact with your domainClasses and produce dependent form / options that depend on one another. The format to define select functionality / auto complete are identical. Auto complete requires additional boolean values to be passed to make it auto complete.</p>\n<h5>Select box dependencies data comes from WebSocket Client running within your application (as part of the plugin)</h5>\n<h5>AutoComplete input areas use HTML5 dataList, data for dataList provided by backend WebSocket Connection.</h5>\n<h4><a href=\"https://www.youtube.com/watch?v=GGB7mtB9nWM\">Walkthrough Video - youtube, Everything you need to know about boselecta</a></h4>\n<p><img src=\"https://raw.githubusercontent.com/vahidhedayati/grails-boselecta-plugin/grails2/documentation/boselecta.png\" alt=\"diagram\" /></p>\n<p><a href=\"https://github.com/vahidhedayati/grails-boselecta-plugin/wiki/More-information\">More information to help with diagram</a></p>\n<p>BoSelecta can be incorporated to an existing grails app running ver 2>+. Supports both resource (pre 2.4) /assets (2.4+) based grails sites.</p>\n<h6>Plugin will work with tomcat 7.0.54 + (inc. 8) running java 1.7+</h6>\n<h6>Dependency</h6>\n<p>Dependency Grails 3:</p>\n<pre><code class=\"language-groovy\"> compile "org.grails.plugins:boselecta:3.0.4"\n</code></pre>\n<p><a href=\"https://github.com/vahidhedayati/grails-boselecta-plugin/\">codebase for grails 3.X</a></p>\n<p>Dependency Grails 2:</p>\n<pre><code class=\"language-groovy\">\tcompile ":boselecta:0.2" \n</code></pre>\n<p><a href=\"https://github.com/vahidhedayati/grails-boselecta-plugin/tree/grails2\">codebase for grails 2.X</a></p>\n<p>######<a href=\"https://github.com/vahidhedayati/testbo\">test site for grails 2</a></p>\n<p>######<a href=\"https://github.com/vahidhedayati/testbo3\">test site for grails 3</a></p>\n<p>###Latest updates (after video published):\nA further lock down has been introduced, with the assumption that most people will be looking up domain objects with single dependencies.\nThis means, typically I expect an end user to map from continent to country to city and so on. So its one to one relationship between each object. For this reason the default call now only supports one relation, so:</p>\n<pre><code class=\"language-gsp\"><bo:selecta\n... \ndomain="package.domainClass1"\n..\ndomain2="package.domainClass2"\n..\n/>\n</code></pre>\n<p>domain will be the primary object itself (so a listing of that object, domain2 is the entity that it has that relationship with.</p>\n<p>If you attempt to exceed and use domain3 and on. The plugin will not work. You can from now use selecta2 for those relations with depth</p>\n<pre><code class=\"language-gsp\"><bo:selecta2\ndomainDepth="4"\n... \ndomain="package.domainClass1"\n..\ndomain2="package.domainClass2"\n..\ndomain3="package.domainClass3"\n..\ndomain4="package.domainClass4"\n..\n/>\n</code></pre>\n<h4><a href=\"https://github.com/vahidhedayati/grails-boselecta-plugin/wiki/Testing-plugin\">Testing plugin</a></h4>\n<h4><a href=\"https://github.com/vahidhedayati/grails-boselecta-plugin/wiki/Config.groovy\">Config.groovy overrides</a></h4>\n<h4>[domainDepth explained] (https://github.com/vahidhedayati/grails-boselecta-plugin/wiki/domainDepth-explained)</h4>\n<h5><a href=\"https://github.com/vahidhedayati/grails-boselecta-plugin/wiki/grails-BoSelecta-Plugin-usage\">grails BoSelecta Plugin usage</a></h5>\n<h4><a href=\"https://github.com/vahidhedayati/grails-boselecta-plugin/wiki/JSON-Formatting\">JSON Formatting</a>.</h4>\n<h5><a href=\"https://github.com/vahidhedayati/grails-boselecta-plugin/wiki/What-is-front-end---back-end-WebSocket-connections\">What is front-end / back-end WebSocket connections</a> ?</h5>\n<p>##Examples:</p>\n<h5>Basic example:</h5>\n<p><a href=\"https://github.com/vahidhedayati/testbo/blob/master/grails-app/views/test/index.gsp\">Example 1: Connector / selectPrimary into default g:select box. (found in above testbo project)</a></p>\n<ol>\n<li>Initiate a master socket connection, <bo:connect handles all the information flowing back from backend websocket. So this is your main and only connection required on any given page. Take a note of the user and job names, they must match all the calls on this page.</li>\n</ol>\n<p>Both the two code blocks below in one gsp:</p>\n<pre><code class=\"language-gsp\"><bo:connect user="myuser" job="job1" />\n</code></pre>\n<p>Now that we have configured our master listener, lets configure one connection with a relation that is returned to a normal blank select box</p>\n<pre><code class=\"language-gsp\"><form action="example5">\n\n<bo:selecta \nid="MyCountry1" name="MyCountry1" job= "job1" user="myuser" domainDepth="0" formatting="JSON"\ndomain='ajaxdependancyselectexample.MyCountry' searchField='countryName' collectField='id'\ndomain2='ajaxdependancyselectexample.MyCity' bindid="mycountry.id" searchField2='cityName' collectField2='id'\nappendValue='' appendName='Updated' noSelection="['': 'Please choose Continent']" setId="MyCity1" />\n\n<g:select name="MyCity1" id="MyCity1" optionKey="id" optionValue="cityName" from="[]" required="required" noSelection="['': 'Please choose Country']" />\n<input type=submit value=go> \n</form>\n</code></pre>\n<p>If you have used ajaxdependancy selection, a lot of the above input will look familiar.\nYou are now giving the backend the ID of your primary selection MyCountry1, you are telling it what domain is which makes this a primary call and then returns MyCountry.countryName and MyCountry.id to the primary box, you are then setting the setId as MyCity1 and saying domain2 is MyCity and to search/collect cityName/id.</p>\n<p><a href=\"https://github.com/vahidhedayati/testbo/blob/master/grails-app/views/test/index2.gsp\">Example 2: Connector / primary / into Secondary into g:select: (found in above testbo project)</a></p>\n<p>Identical to above, but in this example we iterate over the relations using <bo:select passing domain2 object which be the next object so on the secondary objects there is no domain= value defined.</p>\n<pre><code class=\"language-gsp\"><bo:connect user="randomUser2" job="job2" />\n\n<g:form name="myForm" action="example5"> \n<bo:selecta \n id="MyContinent2" name="MyContinent2" setId="MyCountry11"\n job= "job2" user="randomUser2" domainDepth="0" \n domain='ajaxdependancyselectexample.MyContinent' searchField='continentName' collectField='id'\n domain2='ajaxdependancyselectexample.MyCountry' bindid="mycontinent.id" searchField2='countryName'\n appendValue='' appendName='Updated' collectField2='id' noSelection="['': 'Please choose Continent']" />\n\n <bo:selecta id="MyCountry11" name="MyCountry11"\n job= "job2" user="randomUser2" domainDepth="0" setId="MyCity11"\n domain2='ajaxdependancyselectexample.MyCity' bindid="mycountry.id" searchField2='cityName' collectField2='id'\n formatting="JSON" appendValue='' appendName='Updated' noSelection="['': 'Please choose Continent']" />\n\n <bo:selecta \n name="MyCity11" id="MyCity11" job= "job2" user="randomUser2" domainDepth="0" setId="MyShop12" \n domain2='ajaxdependancyselectexample.MyShops' bindid="mycity.id" searchField2='shopName' collectField2='id'\n appendValue='' appendName='Updated' formatting="JSON" noSelection="['': 'Please choose Country 1111']"/>\n\n <g:select \n name="MyShop12" id="MyShop12" optionKey="id" optionValue="shopName" \n from="[]" required="required" noSelection="['': 'Please choose City']" \n />\n <g:submitButton name="submit"/> \n </g:form>\n</code></pre>\n<p><a href=\"https://github.com/vahidhedayati/testbo/blob/master/grails-app/views/test/definedselectvalues.gsp\">Example 3: Defined pre selected values across multiple objects + randomized user within gsp</a></p>\n<p><a href=\"https://github.com/vahidhedayati/testbo/blob/master/grails-app/views/test/definedselectvalues2.gsp\">Example 4: Defined pre selected values across less multiple objects + randomized user within controller</a></p>\n<p><a href=\"https://github.com/vahidhedayati/testbo/blob/master/grails-app/views/test/definedselectvalues3.gsp\">Example 5: Defined pre selected values same as example3 but with JSON return object</a></p>\n<p><a href=\"https://github.com/vahidhedayati/testbo/blob/master/grails-app/views/test/multidomainexample.gsp\">Example 6: Multiple relationship per domainClass example i.e. object1 has many up to Xth relations with object2 3 4..XXX</a></p>\n<p><a href=\"https://github.com/vahidhedayati/testbo/blob/master/grails-app/views/test/multimultidomainexample.gsp\">Example 7: applicable to all methods - reuse of the taglib multiple times on the same page</a></p>\n<p><a href=\"https://github.com/vahidhedayati/testbo/blob/master/grails-app/views/test/noref.gsp\">Example 8: No reference or loose dependency relation between a secondary called object and the next domainClass</a></p>\n<p><a href=\"https://github.com/vahidhedayati/testbo/blob/master/grails-app/views/test/norefselectionext.gsp\">Example 9: No reference relationship with secondary object that then returns back into a normal relationship object</a></p>\n<p><a href=\"https://github.com/vahidhedayati/testbo/blob/master/grails-app/views/test/norefprimary.gsp\">Example 10: Primary object with a No reference relationship</a></p>\n<p><a href=\"https://github.com/vahidhedayati/testbo/blob/master/grails-app/views/test/autoComplete.gsp\">Example 11: Auto complete a few hasMany to a noref relation</a>\nUsing the same Tag to acheive <a href=\"https://github.com/vahidhedayati/testbo/blob/master/grails-app/views/test/autoComplete.gsp\">autoComplete</a>\nIn this example (not on actual link, the user is being defined as a variable and reused - this now makes it a dynamic user but same on that one page.</p>\n<p>The difference with this call and select is that as you can see on the first example it has autoComplete="true" and if this is the primary object then also autoCompletePrimary="true", if second object it just needs the first tag. Follow example below.. There are two additional fields hiddenField and jsonField. In autoComplete, the results are returned from html5 dataList. I have added data-value and parse that into the hidden field for jsonField and hiddenField gets set to the or collectField of the value selected. The rest is like above.</p>\n<pre><code class=\"language-gsp\"><% def myuser = bo.randomizeUser('user': 'random1') %>\n\n<bo:connect user="${myuser}" job="job3"/>\n\n<form action="example5">\n\n<bo:selecta \n autoComplete="true" autoCompletePrimary="true" \n job="job3" user="${myuser}" id="MyContinent2" name="MyContinent2" setId="MyCountry11" \n hiddenField="VahidHidden_" jsonField="VahidJSON_" formatting="JSON"\n domain='ajaxdependancyselectexample.MyContinent' searchField='continentName' collectField='id'\n domain2='ajaxdependancyselectexample.MyCountry' bindid="mycontinent.id" \n searchField2='countryName' collectField2='id' />\n\t\n <bo:selecta \n\tautoComplete="true" \n\tjob="job3" user="${myuser}" id="MyCountry11" name="MyCountry11" \n\thiddenField="NextHidden_" jsonField="NextJSON_" formatting="JSON"\n\tdomain2='ajaxdependancyselectexample.MyCity' bindid="mycountry.id"\n\tsearchField2='cityName' collectField2='id' setId="MyCity11" />\n\t\n <bo:selecta\n \tautoComplete="true"\n\tjob="job3" user="${myuser}" formatting="JSON"\n\tname="MyCity11" id="MyCity11" \n\thiddenField="myHidden_" jsonField="myJSON_"\n\tdomain2='ajaxdependancyselectexample.MyShops' searchField2='shopName' collectField2='id' \n\tbindid="mycity.id" setId="secondarySearch4" \n\t/>\n\t\n <bo:selecta \n \tautoComplete="true"\n \tjob= "job121" user="${myuser }"\tformatting="JSON" id="secondarySearch4" name="NAMEOFBorough" \n\thiddenField="myHidden_" jsonField="myJSON_"\n\tdomain2='ajaxdependancyselectexample.MyBorough' searchField='actualName' collectField='id' \n\tbindid='myborough' value=''\n />\n <input type=submit value=go>\n</form>\n</code></pre>\n<p><a href=\"https://github.com/vahidhedayati/testbo/blob/master/grails-app/views/test/selectautoComplete.gsp\">Example 12: Select To AutoComplete</a></p>\n<p><a href=\"https://github.com/vahidhedayati/testbo/blob/master/grails-app/views/test/autoCompleteToSelect.gsp\">Example 13:AutoComplete To Select</a></p>\n<p><a href=\"https://github.com/vahidhedayati/testbo/blob/master/grails-app/views/test/selectautoComplete2.gsp\">Example 14: AutoComplete To Select from select to another select</a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "browser-detection", |
| "repo": "grails-plugins", |
| "owner": "mathifonseca", |
| "desc": "Grails Browser Detection Plugin", |
| "labels": [ |
| |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/mathifonseca/grails-browser-detection/issues", |
| "latestVersion": "3.4.0", |
| "updated": "2018-03-14T19:17:36.286Z", |
| "systemIds": [ |
| "org.grails.plugins:browser-detection" |
| ], |
| "vcsUrl": "https://github.com/mathifonseca/grails-browser-detection" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>grails-browser-detection</h1>\n<p><a href=\"https://travis-ci.org/mathifonseca/grails-browser-detection\"><img src=\"https://travis-ci.org/mathifonseca/grails-browser-detection.svg\" alt=\"Build Status\" /></a></p>\n<p>This plugin provides a service and tag library for browser detection. It parses User-Agent in order to identify client's browser, operating system, etc. It depends on <a href=\"https://github.com/HaraldWalker/user-agent-utils\">user-agent-utils</a> library from <a href=\"https://github.com/HaraldWalker\">HaraldWalker</a>.\nIf you want to contribute, report issues or just check the code. You can find it at GitHub.</p>\n<p>Here are some of the things that you can currently do with this plugin. All this operations can be used from GSPs or you can use the <code>UserAgentIdentService</code> anywhere in your code.</p>\n<p>Using <code>UserAgentIdentService</code>:</p>\n<pre><code class=\"language-groovy\">class TestController {\n\n def userAgentIdentService\n \n def index() {\n if (userAgentIdentService.isMobile()) {\n println 'Hello mobile device!'\n if (userAgentIdentService.isWindowsPhone()) {\n println 'Wow! Does this still exist?'\n }\n } else {\n println 'Hello desktop browser!'\n if (userAgentIdentService.isInternetExplorer()) {\n println 'Redirecting to Chrome download page...'\n }\n }\n }\n\n}\n</code></pre>\n<p>Detecting Browsers</p>\n<pre><code class=\"language-gsp\"><browser:isMsie> This is Internet Explorer </browser:isMsie>\n<browser:isSafari> This is Safari </browser:isSafari>\n<browser:isChrome> This is Chrome </browser:isChrome>\n<browser:isFirefox> This is Firefox </browser:isFirefox>\n<browser:isOpera> This is Opera </browser:isOpera>\n</code></pre>\n<p>Detecting Devices</p>\n<pre><code class=\"language-gsp\"><browser:isiPhone> This is iPhone </browser:isiPhone>\n<browser:isiPad> This is iPad </browser:isiPad>\n<browser:isMobile> Mobile phones or Android, iPhone, iPad, iPod, Blackberry, etc. </browser:isMobile>\n</code></pre>\n<p>Detecting Operative Systems</p>\n<pre><code class=\"language-gsp\"><browser:isWindows> This is Windows </browser:isWindows>\n</code></pre>\n<p>Other operations</p>\n<p>You can use the following structure that emulates switch behavior:</p>\n<pre><code class=\"language-gsp\"><browser:choice>\n\t<browser:isChrome></browser:isChrome>\n\t<browser:isIE6></browser:isIE6>\n\t<browser:isIE7></browser:isIE7>\n\t<browser:otherwise></browser:otherwise>\n</browser:choice>\n</code></pre>\n<p>Or the one below:</p>\n<pre><code class=\"language-gsp\"><browser:isSafari versionGreater="5">\n\tThis text is rendered if Safari version is greater than 5.\n\tFor example, 5.0.1, 5.1\n</browser:isSafari>\n<browser:isFirefox version="3.*">\n\tIt works for all Firefox versions like 3.1, 3.6 and so on\n</browser:isFirefox>\n<browser:isMsie versionLower="7">\n\tInternet Explorer 5.0, Internet Explorer 6.0\n</browser:isMsie>\n</code></pre>\n<p>At the moment, wildcards are allowed only for version attribute. Be aware that 5.1 is greater than 5 and 5.0 equals to 5.</p>\n<p>All of these taglibs have their negative assert by starting with <code>isNot</code>. For example:</p>\n<pre><code class=\"language-gsp\"><browser:isNotSafari>\n\tThis text is rendered if the browser IS NOT Safari.\n</browser:isNotSafari>\n<browser:isNotFirefox>\n\tThis text is rendered if the browser IS NOT Firefox.\n</browser:isNotFirefox>\n<browser:isNotMsie>\n\tThis text is rendered if the browser IS NOT Internet Explorer.\n</browser:isNotMsie>\n<browser:isNotChrome>\n\tThis text is rendered if the browser IS NOT Chrome.\n</browser:isNotChrome>\n</code></pre>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "build-test-data", |
| "repo": "plugins", |
| "owner": "longwa", |
| "desc": "Grails build-test-data plugin", |
| "labels": [ |
| "testing" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/longwa/build-test-data/issues", |
| "latestVersion": "4.0.0", |
| "updated": "2019-12-20T01:02:42.869Z", |
| "systemIds": [ |
| "io.github.longwa:build-test-data", |
| "org.grails.plugins:build-test-data" |
| ], |
| "vcsUrl": "https://github.com/longwa/build-test-data" |
| }, |
| "documentationUrl": "https://longwa.github.io/build-test-data/", |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/longwa/build-test-data\"><img src=\"https://api.travis-ci.org/longwa/build-test-data.png?branch=master\" alt=\"Build Status\" /></a></p>\n<h2>Build Test Data Grails Plugin</h2>\n<h3>Grails 3.3 and 4.0</h3>\n<p>http://longwa.github.io/build-test-data/index</p>\n<h3>Grails 2.4 - 3.2</h3>\n<p>https://github.com/longwa/build-test-data/wiki</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "cache", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Grails Cache Plugin", |
| "labels": [ |
| "cache" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/grails-cache/issues", |
| "latestVersion": "7.0.0", |
| "updated": "2024-03-21T08:40:30.000Z", |
| "systemIds": [ |
| "org.grails.plugins:cache" |
| ], |
| "vcsUrl": "https://github.com/grails/grails-cache" |
| }, |
| "documentationUrl": "https://grails.github.io/grails-cache/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/grails/plugins/cache/maven-metadata.xml", |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "cache-ehcache", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Provides an ehcache implementation of the cache plugin", |
| "labels": [ |
| "cache", |
| "ehcache" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/grails-cache-ehcache/issues", |
| "latestVersion": "3.0.0", |
| "updated": "2020-07-01T19:32:27.992Z", |
| "systemIds": [ |
| "org.grails.plugins:cache-ehcache" |
| ], |
| "vcsUrl": "https://github.com/grails-plugins/grails-cache-ehcache" |
| }, |
| "documentationUrl": "https://grails-plugins.github.io/grails-cache-ehcache/latest/", |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/grails-plugins/grails-cache-ehcache\"><img src=\"https://travis-ci.org/grails-plugins/grails-cache-ehcache.svg\" alt=\"Build Status\" /></a></p>\n<h1>Grails Cache Ehcache Plugin</h1>\n<p>Makes Ehcache the cache implementation for the <a href=\"https://github.com/grails-plugins/grails-cache\">Grails Cache Plugin</a></p>\n<h2>Grails 3</h2>\n<p>See https://plugins.grails.org/plugin/grails/cache-ehcache and <a href=\"http://grails-plugins.github.io/grails-cache-ehcache/latest/\">Documentation</a></p>\n<h2>Grails 2</h2>\n<p>See https://grails.org/plugin/cache-ehcache and <a href=\"http://grails-plugins.github.io/grails-cache-ehcache/\">Documentation</a></p>\n<h2>Branches</h2>\n<p>The current master branch is for 3.x versions of the plugin compatible with Grails 3. There is a 1.x branch for on-going maintenance of 1.x versions of the plugin compatible with Grails 2. Please submit any pull requests to the appropriate branch. Changes to the 1.x branch will be merged into the master branch if appropriate.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "cache-guava", |
| "repo": "plugins", |
| "owner": "mkobel", |
| "desc": "The guava cache provides a simple in memory cache with maximal capacity and TTL.", |
| "labels": [ |
| "cache" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/itds-ch/grails-cache-guava/issues", |
| "latestVersion": "1.0.0", |
| "updated": "2020-07-03T07:46:52.226Z", |
| "systemIds": [ |
| "org.grails.plugins:cache-guava" |
| ], |
| "vcsUrl": "https://github.com/itds-ch/grails-cache-guava" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>grails-cache-guava</h1>\n<p>This Grails plugin extends the grails-cache plugin.</p>\n<p>The guava cache provides a simple in memory cache with maximal capacity and TTL.</p>\n<h2>Usage</h2>\n<h3>Dependency</h3>\n<pre><code class=\"language-groovy\">dependencies {\n compile 'org.grails.plugins:cache:4.0.0'\n compile 'org.grails.plugins:cache-guava:1.0.0'\n}\n</code></pre>\n<h3>Configuration</h3>\n<pre><code class=\"language-yaml\">grails:\n cache:\n guava: \n defaultTtl: 3600\n caches:\n message:\n maxCapacity: 5000\n ttl: 60\n maps:\n maxCapacity: 6000\n ttl: 30\n countries:\n maxCapacity: 1000\n</code></pre>\n<p>The GrailsGuavaCacheManager is automatically configured by the plugin.</p>\n<h3>Annoations and Services</h3>\n<p>Just use grails-cache's annotations and services as described in\nits <a href=\"http://grails-plugins.github.io/grails-cache/snapshot/guide/index.html\">documentation</a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "cache-headers", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Improve your application performance with browser caching, with easy ways to set caching headers\nin controller responses", |
| "labels": [ |
| "cache" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/cache-headers/issues", |
| "latestVersion": "2.0.2", |
| "updated": "2017-07-13T17:33:18.181Z", |
| "systemIds": [ |
| "org.grails.plugins:cache-headers" |
| ], |
| "vcsUrl": "https://github.com/grails-plugins/cache-headers" |
| }, |
| "documentationUrl": "https://grails-plugins.github.io/cache-headers/", |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/grails-plugins/cache-headers\"><img src=\"https://travis-ci.org/grails-plugins/cache-headers.svg\" alt=\"Build Status\" /></a></p>\n<h1>Grails Cache Headers Plugin</h1>\n<p>his plugin helps you Improve your application performance with browser caching, with easy ways to set caching headers in controller responses, and elegant ways to deal with ETag and Last-Modified generation and checking.\nYou can use this plugin to prevent caching of pages (eg forms), specify long term caching on infrequently changing content, and pass information to caching servers between the client and your app, and also to avoid regeneration of content if it has not changed since the client last downloaded it (even though the client may have an indication it has expired).</p>\n<p>See <a href=\"http://grails-plugins.github.io/cache-headers/latest/\">the documentation</a> for more information</p>\n<h1>Distribution</h1>\n<p>Software is distributed in <a href=\"https://bintray.com/grails/plugins/cache-headers\">Bintray</a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "cascade-validation", |
| "repo": "grails-plugins", |
| "owner": "ctoestreich", |
| "desc": "Grails Cascade Validation Plugin", |
| "labels": [ |
| "validation" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/Grails-Plugin-Consortium/grails-cascade-validation/issues", |
| "latestVersion": "2.0.2", |
| "updated": "2016-03-31T13:31:54.830Z", |
| "systemIds": [ |
| "org.grails.plugins:cascade-validation", |
| "org.grails.plugins:grails-cascade-validation" |
| ], |
| "vcsUrl": "https://github.com/Grails-Plugin-Consortium/grails-cascade-validation" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>grails-cascade-validation</h1>\n<p>See: [https://github.com/rmorrise/grails-cascade-validation/wiki/How-to-use-cascade-validation].</p>\n<p>This plugin establishes a 'cascade' constraint property for validateable objects. If "cascade:true" is set on a nested object, the nested object's validate() method will be invoked and the results will be reported as part of the parent object's validation.</p>\n<p>To use this plugin, add the plugin to BuildConfig.groovy:</p>\n<pre><code class=\"language-groovy\"> plugins {\n //CSC custom plugin for 'cascade' constraint\n compile ":cascade-validation:0.1.4"\n }\n</code></pre>\n<p>Here is an example of a command object that uses the plugin:</p>\n<pre><code class=\"language-groovy\"> @Validateable\n class PhoneNumber {\n long id\n String countryCode\n String areaCode\n String number\n String extension\n TelephoneType telephoneType\n boolean isPrimary\n\n static constraints = {\n areaCode(blank: false)\n number(blank: false)\n telephoneType(cascade: true)\n }\n\n @Validateable\n static class TelephoneType {\n String id\n boolean countryCodeRecommended\n\n static constraints = {\n id(blank: false)\n countryCodeRecommended(nullable: false)\n }\n }\n }\n</code></pre>\n<p>When the cascade: constraint is added on the telephoneType property, this enables nested validation. When the phoneNumber.validate() method is called, the telephoneType.validate() method will also be invoked. Field errors that are added to the telephoneType will also be added to the parent phoneNumber object.</p>\n<p>This plugin was originally based on a blog post by Eric Kelm and is used here with Eric's permission.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "phone-number-constraint", |
| "repo": "grails-plugins", |
| "owner": "sbglasius", |
| "desc": "Grails Phone Number Constraint Plugin", |
| "labels": [ |
| "validation" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/gpc/grails-phone-number-constraint/issues", |
| "latestVersion": "1.0.0", |
| "updated": "2024-02-06T11:35:24.000Z", |
| "systemIds": [ |
| "io.github.gpc:phone-number-constraint" |
| ], |
| "vcsUrl": "https://github.com/gpc/grails-phone-number-constraint" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": "https://repo.maven.apache.org/maven2/io/github/gpc/phone-number-constraint/maven-metadata.xml", |
| "readme": "This plugin establishes a `phoneNumber` constraint property for validateable objects, that being domain objects, and objects implementing `grails.validation.Validateable`. It relies on Google's [libphonenumber](https://github.com/google/libphonenumber) Java implementation" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "cassandra", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "GORM - Grails Data Access Framework", |
| "labels": [ |
| "cassandra", |
| "gorm" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/gorm-cassandra/issues", |
| "latestVersion": "6.1.0", |
| "updated": "2017-03-27T13:56:24.682Z", |
| "systemIds": [ |
| "org.grails.plugins:cassandra" |
| ], |
| "vcsUrl": "https://github.com/grails/gorm-cassandra" |
| }, |
| "documentationUrl": "https://gorm.grails.org/latest/cassandra/manual/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>GORM for Cassandra</h1>\n<p>This project implements <a href=\"http://gorm.grails.org/latest/\">GORM</a> for the Cassandra Column Database.</p>\n<p>For more information see the following links:</p>\n<ul>\n<li><a href=\"http://gorm.grails.org/latest/cassandra/manual\">Documentation</a></li>\n<li><a href=\"http://gorm.grails.org/latest/cassandra/api\">API</a></li>\n<li><a href=\"https://grails.org/plugins.html#plugin/cassandra\">Grails Plugin</a></li>\n<li><a href=\"https://travis-ci.org/grails/gorm-cassandra\"><img src=\"https://travis-ci.org/grails/gorm-cassandra.svg?branch=master\" alt=\"Build Status\" /></a></li>\n</ul>\n<p>For the current development version see the following links:</p>\n<ul>\n<li><a href=\"http://gorm.grails.org/snapshot/cassandra/manual\">Beta Documentation</a></li>\n<li><a href=\"http://gorm.grails.org/snapshot/cassandra/api\">Beta API</a></li>\n</ul>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "ckeditor", |
| "repo": "plugins", |
| "owner": "stefanogualdi", |
| "desc": "CKeditor web WYSIWYG editor integration plugin.", |
| "labels": [ |
| "ckeditor" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/stefanogualdi/grails-ckeditor/issues", |
| "latestVersion": "4.5.9.0", |
| "updated": "2016-08-27T09:08:35.970Z", |
| "systemIds": [ |
| "org.grails.plugins:ckeditor" |
| ], |
| "vcsUrl": "https://github.com/stefanogualdi/grails-ckeditor" |
| }, |
| "documentationUrl": "https://stefanogualdi.github.io/grails-ckeditor/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>CKeditor plugin for Grails</h1>\n<p>The user guide can be found here: <a href=\"https://stefanogualdi.github.io/grails-ckeditor/\">Documentation</a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "cmeditor", |
| "repo": "maven", |
| "owner": "frnktrgr", |
| "desc": "CMEditor is a simple way to use the popular CodeMirror web editor in grails applications.", |
| "labels": [ |
| "cmeditor", |
| "codemirror" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/RRZE-PP/grails-cmeditor/issues", |
| "latestVersion": "2.7.8", |
| "updated": "2019-05-13T09:05:24.098Z", |
| "systemIds": [ |
| "org.grails.plugins:cmeditor" |
| ], |
| "vcsUrl": "https://github.com/RRZE-PP/grails-cmeditor" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>CMEditor</h1>\n<p>CMEditor is a simple way to use the popular CodeMirror web editor in grails applications. You can use it to edit pretty much anything that can be mapped to a file-like object. I.e. something with a filename and text-content. If your model requires additional fields this is supported, too.</p>\n<p>For example managing your library could be done by mapping filename to "$author - $title". The tabbed editor then could manage everything: Author, title, publication year and - of course - the books content in a nice-to-use CodeMirror editor. You could even edit multiple books simultaneously.</p>\n<p>Check out our <a href=\"https://github.com/RRZE-PP/grails-cmeditor-demo\">demo grails project</a>.</p>\n<h2>Usage</h2>\n<p>You currently have the Grails 3 branch checked out. If you wish to use the plugin with Grails 2, checkout the branch 'grails-2.x' and follow the instruction in its README.md.</p>\n<p>Add cmeditor as a plugin to your grails project's build.gradle</p>\n<pre><code> plugins {\n compile 'de.rrze:cmeditor:+'\n }\n</code></pre>\n<p>The plugin depends on jQuery, but does not require it via the assets plugin, because this might overwrite jQuery instances (and registered in jQuery plugins) from other grails plugins. Please ensure that jQuery is loaded before the CMEditor's assets. And that no other jQuery instance is loaded thereafter (e.g. by your layout).</p>\n<pre><code class=\"language-gsp\"> <asset:javascript src="path/to/your/jQuery.js"/>\n <asset:javascript src="cmeditor.js"/>\n <asset:stylesheet href="cmeditor.css"/>\n\n</code></pre>\n<p>When adding a textarea or tabbed editor you have to supply a <code>name</code>-attribute. After document initialization you can access the corresponding javascript CMEditor-object by calling <code>CMEditor.getInstance("<nameAttributeValue>)"</code>. For an API of the class see the CMEditor.js file in grails-app/js/web-app/js/.</p>\n<h3>Tabbed Editor</h3>\n<p>The tabbed editor is useful to edit more than one file at once. They are loaded and stored seamlessly using ajax to a controller of your choice.</p>\n<p>For further documentation please visit <a href=\"https://github.com/RRZE-PP/grails-cmeditor/wiki/Tabbed-Editor\">our project wiki</a> for information on the API.</p>\n<p>If you need additional input fields, you can provide them in the body of the tag. All elements with the class <code>cmeditor-field</code> there will be serialized using their name as key and sent along with the document's content.</p>\n<p>A simple example would look like this:</p>\n<pre><code class=\"language-gsp\"> <cmeditor:tabs name="book" options="[defaultContent:'Lorem ipsum sit dolor']" ajax="[getURL:createLink(action: 'ajaxGet')+'?name=']">\n <label for="author"> <g:message code="myLibrary.author.label" default="Author" /></label>\n <g:textField name="author" class="cmeditor-field" /> <br />\n\n <label for="title"><g:message code="myLibrary.title.label" default="Title" /></label>\n <g:textField name="title" class="cmeditor-field" />\n </cmeditor:tabs>\n</code></pre>\n<p>The resulting CMEditor would be similar to this:\n<img src=\"https://raw.githubusercontent.com/RRZE-PP/grails-cmeditor-demo/master/example.gif\" alt=\"Recorded demo\" /></p>\n<h3>Textareas</h3>\n<p>You can substitute a <code><g:textArea name=""/></code> with <code><cmeditor:textArea name=""/></code>.</p>\n<p>For further documentation please visit <a href=\"https://github.com/RRZE-PP/grails-cmeditor/wiki/Tabbed-Editor\">our project wiki</a> for information on the API.</p>\n<p>So for example use: <code><g:textArea name="foobar" binding="vim" options="[readOnly: true"] /></code></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "coffee-asset-pipeline", |
| "repo": "asset-pipeline", |
| "owner": "bertramlabs", |
| "desc": "Easily process CoffeeScript files with the asset-pipeline plugin. Package includes both jvm coffee runtime as well as the ability to use the coffeescript npm module if detected.", |
| "labels": [ |
| "asset-pipeline", |
| "coffeescript" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/bertramdev/asset-pipeline/issues", |
| "latestVersion": "5.0.9", |
| "updated": "2025-04-13T23:20:06.000Z", |
| "systemIds": [ |
| "com.bertramlabs.plugins:coffee-asset-pipeline" |
| ], |
| "vcsUrl": "https://github.com/bertramdev/asset-pipeline" |
| }, |
| "documentationUrl": "https://bertramdev.github.io/asset-pipeline/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/com/bertramlabs/plugins/coffee-asset-pipeline/maven-metadata.xml", |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "command", |
| "repo": "plugins", |
| "owner": "virtualdogbert", |
| "desc": "Grails command plugin", |
| "labels": [ |
| "command-objects", |
| "validation" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/virtualdogbert/command/issues", |
| "latestVersion": "4.0.0", |
| "updated": "2018-06-26T23:35:43.271Z", |
| "systemIds": [ |
| "org.grails.plugins:command" |
| ], |
| "vcsUrl": "https://github.com/virtualdogbert/command" |
| }, |
| "documentationUrl": "https://virtualdogbert.github.io/command/", |
| "mavenMetadataUrl": null, |
| "readme": "<p>The command Plugin, give Grails a convention for command objects, and adds an ErrorsHandler AST to reduce error handling boilerplate.</p>\n<p>For documentation see the github page:\n<a href=\"https://virtualdogbert.github.io/command\">documentation</a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "compass-asset-pipeline", |
| "repo": "asset-pipeline", |
| "owner": "bertramlabs", |
| "desc": "Provides Compass/SCSS Build support using the jruby runtime. Any compass project can be adjusted to be built by the asset-pipeline and used in applications.", |
| "labels": [ |
| "asset-pipeline", |
| "compass", |
| "scss", |
| "css" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/bertramdev/asset-pipeline/issues", |
| "latestVersion": "4.3.0", |
| "updated": "2023-05-01T16:24:04.000Z", |
| "systemIds": [ |
| "com.bertramlabs.plugins:compass-asset-pipeline" |
| ], |
| "vcsUrl": "https://github.com/bertramdev/asset-pipeline" |
| }, |
| "documentationUrl": "https://bertramdev.github.io/asset-pipeline/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/com/bertramlabs/plugins/compass-asset-pipeline/maven-metadata.xml", |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "console", |
| "repo": "grails-plugins", |
| "owner": "sheehan", |
| "desc": "A web-based Groovy console for interactive runtime application management and debugging.", |
| "labels": [ |
| "console", |
| "management", |
| "debugging" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/sheehan/grails-console/issues", |
| "latestVersion": "2.1.1", |
| "updated": "2018-01-23T03:19:17.309Z", |
| "systemIds": [ |
| "org.grails.plugins:grails-console" |
| ], |
| "vcsUrl": "https://github.com/sheehan/grails-console" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h2>Summary</h2>\n<p>A web-based Groovy console for interactive runtime application management and debugging</p>\n<p><img src=\"https://raw.github.com/sheehan/grails-console/images/screenshot.png\" alt=\"Screenshot\" /></p>\n<h2>Installation</h2>\n<p>The <a href=\"https://grails.org/plugin/console\">1.X</a> version is for Grails 2.</p>\n<p>The <a href=\"http://plugins.grails.org/plugin/sheehan/console\">2.0.X</a> version is for Grails 3.0 - 3.2.</p>\n<p>The <a href=\"http://plugins.grails.org/plugin/sheehan/console\">2.1.X</a> version is for Grails 3.3+.</p>\n<h3>Grails 2</h3>\n<p>Add a dependency in BuildConfig.groovy:</p>\n<pre><code class=\"language-groovy\">grails.project.dependency.resolution = {\n // ...\n plugins {\n runtime ':console:1.5.12'\n // ...\n }\n}\n</code></pre>\n<h3>Grails 3+</h3>\n<p><strong>Note:</strong> If using Grails 3.0.4, you need to update the asset-pipeline dependency in build.gradle to 3.0.6 or greater. 3.0.5 is used by default and has a bug that prevents the console page from rendering.</p>\n<p><strong>Note:</strong> If using Grails 3.0.12, you will need to add this to your configuration: <code>grails.resources.pattern = '/**'</code>. There is a <a href=\"https://github.com/grails/grails-core/issues/9584\">bug</a> related to resource paths.</p>\n<p>Add a dependency in build.gradle</p>\n<pre><code class=\"language-groovy\">runtime 'org.grails.plugins:grails-console:2.1.1'\n</code></pre>\n<h2>Usage</h2>\n<p>Use a browser to navigate to the /console page of your running app, e.g. http://localhost:8080/{app-name}/console</p>\n<p>Type any Groovy commands in the console text area, then click on the execute button. The console plugin relies on Groovy Shell. Lookup Groovy Shell documentation for more information.\nThe Groovy Shell uses the Grails classloader, so you can access any class or artifact (e.g. domain classes, services, etc.) just like in your application code.</p>\n<h2>Saving/loading scripts</h2>\n<p>Click on the <code>Save</code> button to save the current script.</p>\n<p>Use the Storage pane to navigate existing files. Click on a file to load it into the editor.</p>\n<p>There are currently two storage options available:</p>\n<h3>Local Storage</h3>\n<p>Local Storage uses HTML5 <a href=\"http://dev.w3.org/html5/webstorage/\">Web Storage</a>. The files are serialized and stored in the browser as a map under the key <code>gconsole.files</code>.</p>\n<h3>Remote Storage</h3>\n<p>Remote Storage uses the filesystem of the server on which the application is running.</p>\n<h2>Writing to the browser console</h2>\n<p>Calls made to the implicit <code>console</code> variable will be executed on the browser's console.\nThe arguments are serialized as JSON and the calls are queued to run after the script completes.</p>\n<p>Example:\n<img src=\"https://raw.github.com/sheehan/grails-console/images/screenshot2.png\" alt=\"Screenshot\" /></p>\n<h2>Implicit variables</h2>\n<p>The following implicit variables are available:</p>\n<ul>\n<li><code>ctx</code> - the Spring <a href=\"http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/context/ApplicationContext.html\">ApplicationContext</a></li>\n<li><code>grailsApplication</code> - the <a href=\"http://grails.org/doc/latest/api/org/codehaus/groovy/grails/commons/GrailsApplication.html\">GrailsApplication</a> instance</li>\n<li><code>config</code> - the Grails configuration</li>\n<li><code>request</code> - the current <a href=\"http://java.sun.com/products/servlet/2.3/javadoc/javax/servlet/http/HttpServletRequest.html\">HTTP request</a></li>\n<li><code>session</code> - the current <a href=\"http://java.sun.com/products/servlet/2.3/javadoc/javax/servlet/http/HttpSession.html\">HTTP session</a></li>\n<li><code>out</code> - the output <a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/PrintStream.html\">PrintStream</a></li>\n</ul>\n<p>See <a href=\"https://github.com/sheehan/grails-console/wiki/Script-Examples\">Script Examples</a> for example usage.</p>\n<h2>Keyboard Shortcuts</h2>\n<p>| Key | Command |\n|---|---|\n| Ctrl-Enter / \ufffd\ufffd\ufffd\ufffd\ufffd\ufffd-Enter | Execute |\n| Ctrl-S / \ufffd\ufffd\ufffd\ufffd\ufffd\ufffd-S | Save |\n| Esc | Clear output |</p>\n<h2>Configuration</h2>\n<p>The following configuration options are available:</p>\n<p>| Property | Description |\n|---|---|\n| <code>grails.plugin.console.enabled</code> | Whether to enable the plugin. Default is true for the development environment, false otherwise. |\n| <code>grails.plugin.console.baseUrl</code> | Base URL for the console controller. Can be a String or a List of Strings if having multiple URLs is desired. Default uses createLink(). |\n| <code>grails.plugin.console.fileStore.remote.enabled</code> | Whether to include the remote file store functionality. Default is true. |\n| <code>grails.plugin.console.fileStore.remote.defaultPath</code> | Default path when browsing remote files. Default is <code>/</code>. |\n| <code>grails.plugin.console.layout</code> | Used to override the plugin's GSP layout. |\n| <code>grails.plugin.console.newFileText</code> | Text to display as a template for new files. Can be used to add frequently used imports, environment specific warnings, etc... Defaults to empty. |\n| <code>grails.plugin.console.tabSize</code> | The width of a tab character. Defaults to 4. |\n| <code>grails.plugin.console.indentWithTabs</code> | Whether indents should use tabs rather than spaces. Default is false. |\n| <code>grails.plugin.console.indentUnit</code> | How many spaces a block should be indented. Default is 4. |\n| <code>grails.plugin.console.csrfProtection.enabled</code> | Whether to enable CSRF protection. Default is true. |</p>\n<h2>Security</h2>\n<p>By default (as of v1.5.0) the console plugin is only enabled in the development environment. You can enable or disable it for any environment with\nthe <code>grails.plugin.console.enabled</code> config option in Config.groovy / application.groovy (Grails 3). If the plugin is enabled in non-development environments, be sure to guard access using a security plugin like Spring Security Core or Shiro. For Grails 2.x, the paths <code>/console/**</code> and <code>/plugins/console*/**</code> should be secured. For Grails 3.x, the paths <code>/console/**</code> and <code>/static/console/**</code> should be secured.</p>\n<p>Spring Security Core example:</p>\n<pre><code class=\"language-groovy\">grails.plugin.springsecurity.controllerAnnotations.staticRules = [\n [pattern:"/console/**", access:['ROLE_ADMIN']],\n [pattern:"/plugins/console*/**", access:['ROLE_ADMIN']], // Grails 2.x\n [pattern:"/static/console/**", access:['ROLE_ADMIN']], // Grails 3.x\n]\n</code></pre>\n<p>Another example restricting access to localhost IPs:</p>\n<pre><code class=\"language-groovy\">grails.plugin.springsecurity.controllerAnnotations.staticRules = [\n [pattern:"/console/**", access:["hasRole('ROLE_ADMIN') && (hasIpAddress('127.0.0.1') || hasIpAddress('::1'))"]],\n [pattern:"/plugins/console*/**", access:["hasRole('ROLE_ADMIN') && (hasIpAddress('127.0.0.1') || hasIpAddress('::1'))"]], // Grails 2.x\n [pattern:"/static/console/**", access:["hasRole('ROLE_ADMIN') && (hasIpAddress('127.0.0.1') || hasIpAddress('::1'))"]], // Grails 3.x\n]\n</code></pre>\n<h2>Authors</h2>\n<ul>\n<li><a href=\"https://github.com/ziegfried\">Siegfried Puchbauer</a></li>\n<li><a href=\"https://github.com/mingfai\">Mingfai Ma</a></li>\n<li><a href=\"https://github.com/burtbeckwith\">Burt Beckwith</a></li>\n<li><a href=\"https://github.com/sheehan\">Matt Sheehan</a></li>\n<li><a href=\"https://github.com/mjhugo\">Mike Hugo</a></li>\n</ul>\n<h2>Development</h2>\n<p>Please see <a href=\"CONTRIBUTING.md\">CONTRIBUTING.md</a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "consulta-nif", |
| "repo": "plugins", |
| "owner": "puravida-software", |
| "desc": "Consulta el nombre registrado en la AEAT para un NIF dado", |
| "labels": [ |
| |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://gitlab.com/puravida-software/consulta-nif/issues", |
| "latestVersion": "0.1", |
| "updated": "2018-01-10T09:34:46.818Z", |
| "systemIds": [ |
| "com.puravida:consulta-nif" |
| ], |
| "vcsUrl": "https://gitlab.com/puravida-software/consulta-nif/tree/master" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "converters", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Provides JSON and XML converters", |
| "labels": [ |
| "json", |
| "xml" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/grails-plugin-converters/issues", |
| "latestVersion": "5.0.0", |
| "updated": "2024-02-26T10:59:18.000Z", |
| "systemIds": [ |
| "org.grails.plugins:converters" |
| ], |
| "vcsUrl": "https://github.com/grails-plugins/grails-plugin-converters" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/grails/plugins/converters/maven-metadata.xml", |
| "readme": "<h2>Grails Converters</h2>\n<p>This is the Converters plugin that has been part of Grails core up until version 3.3 and now is a standalone plugin.</p>\n<p>Users of Grails 3.3.x and above should use this plugin.</p>\n<h3>Installation</h3>\n<p>Simply add the dependency to your <code>build.gradle</code> file:</p>\n<pre><code class=\"language-groovy\">compile "org.grails.plugins:converters"\n</code></pre>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "cookie", |
| "repo": "grails-plugins", |
| "owner": "ctoestreich", |
| "desc": "Grails Cookie Plugin", |
| "labels": [ |
| "cookies" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/Grails-Plugin-Consortium/grails-cookie/issues", |
| "latestVersion": "2.0.5", |
| "updated": "2016-04-21T01:59:54.523Z", |
| "systemIds": [ |
| "org.grails.plugins:cookie", |
| "org.grails.plugins:grails-cookie" |
| ], |
| "vcsUrl": "https://github.com/Grails-Plugin-Consortium/grails-cookie" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails Cookie Plugin</h1>\n<p><a href=\"https://api.travis-ci.org/Grails-Plugin-Consortium/grails-cookie\"><img src=\"https://api.travis-ci.org/Grails-Plugin-Consortium/grails-cookie.svg?branch=master\" alt=\"Build Status\" /></a></p>\n<p>This plugin makes dealing with cookies easy. Provides an injectable service and tag to easily get, set, and delete cookies with one line.</p>\n<p>It's <a href=\"http://tools.ietf.org/html/rfc6265\">RFC 6265</a> compliant.</p>\n<h2>Installation</h2>\n<p>To install the cookie plug-in just add to <code>build.gradle</code>:</p>\n<pre><code class=\"language-groovy\"> \n compile 'org.grails.plugins:grails-cookie:2.0.3'\n \n</code></pre>\n<h2>Configuration</h2>\n<p>You can configure in <code>Config.groovy</code> or <code>application.yml</code> how long the default cookie age will be (in seconds) when not explicitly supplied while setting a cookie.</p>\n<pre><code class=\"language-groovy\">grails.plugins.cookie.cookieage.default = 86400 // if not specified default in code is 30 days\n</code></pre>\n<h2>Usage</h2>\n<p>You have two ways to work with cookies:</p>\n<ul>\n<li>The cookie plug-in extends the <code>request</code> and <code>response</code> objects found in controllers, filters, etc to allow the following.</li>\n<li>The cookie plug-in provides a <a href=\"./grails-app/services/grails/plugin/cookie/CookieService.groovy\">CookieService</a> that can be used anywhere in your Grails application.</li>\n</ul>\n<p>Example of setting a new cookie:</p>\n<pre><code class=\"language-groovy\">// This sets a cookie with the name `username` to the value `cookieUser123` with a expiration set to a week, defined in seconds\nresponse.setCookie('username', 'cookieUser123', 604800)\n// will use default age from Config (or 30 days if not defined)\nresponse.setCookie('username', 'cookieUser123')\n\n// using service\ndef cookieService // define field for DI\n...\ncookieService.setCookie('username', 'cookieUser123', 604800)\n</code></pre>\n<p>To get the cookie value:</p>\n<pre><code class=\"language-groovy\">request.getCookie('username') // returns 'cookieUser123'\n\n// using service\ndef cookieService // define field for DI\n...\ncookieService.getCookie('username') // returns 'cookieUser123'\n</code></pre>\n<p>To delete the cookie (actually it set new expired cookie with same name):</p>\n<pre><code class=\"language-groovy\">response.deleteCookie('username') // deletes the 'username' cookie\n// using service\ndef cookieService // define field for DI\n...\ncookieService.deleteCookie('username')\n</code></pre>\n<p>All this methods has other signatures and you can find all of them in <a href=\"./grails-app/services/grails/plugin/cookie/CookieService.groovy\">CookieService</a> JavaDoc's.</p>\n<p>You can check out <a href=\"https://github.com/stokito/grails-cookie-demo\">Demo project</a> and also you can find details of implementation in <a href=\"./src/test/groovy/grails/plugin/cookie/CookieRequestSpec.groovy\">CookieRequestSpec</a> and <a href=\"./src/test/groovy/grails/plugin/cookie/CookieResponseSpec.groovy\">CookieResponseSpec</a>.</p>\n<h2>Configuration</h2>\n<p>You can configure default values of attributes in <code>Config.groovy</code>.</p>\n<h3>Default Max Age</h3>\n<p>Default expiration age for cookie in seconds. <code>Max-Age</code> attribute, integer.</p>\n<p>If it has value <code>-1</code> cookie will not stored and removed after browser close.</p>\n<p>If it has null value or unset, will be used 30 days, i.e. <code>2592000</code> seconds.</p>\n<p>Can't has value <code>0</code>, because it means that cookie should be removed.</p>\n<pre><code class=\"language-groovy\">grails.plugins.cookie.cookieage.default = 360 * 24 * 60 * 60\n</code></pre>\n<h3>Default Path</h3>\n<p>Default path for cookie selection strategy, string.</p>\n<ul>\n<li>'context' - web app context path, i.e. <code>grails.app.context</code> option in <code>Config.groovy</code></li>\n<li>'root' - root of server, i.e. '/'</li>\n<li>'current' - current directory, i.e. controller name</li>\n</ul>\n<p>If default path is null or unset, it will be used 'context' strategy</p>\n<pre><code class=\"language-groovy\">grails.plugins.cookie.path.defaultStrategy = 'context'\n</code></pre>\n<h3>Default Secure</h3>\n<p>Default secure cookie param. Secure cookie available only for HTTPS connections. <code>Secure</code> attribute, boolean.\nIf default secure is null or unset, it will set all new cookies as secure if current connection is secure</p>\n<pre><code class=\"language-groovy\">grails.plugins.cookie.secure.default = null\n</code></pre>\n<h3>Default HTTP Only</h3>\n<p>Default HTTP Only param that denies accessing to JavaScript's <code>document.cookie</code>.</p>\n<p>If null or unset will be <code>true</code></p>\n<pre><code class=\"language-groovy\">grails.plugins.cookie.httpOnly.default = true\n</code></pre>\n<p>You can find details of implementation in <a href=\"./src/test/groovy/grails/plugin/cookie/CookieServiceDefaultsSpec.groovy\">CookieServiceDefaultsSpec</a>.</p>\n<h3>External Config</h3>\n<p>If you use property files to inject values to plugins at runtime. This is now supported as of version 1.0.2. This means that inside your external <code>foo.properties</code> file you can specify the following.</p>\n<pre><code class=\"language-groovy\">grails.plugins.cookie.httpOnly.default=true\n</code></pre>\n<p>The string value will correctly be treated as a boolean.</p>\n<h2>Changelog</h2>\n<p><a href=\"https://github.com/grails-plugin-consortium/grails-cookie/releases\">All releases</a></p>\n<h3>v2.0.5 For Grails 3.0</h3>\n<p><a href=\"https://github.com/grails-plugin-consortium/grails-cookie/releases/tag/v2.0.5\">Source</a></p>\n<ul>\n<li>Bug fix for NPE on some find methods in groovy (Even though supposed to be null safe http://stackoverflow.com/questions/6866253/groovy-give-npe-on-list-find-call-but-only-after-a-period-of-time)</li>\n</ul>\n<h3>v2.0.3 For Grails 3.0</h3>\n<p><a href=\"https://github.com/grails-plugin-consortium/grails-cookie/releases/tag/v2.0.3\">Source</a></p>\n<ul>\n<li>Missed exclude for test service</li>\n</ul>\n<h3>v2.0.2 For Grails 3.0</h3>\n<p><a href=\"https://github.com/grails-plugin-consortium/grails-cookie/releases/tag/v2.0.2\">Source</a></p>\n<ul>\n<li>Syncing extension and plugin versions</li>\n</ul>\n<h3>v2.0.1 For Grails 3.0</h3>\n<p><a href=\"https://github.com/grails-plugin-consortium/grails-cookie/releases/tag/v2.0.1\">Source</a></p>\n<ul>\n<li>Testing for mocking of service which was causing issues in grails 3.0.10</li>\n</ul>\n<h3>v2.0 For Grails 3.0</h3>\n<p><a href=\"https://github.com/grails-plugin-consortium/grails-cookie/releases/tag/v2.0\">Source</a></p>\n<h3>v1.4 For Grails 2.4</h3>\n<p><a href=\"https://github.com/stokito/grails-cookie/releases/tag/v1.4\">Source</a></p>\n<ul>\n<li>Minimal Grails version 2.4</li>\n</ul>\n<h3>v1.2 Fixed bug with <code>path.defaultStrategy</code> option</h3>\n<p><a href=\"https://github.com/stokito/grails-cookie/releases/tag/v1.2\">Source</a></p>\n<ul>\n<li><a href=\"https://github.com/stokito/grails-cookie/issues/35\">#35</a> option <code>grails.plugins.cookie.path.defaultStrategy</code> doesn't work.</li>\n<li>Minimal Grails version 2.2.0. But tests of plugin itself will failed. To run them use command <code>./grailsw test-app</code> that uses wrapper with Grails 2.4</li>\n<li>Minimal Java version is downgraded to 6</li>\n</ul>\n<h3>v1.1.0 Fixed bug with defaults not configured in Config</h3>\n<p><a href=\"https://github.com/stokito/grails-cookie/releases/tag/v1.1.0\">Source</a></p>\n<ul>\n<li>Minimal Grails version 2.4.0. Plugin probably should work with early versions of Grails but init tests require v2.4.0</li>\n<li><a href=\"https://github.com/stokito/grails-cookie/issues/32\">#32</a> Add ability to externalize configuration by changing check for boolean from <code>instanceof Boolean</code> to <code>toBoolean()</code> which will correctly address boolean <code>false</code> and string <code>"false"</code> properties</li>\n</ul>\n<h3>v1.0.1 Fixed bug with defaults not configured in Config</h3>\n<p><a href=\"https://github.com/stokito/grails-cookie/releases/tag/v1.0.1\">Source</a></p>\n<ul>\n<li><a href=\"https://github.com/stokito/grails-cookie/issues/30\">#30</a> Default path strategy is 'context' and <code>grails.app.context</code> used null instead of actual context</li>\n</ul>\n<h3>v1.0 Production ready version</h3>\n<p><a href=\"https://github.com/stokito/grails-cookie/releases/tag/v1.0\">Source</a></p>\n<ul>\n<li><a href=\"https://github.com/stokito/grails-cookie/issues/17\">#17</a> Since v0.1 all deprecated things was removed:\n* Tag <code><cookie:get/></code>. Use standard <code><g:cookie/></code> tag instead.\n* Methods <code>get()</code>, <code>set()</code>, <code>delete()</code> from <code>CookieService</code>. They are replaced with corresponding <code>getCookie()</code>, <code>setCookie()</code>, <code>deleteCookie()</code>.</li>\n<li><a href=\"https://github.com/stokito/grails-cookie/issues/19\">#19</a> All cookies should be Version 1 (by RFC 2109) cookie specifications</li>\n<li><a href=\"https://github.com/stokito/grails-cookie/issues/22\">#22</a> Support of cookie attributes</li>\n<li><a href=\"https://github.com/stokito/grails-cookie/issues/10\">#10</a> Improved delete cookie method. Method delete cookie now can takes a domain name</li>\n<li><a href=\"https://github.com/stokito/grails-cookie/issues/28\">#28</a> <code>setCookie()</code> and <code>deleteCookie()</code> should return added cookie</li>\n<li><a href=\"https://github.com/stokito/grails-cookie/issues/25\">#25</a> Make default <code>path</code>, <code>secure</code> and <code>httpOnly</code> configurable and more intelligent enhancement</li>\n</ul>\n<h3>v0.60 Last release with deprecated taglib and methods in service</h3>\n<p><a href=\"https://github.com/stokito/grails-cookie/releases/tag/v0.6\">Source</a></p>\n<ul>\n<li><a href=\"https://github.com/stokito/grails-cookie/issues/3\">#3</a> Fixed <code>deleteCookie</code> not works in <code>response</code></li>\n<li><a href=\"https://github.com/stokito/grails-cookie/issues/16\">#16</a> added tests</li>\n<li><a href=\"https://github.com/stokito/grails-cookie/issues/17\">#17</a> Since v0.5 few things was deprecated and will be removed in version v1.0:\n* Tag <code><cookie:get/></code>. Use standard <code><g:cookie/></code> tag instead.\n* Methods <code>get()</code>, <code>set()</code>, <code>delete()</code> from <code>CookieService</code>. They are replaced with corresponding <code>getCookie()</code>, <code>setCookie()</code>, <code>deleteCookie()</code>.</li>\n</ul>\n<h3>v0.3</h3>\n<p><a href=\"https://github.com/stokito/grails-cookie/releases/tag/v0.3\">Source</a></p>\n<p>In the v0.3 release a big issue was fixed that now sets the cookie's path to the root <code>/</code> context.\nOtherwise it was setting the path to the same as the controller/service that triggered it.\nMost users I believe will want this behavior. If setting the path is desired, that can be accommodated.\nPlease contact me or do a pull request if you'd like that.</p>\n" |
| }, |
| { |
| "deprecated": "It seems that this project is continued in a fork by double16 and published at the same maven coordinates. This entry in the registry should probably be removed to avoid confusion.", |
| "bintrayPackage": { |
| "name": "cookie-session", |
| "repo": "maven", |
| "owner": "benlucchesi", |
| "desc": "Grails cookiesession plugin", |
| "labels": [ |
| "cookies", |
| "http-session" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/benlucchesi/grails-cookie-session", |
| "latestVersion": "3.0.1", |
| "updated": "2016-03-31T13:31:55.060Z", |
| "systemIds": [ |
| "org.grails.plugins:cookie-session" |
| ], |
| "vcsUrl": "https://github.com/benlucchesi/grails-cookie-session-v2" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Cookie Session Grails Plugin</h1>\n<p>Current Version: 3.0.1</p>\n<p>The Cookie Session plugin enables grails applications to store session data in http cookies between requests instead of in memory on the server. Client sessions are transmitted from the browser to the application with each request and transmitted back with each response. This allows application deployments to be more stateless. Benefits of managing sessions this way include:</p>\n<ul>\n<li>\n<p>Simplified Scaling</p>\n<pre><code>Because a client's session is passed with every request, the deployment architecture need not be concerned \nwith scaling strategies that account for sessions stored on the server, such as session replication or sticky sessions. \nSimply add application instances and route requests to them. Also, because the session data is stored with client, \nthe server doesn't expend memory or disk space storing sessions that are open for long periods of time.\n</code></pre>\n</li>\n<li>\n<p>Fault Tolerance</p>\n<pre><code>When sessions are stored in memory on the server, if an application crashes or becomes inaccessible,\nclients' sessions are usually lost which can result in unexpected logouts, redirects, or loss of data. \nWhen sessions are stored cookies,the applications can be much more tolerant to server-side commission failures. \nIn a single-instance deployment scenario, the server or application can be recycled \nand clients can continue working when the application becomes available and with their session fully intact. In a \nmulti-instance deployment scenario, any instance of the applicatin can service a clients request. A benificial \nside effect of cookie-sessions is that applications can be upgraded or restarted without logging out users.\n</code></pre>\n</li>\n<li>\n<p>Known incompatibility</p>\n<ul>\n<li>spring webflow</li>\n</ul>\n</li>\n</ul>\n<h1>Installation</h1>\n<p>edit build.gradle add the following line under the plugins closure</p>\n<p>compile ":grails-cookie-session-v3:3.0"</p>\n<h1>Configuration</h1>\n<p>The following parameters are supported directly by the cookie-session-v3 plugin. Note, additional configuration is needed for large session support. See additional instructions below.</p>\n<h2>Parameters</h2>\n<table>\n <thead>\n <tr>\n <th>name</th>\n <th>default</th>\n <th>description</th>\n </thead>\n <tbody>\n <tr>\n <td>grails.plugin.cookiesession.enabled</td>\n <td>false</td>\n <td>enables or disables the cookie session.</td>\n </tr>\n <tr>\n <td>grails.plugin.cookiesession.encryptcookie</td>\n <td>true</td>\n <td>enable or disable encrypting session data stored in cookies.</td>\n </tr>\n <tr>\n <td>grails.plugin.cookiesession.cryptoalgorithm</td>\n <td>Blowfish</td>\n <td>The cryptographic algorithm used to encrypt session data (i.e. Blowfish, DES, DESEde, AES). NOTE: the secret must be compatible with the crypto algorithm. Version 2.0.12 supports non-ECB cipher modes, such as 'Blowfish/CBC/PKCS5Padding', that require an initialization vector</td>\n </tr>\n <tr>\n <td>grails.plugin.cookiesession.secret</td>\n <td><b>generated</b></td>\n <td>The secret key used to encrypt session data. If not set, a random key will be created at runtime. Set this parameter if deploying multiple instances of the application or if sessions need to survive a server crash or restart. sessions to be recovered after a server crash or restart.</td>\n </tr>\n <tr>\n <td>grails.plugin.cookiesession.cookiecount</td>\n <td>5</td>\n <td>The maximum number of cookies that are created to store the session in</td>\n </tr>\n <tr>\n <td>grails.plugin.cookiesession.maxcookiesize</td>\n <td>2048</td>\n <td>The max size for each cookie expressed in bytes.</td>\n </tr>\n <tr>\n <td>grails.plugin.cookiesession.sessiontimeout</td>\n <td>0</td>\n <td>The length of time a session can be inactive for expressed in seconds. -1 indicates that a session will be active for as long as the browser is open.</td>\n </tr>\n <tr>\n <td>grails.plugin.cookiesession.cookiename</td>\n <td>gsession-X</td>\n <td>X number of cookies will be written per the cookiecount parameter. Each cookie is suffixed with the integer index of the cookie.</td>\n </tr>\n<pre><code><tr>\n <td>grails.plugin.cookiesession.condenseexceptions</td>\n <td>false</td>\n <td>replaces instances of Exceptions objects in the session with the Exception.getMessage() in the session (see SessionPersistanceListener for further details)</td> \n</tr>\n\n<tr>\n <td>grails.plugin.cookiesession.serializer</td>\n <td>'java'</td>\n <td>specify serializer used to serialize session objects. valid values are: 'java', 'kryo', or the name of a spring bean that implement SessionSerializer. See section on Serializers below.</td> \n</tr>\n\n<tr>\n <td>grails.plugin.cookiesession.usesessioncookieconfig</td>\n <td>false</td>\n <td>version 2.0.12+ uses the ServletContext.SessionCookieConfig to configure cookies used to store the session. values from SessionCookieConfig override config parameters setsecure, sethttp, path, domain, comment, sessiontimeout, and cookiename. See notes below on use of this config option.</td> \n</tr>\n\n<tr>\n <td>grails.plugin.cookiesession.springsecuritycompatibility</td>\n <td>false</td>\n <td>true to configure enhanced compatibility with spring security, false to disable.</td> \n</tr>\n\n<tr>\n <td>grails.plugin.cookiesession.setsecure</td>\n <td>false</td>\n <td>calls Cookie.setSecure on cookie-session cookies. This flag indicates to browsers whether cookies should only be sent over secure connections.</td> \n</tr>\n\n<tr>\n <td>grails.plugin.cookiesession.httponly</td>\n <td>false</td>\n <td>calls Cookie.setHttpOnly on cookie-session cookies. This flag indicates to browsers that the cookie should not be made available to scripts.</td>\n</tr>\n\n<tr>\n <td>grails.plugin.cookiesession.path</td>\n <td>/</td>\n <td>calls Cookie.setPath on cookie-session cookies. This limits the paths for which the browser should send the cookie.</td>\n</tr>\n\n<tr>\n <td>grails.plugin.cookiesession.domain</td>\n <td>-unset-</td>\n <td>calls Cookie.setDomain on cookie-session cookies if set. This tells the browsers which domains the cookie is valid for; if unset, then the cookie is valid for the current host only.</td>\n</tr>\n\n<tr>\n <td>grails.plugin.cookiesession.comment</td>\n <td>-unset-</td>\n <td>calls Cookie.setComment on cookie-session cookies.</td>\n</tr>\n\n\n<tr>\n <td>grails.plugin.cookiesession.id</td>\n <td><b>deprecated</b></td>\n <td>deprecated. use the 'grails.plugin.cookiesession.cookiename' setting.</td>\n</tr>\n\n<tr>\n <td>grails.plugin.cookiesession.timeout</td>\n <td><b>deprecated</b></td>\n <td>deprecated. use the 'grails.plugin.cookiesession.sessiontimeout' setting.</td>\n</tr>\n\n<tr>\n <td>grails.plugin.cookiesession.hmac.secret</td>\n <td><b>deprecated</b></td>\n <td>deprecated. use the 'grails.plugin.cookiesession.secret' setting.</td>\n</tr>\n\n<tr>\n <td>grails.plugin.cookiesession.hmac.id</td>\n <td><b>deprecated</b></td>\n <td>deprecated. no equivelent setting is present in this version of the plugin.</td>\n</tr>\n\n<tr>\n <td>grails.plugin.cookiesession.hmac.algorithm </td>\n <td><b>deprecated</b></td>\n <td>deprecated. use the 'grails.plugin.cookiesession.cryptoalgorithm' settings.</td>\n</tr>\n</code></pre>\n </tbody>\n</table>\n<h2>Example</h2>\n<p>application.yml</p>\n<pre><code> grails:\n plugin:\n cookiesession:\n enabled: true\n encryptcookie: true\n cryptoalgorithm: "Blowfish"\n secret: "This is my secret."\n cookiecount: 10\n maxcookiesize: 2048 // 2kb\n sessiontimeout: 3600 // one hour\n cookiename: 'gsession'\n condenseexceptions: false\n setsecure: true\n sethttponly: false\n path: '/'\n comment: 'Acme Session Info'\n serializer: 'kryo'\n springsecuritycompatibility: true\n</code></pre>\n<h2>Understanding cookiecount and maxcookiesize</h2>\n<p>The maximum session size stored by this plugin is calculated by (cookiecount * maxcookiesize). The reason for these two parameters is that through experimentation, some browsers didn't reliably set large cookies set before the subsequent request. To solve this issue, this plugin supports configuring the max size of each cookie stored and the number of cookies to span the session over. The default values are conservative. If sessions exceed the max session size as configured, first increase the cookiecount and then the maxcookiesize parameters.</p>\n<h2>Enabling large session</h2>\n<p>To enable large sessions, increase the max http header size for the servlet container you are using.</p>\n<p>Due to the potentially large amount of data that may be stored, consider setting it to something large, such as 262144 ( 256kb ).</p>\n<p><em>the following are for grails 2.x, needs to be updated for 3.x - investigating</em></p>\n<h3>Tomcat</h3>\n<p>Edit the server.xml and set the connector's maxHttpHeaderSize parameter.</p>\n<p>When developing in grails, configure the embedded tomcat server with the tomcat configuration event:</p>\n<ol>\n<li>\n<p>create the file scripts/_Events.groovy in your project directory</p>\n</li>\n<li>\n<p>add the following code:</p>\n<pre><code>eventConfigureTomcat = {tomcat ->\n tomcat.connector.setAttribute("maxHttpHeaderSize",262144)\n}\n</code></pre>\n</li>\n</ol>\n<h3>Jetty (2.0.5+)</h3>\n<p>Edit the jetty.xml or web.xml and set the connector's requestHeaderSize and responseHeaderSize parameters.</p>\n<ol>\n<li>\n<p>create the file scripts/_Events.groovy in your project directory</p>\n</li>\n<li>\n<p>add the following code:</p>\n<pre><code>eventConfigureJetty = {jetty ->\n jetty.connectors[0].requestHeaderSize = 262144\n jetty.connectors[0].responseHeaderSize = 262144\n}\n</code></pre>\n</li>\n</ol>\n<h2>SessionPersistenceListener</h2>\n<p>SessionPersistenceListener is an interface used inspect the session just after its been deserialized from persistent storage and just before being serialized and persisted.</p>\n<p>SessionPersistenceListener defines the following methods:\nvoid afterSessionRestored( SerializableSession session )\nvoid beforeSessionSaved( SerializableSession session )</p>\n<p>To use, write a class that implements this interface and define the object in the application's spring application context (grails-app/conf/spring/resources.groovy). The CookieSession plugin will scan the application context and retrieve references to all classes that implement SessionPersistenceListener. The order that the SessionPersistenceListeners are called is unspecified. For an example of how to implement a SessionPersistenceListener, see the ExceptionCondenser class which is part of the cookie-session plugin.</p>\n<p>The ExceptionCondenser uses beforeSessionSaved() to replace instances of Exceptions the exception's message. This is useful because some libraries, notably the spring-security, store exceptions in the session, which can cause the cookie-session storage to overflow. The ExceptionCondenser can be installed by either adding it in the application context or by enabling it with the convenience settings grails.plugin.cookiesession.condenseexceptions = true.</p>\n<h2>Configuring Serialization</h2>\n<p>The grails.plugin.cookiesession.serializer config setting is used to pick which serializer the cookie-session plugin will use to serialize sessions. Currently, only two options are supported: 'java' and 'kryo'. 'java' is used to pick the java.io API serializer. This serializer has proven to be reliable and works 'out of the box'. 'kryo' is used to pick the Kryo serializer (http://code.google.com/p/kryo/). The Kryo serializer has many benifits over the Java serializer, primarily serialized results are significantly smaller which reduces the size of the session cookies. However, the Kryo serializer requires configuration to work correctly with some grails and spring objects. By default the kryo serializer is configured to serialize GrailsFlashScope and other basic grails objects. If the application uses spring-security, you must enabled springsecuritycompatibility for the cookie-session plugin. Additionally you should verify that the serializer is successfully serializing all objects that will be stored in the session. Configure info level logging for 'com.granicus.grails.plugins.cookiesession.CookieSessionRepository' for test and development environments to monitor the serialization and deserialization process. If objects fail to serialize, please report an issue to this github project; a best effort will be made to make the kryo serializer as compatible as possible. If the kryo serializer doesn't work for your application, consider falling back to the java serializer or implementing your own SessionSerializer as described below.</p>\n<h2>Spring Security Compatibility</h2>\n<p>Spring Security Compatibility, configured with the <code>springsecuritycompatibility</code> setting, directs the cookie-session plugin to adjust its behavior to be more compatible with the spring-security-core plugin.</p>\n<p>The primary issue addressed in this mode relates to when the spring-security core's SecurityContextPersistenceFilter writes the current security context to the SecurityContextRepository. In most cases, the SecurityContextPersistenceFilter stores the current security context after the current web response has been written. This is a problem for the cookie-session plugin because the session is stored in cookies in the web response. As a result, the current security context is never saved in the session, in effect losing the security context after each request. To work around this issue, spring security compatibility mode causes the cookie-session plugin to write the current security context to the session just before the session is serialized and saved in cookies. The security context is stored under the key that the SecurityContextRepository expects to find the security context.</p>\n<p>The next issue that Spring Security Compatibility addresses involves cookies saved in the DefaultSavedRequest. DefaultSavedRequest is created by spring security core and stored in the session during redirects, such as after authentication. Spring Security Compatibility causes the cookie-session plugin to detect the presense of a DefaultSavedRequest in the session and remove any cookie-session cookies it may be storing. This ensures that old session information doesn't replace more current session information when following a redirects. This also reduces the size of the the serialized session because the DefaultSavedRequest is storing an old copy of a session in the current session. Finally, Spring Security Compatibility adds custom kryo serializers (when kryo serialization is enabled) to successfully serialize objects that kryo isn't capable of serializing by default.</p>\n<p>When compatibility with Spring Security is enabled the plugin may enforce new session creation if none exists yet. The reason is that without a session present the Security Context would not be persisted and propagaded between requests. This would manifest as an intermittent issue depending whether or not the application uses session for some other purpose or not (e.g. flash scope).</p>\n<h2>use of SessionCookieConfig</h2>\n<p>SessionCookieConfig is a interface introduced in Servlet 3.0 and is used to specify configuration parameters of session cookies. If you enable the grails.plugin.cookiesession.usesessioncookieconfig parameter, then this interface is used to configure the cookie session cookies. In order for this option to work, the servlet context must be servlet context version 3.0 or great.</p>\n<p>The following is an example of how to use the SessionCookieConfig to configure cookies in the init closure in BootStrap.groovy.</p>\n<pre><code> if( servletContext.majorVersion >= 3 ){\n servletContext.sessionCookieConfig.name = 'sugar2'\n servletContext.sessionCookieConfig.secure = false\n servletContext.sessionCookieConfig.maxAge = 3600\n }\n</code></pre>\n<h2>WARNING on updating cookie specifications and general recomendations</h2>\n<p>Be warned, updating the cookie specification can cause unexpected results and cause your application to fail. In general, you should not update the cookie specification once an application is in production. If you do, mutliple cookies with the same name will be saved back to the browser and will be sent back to your application, which will undoubtably cause deserialization of the session cookie to fail. Here are some general recomendations on how to configure cookie session cookie, either with the plugin's configuration options or with the SessionCookieConfig:</p>\n<ul>\n<li>Always configure a reasonable timeout so that in the event that duplicate cookies are created, they'll be cleared from the browser automatically</li>\n<li>Use a unique cookie name for each application. If you run multiple applications under the same domain, this will ensure that cookies between applications don't conflict with one-another, unless you intend to share sessions between applications. In that case, make sure cookies are configured EXACTLY the same.</li>\n<li>Avoid changing the cookie configuration after an application is production. Be aware that any browser storing cookie session cookies that haven't expired will like get duplicate cookie names and experience errors the next time they access the site. This can be avoided by having a short session timeout or by renaming the cookie, in which case ALL existing sessions will be lost.</li>\n</ul>\n<h2>Logging</h2>\n<p>The following logback keys are configurable:</p>\n<ul>\n<li>grails.plugin.cookiesession.CookieSessionFilter</li>\n<li>grails.plugin.cookiesession.SessionRepositoryRequestWrapper</li>\n<li>grails.plugin.cookiesession.SessionRepositoryResponseWrapper</li>\n<li>grails.plugin.cookiesession.CookieSessionRepository</li>\n<li>grails.plugin.cookiesession.JavaSessionSerializer</li>\n<li>grails.plugin.cookiesession.KryoSessionSerializer</li>\n<li>grails.plugin.cookiesession.KryoSessionSerializer</li>\n<li>grails.plugin.cookiesession.SecurityContextSessionPersistenceListener</li>\n<li>grails.plugin.cookiesession.SerializableSession</li>\n</ul>\n<h2>Configured Beans</h2>\n<ul>\n<li>cookieSessionFilter - the plugin filter</li>\n<li>sessionRepository - an implementation of SessionRepository</li>\n<li>javaSessionSerializer or kryoSessionSerializer - serializer configured with 'serializer' config setting.</li>\n</ul>\n<h2>How this plugin works</h2>\n<p>This plugin consists of the following components:</p>\n<ul>\n<li>CookieSessionFilter - a servlet filter installed in the first position of the filter chain which is responsible for wrapping the request and response object with the SessionRepositoryRequestWrapper and SessionRepositoryResponseWrapper objects.</li>\n<li>SessionRepositoryRequestWrapper - an implementation of HttpServletRequestWrapper which delegates responsibility for retrieving session data from persistence storage to an instance of a SessionRepository object and for managing an instance of SerializableSession.</li>\n<li>SessionRespositoryResponseWrapper - an implementation of HttpServletResponseWrapper which delegates saving sessions to persistance storage to an instance of SessionRepository.</li>\n<li>SerializableSession - an implementation of HttpSession that can be serialized</li>\n<li>SessionRepository - an interface that describes a class that can save and restore a session from a persistent location</li>\n<li>CookieSessionRepository - an implementation of SerializableSession that is responsible for the mechanics of storing session data in cookies and retrieve session data from cookies.</li>\n</ul>\n<h3>Execution sequence outline</h3>\n<p>When a request is received by the server, the CookieSessionFilter is called in the filter chain and performs the following:</p>\n<ol>\n<li>retrieves an instance of a SessionRepository bean from the application context</li>\n<li>creates an instance of the SessionRepositoryRequestWrapper, assigning it the SessionRepository instance and the current request</li>\n<li>uses SessionRepositoryRequestWrapper instance to restore the session</li>\n<li>uses the SessionRepositoryInstance to get the current session</li>\n<li>creates an instance of the SessionRepositoryResponseWrapper, assigning it the current session, the SessionRespository instance and the current response object.</li>\n<li>calls the next filter in the chain</li>\n</ol>\n<p>Throughout the remainder of the request, the SessionRepositoryRequestWrapper is only responsible for returning the stored instances of the SerializableSession.</p>\n<p>As the request processing comes to a conclussion the SessionRepositoryResponseWrapper is used to intercept calls that would cause the response to be committed (i.e. written back to the client). When it intercepts these calls, it uses a SessionRepository object to persist the Session object.</p>\n<p>The CookieSession object is a spring bean that implements the SessionRepository interface. This object is injected injected into the application so that it can be replaced with alternative implementations that can store the session to different locations such as database, shared in-memory store, shared filesystem, etc.</p>\n<h2>How to contribute</h2>\n<p>If you want to contribute a bug fix, please work from the 'develop' branch. Additionally, before submitting a pull request please confirm that all of the tests in test suite pass. The test suite is located at github.com/benlucchesi/test-cookie-session-plugin</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "cookie-session", |
| "repo": "plugins", |
| "owner": "double16", |
| "desc": "The Cookie Session plugin enables grails applications to store session data in http cookies between requests instead of in memory on the server.", |
| "labels": [ |
| "cookies", |
| "http-session" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/double16/grails-cookie-session/issues", |
| "latestVersion": "4.0.2", |
| "updated": "2018-07-18T13:04:38.683Z", |
| "systemIds": [ |
| "org.grails.plugins:cookie-session" |
| ], |
| "vcsUrl": "https://github.com/double16/grails-cookie-session" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Cookie Session Grails Plugin</h1>\n<p><a href=\"https://bintray.com/double16/plugins/cookie-session/_latestVersion\"><img src=\"https://api.bintray.com/packages/double16/plugins/cookie-session/images/download.svg\" alt=\"Download\" /></a> <a href=\"https://circleci.com/gh/double16/grails-cookie-session\"><img src=\"https://circleci.com/gh/double16/grails-cookie-session.svg?style=svg&circle-token=aa34d542a6c31d626c75fa8d946858a32132c63e\" alt=\"CircleCI\" /></a></p>\n<p>The Cookie Session plugin enables grails applications to store session data in http cookies between requests instead of in memory on the server. Client sessions are transmitted from the browser to the application with each request and transmitted back with each response. This allows application deployments to be more stateless. Benefits of managing sessions this way include:</p>\n<h2>Simplified Scaling</h2>\n<p>Because a client's session is passed with every request, the deployment architecture need not be concerned with scaling strategies that account for sessions stored on the server, such as session replication or sticky sessions. Simply add application instances and route requests to them. Also, because the session data is stored with client, the server doesn't expend memory or disk space storing sessions that are open for long periods of time.</p>\n<h2>Fault Tolerance</h2>\n<p>When sessions are stored in memory on the server, if an application crashes or becomes inaccessible, clients' sessions are usually lost which can result in unexpected logout, redirects, or loss of data. When sessions are stored cookies,the applications can be much more tolerant to server-side commission failures. In a single-instance deployment scenario, the server or application can be recycled and clients can continue working when the application becomes available and with their session fully intact. In a multi-instance deployment scenario, any instance of the application can service a clients request. A beneficial side effect of cookie-sessions is that applications can be upgraded or restarted without logging out users.</p>\n<ul>\n<li>Known incompatibility\n<ul>\n<li>spring webflow</li>\n</ul>\n</li>\n</ul>\n<h1>Installation</h1>\n<p>Edit <code>build.gradle</code> add the following line under the plugins closure</p>\n<pre><code class=\"language-groovy\"> compile 'org.grails.plugins:cookie-session:4.0.2'\n</code></pre>\n<h1>Configuration</h1>\n<p>The following parameters are supported directly by the cookie-session plugin. Note, additional configuration is needed for large session support. See additional instructions below.</p>\n<h2>Parameters</h2>\n<p>| name | default | description |\n| ---- | ------- | ----------- |\n| grails.plugin.cookiesession.enabled | false | enables or disables the cookie session. |\n| grails.plugin.cookiesession.encryptcookie | true | enable or disable encrypting session data stored in cookies. |\n| grails.plugin.cookiesession.cryptoalgorithm | Blowfish | The cryptographic algorithm used to encrypt session data (i.e. Blowfish, DES, DESEde, AES). NOTE: the secret must be compatible with the crypto algorithm. Version 2.0.12 supports non-ECB cipher modes, such as 'Blowfish/CBC/PKCS5Padding', that require an initialization vector |\n| grails.plugin.cookiesession.secret | <strong>generated</strong> | The secret key used to encrypt session data. If not set, a random key will be created at runtime. Set this parameter if deploying multiple instances of the application or if sessions need to survive a server crash or restart. sessions to be recovered after a server crash or restart. |\n| grails.plugin.cookiesession.cookiecount | 5 | The maximum number of cookies that are created to store the session in |\n| grails.plugin.cookiesession.maxcookiesize | 2048 | The max size for each cookie expressed in bytes. |\n| grails.plugin.cookiesession.warnthreshold | 0.8 | Threshold for logging a warning when the cookie size becomes equal to or greater than the total maximum cookie size (cookieCount * maxCookieSize) |\n| grails.plugin.cookiesession.sessiontimeout | 0 | The length of time a session can be inactive for expressed in seconds. -1 indicates that a session will be active for as long as the browser is open. |\n| grails.plugin.cookiesession.cookiename | gsession-X | X number of cookies will be written per the cookiecount parameter. Each cookie is suffixed with the integer index of the cookie. |\n| grails.plugin.cookiesession.condenseexceptions | false | replaces instances of Exceptions objects in the session with the Exception.getMessage() in the session (see SessionPersistanceListener for further details) |\n| grails.plugin.cookiesession.serializer | 'java' | specify serializer used to serialize session objects. valid values are: 'java', 'kryo', or the name of a spring bean that implement SessionSerializer. See section on Serializers below. |\n| grails.plugin.cookiesession.usesessioncookieconfig | false | version 2.0.12+ uses the ServletContext.SessionCookieConfig to configure cookies used to store the session. values from SessionCookieConfig override config parameters setsecure, sethttp, path, domain, comment, sessiontimeout, and cookiename. See notes below on use of this config option. |\n| grails.plugin.cookiesession.springsecuritycompatibility | false | true to configure enhanced compatibility with spring security, false to disable. |\n| grails.plugin.cookiesession.setsecure | false | calls Cookie.setSecure on cookie-session cookies. This flag indicates to browsers whether cookies should only be sent over secure connections. |\n| grails.plugin.cookiesession.httponly | false | calls Cookie.setHttpOnly on cookie-session cookies. This flag indicates to browsers that the cookie should not be made available to scripts. |\n| grails.plugin.cookiesession.path | / | calls Cookie.setPath on cookie-session cookies. This limits the paths for which the browser should send the cookie. |\n| grails.plugin.cookiesession.domain | -unset- | calls Cookie.setDomain on cookie-session cookies if set. This tells the browsers which domains the cookie is valid for; if unset, then the cookie is valid for the current host only. |\n| grails.plugin.cookiesession.comment | -unset- | calls Cookie.setComment on cookie-session cookies. |\n| grails.plugin.cookiesession.id | <strong>deprecated</strong> | deprecated. use the 'grails.plugin.cookiesession.cookiename' setting. |\n| grails.plugin.cookiesession.timeout | <strong>deprecated</strong> | deprecated. use the 'grails.plugin.cookiesession.sessiontimeout' setting. |\n| grails.plugin.cookiesession.hmac.secret | <strong>deprecated</strong> | deprecated. use the 'grails.plugin.cookiesession.secret' setting. |\n| grails.plugin.cookiesession.hmac.id | <strong>deprecated</strong> | deprecated. no equivalent setting is present in this version of the plugin. |\n| grails.plugin.cookiesession.hmac.algorithm | <strong>deprecated</strong> | deprecated. use the 'grails.plugin.cookiesession.cryptoalgorithm' settings. |</p>\n<h2>Example</h2>\n<p>application.yml</p>\n<pre><code class=\"language-yaml\">grails:\n plugin:\n cookiesession:\n enabled: true\n encryptcookie: true\n cryptoalgorithm: "Blowfish"\n secret: "This is my secret."\n cookiecount: 10\n maxcookiesize: 2048 // 2kb\n sessiontimeout: 3600 // one hour\n cookiename: 'gsession'\n condenseexceptions: false\n setsecure: true\n httponly: false\n path: '/'\n comment: 'Acme Session Info'\n serializer: 'kryo'\n springsecuritycompatibility: true\n</code></pre>\n<h2>Understanding cookiecount and maxcookiesize</h2>\n<p>The maximum session size stored by this plugin is calculated by (cookiecount * maxcookiesize). The reason for these two parameters is that through experimentation, some browsers didn't reliably set large cookies set before the subsequent request. To solve this issue, this plugin supports configuring the max size of each cookie stored and the number of cookies to span the session over. The default values are conservative. If sessions exceed the max session size as configured, first increase the cookiecount and then the maxcookiesize parameters.</p>\n<h2>Enabling large session</h2>\n<p>To enable large sessions, increase the max http header size for the servlet container you are using.</p>\n<p>Due to the potentially large amount of data that may be stored, consider setting it to something large, such as 262144 ( 256kb ).</p>\n<p><em>the following are for grails 2.x, needs to be updated for 3.x - investigating</em></p>\n<h3>Tomcat</h3>\n<p>Edit the server.xml and set the connector's maxHttpHeaderSize parameter.</p>\n<p>When developing in grails, configure the embedded tomcat server with the tomcat configuration event:</p>\n<ol>\n<li>\n<p>create the file scripts/_Events.groovy in your project directory</p>\n</li>\n<li>\n<p>add the following code:</p>\n<pre><code>eventConfigureTomcat = {tomcat ->\n tomcat.connector.setAttribute("maxHttpHeaderSize",262144)\n}\n</code></pre>\n</li>\n</ol>\n<h3>Jetty (2.0.5+)</h3>\n<p>Edit the jetty.xml or web.xml and set the connector's requestHeaderSize and responseHeaderSize parameters.</p>\n<ol>\n<li>\n<p>create the file scripts/_Events.groovy in your project directory</p>\n</li>\n<li>\n<p>add the following code:</p>\n<pre><code>eventConfigureJetty = {jetty ->\n jetty.connectors[0].requestHeaderSize = 262144\n jetty.connectors[0].responseHeaderSize = 262144\n}\n</code></pre>\n</li>\n</ol>\n<h2>SessionPersistenceListener</h2>\n<p>SessionPersistenceListener is an interface used inspect the session just after its been deserialized from persistent storage and just before being serialized and persisted.</p>\n<p>SessionPersistenceListener defines the following methods:</p>\n<pre><code class=\"language-groovy\"> void afterSessionRestored( SerializableSession session )\n void beforeSessionSaved( SerializableSession session )\n</code></pre>\n<p>To use, write a class that implements this interface and define the object in the application's spring application context (grails-app/conf/spring/resources.groovy). The CookieSession plugin will scan the application context and retrieve references to all classes that implement SessionPersistenceListener. The order that the SessionPersistenceListeners are called is unspecified. For an example of how to implement a SessionPersistenceListener, see the ExceptionCondenser class which is part of the cookie-session plugin.</p>\n<p>The ExceptionCondenser uses beforeSessionSaved() to replace instances of Exceptions the exception's message. This is useful because some libraries, notably the spring-security, store exceptions in the session, which can cause the cookie-session storage to overflow. The ExceptionCondenser can be installed by either adding it in the application context or by enabling it with the convenience settings <code>grails.plugin.cookiesession.condenseexceptions = true</code>.</p>\n<h2>Configuring Serialization</h2>\n<p>The grails.plugin.cookiesession.serializer config setting is used to pick which serializer the cookie-session plugin will use to serialize sessions. Currently, only two options are supported: 'java' and 'kryo'. 'java' is used to pick the java.io API serializer. This serializer has proven to be reliable and works 'out of the box'. 'kryo' is used to pick the Kryo serializer (https://github.com/EsotericSoftware/kryo). The Kryo serializer has many benefits over the Java serializer, primarily serialized results are significantly smaller which reduces the size of the session cookies. However, the Kryo serializer requires configuration to work correctly with some grails and spring objects. By default the kryo serializer is configured to serialize GrailsFlashScope and other basic grails objects. If the application uses spring-security, you must enable <code>springsecuritycompatibility</code> for the cookie-session plugin. Additionally you should verify that the serializer is successfully serializing all objects that will be stored in the session. Configure info level logging for <code>grails.plugins.cookiesession.CookieSessionRepository</code> for test and development environments to monitor the serialization and deserialization process. If objects fail to serialize, please report an issue to this github project; a best effort will be made to make the kryo serializer as compatible as possible. If the kryo serializer doesn't work for your application, consider falling back to the java serializer or implementing your own SessionSerializer as described below.</p>\n<h2>Spring Security Compatibility</h2>\n<p>Spring Security Compatibility, configured with the <code>springsecuritycompatibility</code> setting, directs the cookie-session plugin to adjust its behavior to be more compatible with the spring-security-core plugin.</p>\n<p>The primary issue addressed in this mode relates to when the spring-security core's SecurityContextPersistenceFilter writes the current security context to the SecurityContextRepository. In most cases, the SecurityContextPersistenceFilter stores the current security context after the current web response has been written. This is a problem for the cookie-session plugin because the session is stored in cookies in the web response. As a result, the current security context is never saved in the session, in effect losing the security context after each request. To work around this issue, spring security compatibility mode causes the cookie-session plugin to write the current security context to the session just before the session is serialized and saved in cookies. The security context is stored under the key that the SecurityContextRepository expects to find the security context.</p>\n<p>The next issue that Spring Security Compatibility addresses involves cookies saved in the DefaultSavedRequest. DefaultSavedRequest is created by spring security core and stored in the session during redirects, such as after authentication. Spring Security Compatibility causes the cookie-session plugin to detect the presence of a DefaultSavedRequest in the session and remove any cookie-session cookies it may be storing. This ensures that old session information doesn't replace more current session information when following a redirect. This also reduces the size of the the serialized session because the DefaultSavedRequest is storing an old copy of a session in the current session.</p>\n<p>Finally, Spring Security Compatibility adds custom kryo serializers (when kryo serialization is enabled) to successfully serialize objects that kryo isn't capable of serializing by default.</p>\n<p>When compatibility with Spring Security is enabled the plugin may enforce new session creation if none exists yet. The reason is that without a session present the Security Context would not be persisted and propagated between requests. This would manifest as an intermittent issue depending whether or not the application uses session for some other purpose or not (e.g. flash scope).</p>\n<h2>use of SessionCookieConfig</h2>\n<p>SessionCookieConfig is a interface introduced in Servlet 3.0 and is used to specify configuration parameters of session cookies. If you enable the <code>grails.plugin.cookiesession.usesessioncookieconfig</code> parameter, then this interface is used to configure the cookie session cookies. In order for this option to work, the servlet context must be servlet context version 3.0 or great.</p>\n<p>The following is an example of how to use the SessionCookieConfig to configure cookies in the init closure in BootStrap.groovy.</p>\n<pre><code class=\"language-groovy\"> if( servletContext.majorVersion >= 3 ){\n servletContext.sessionCookieConfig.name = 'sugar2'\n servletContext.sessionCookieConfig.secure = false\n servletContext.sessionCookieConfig.maxAge = 3600\n }\n</code></pre>\n<h2>WARNING on updating cookie specifications and general recommendations</h2>\n<p>Be warned, updating the cookie specification can cause unexpected results and cause your application to fail. In general, you should not update the cookie specification once an application is in production. If you do, multiple cookies with the same name will be saved back to the browser and will be sent back to your application, which will undoubtedly cause deserialization of the session cookie to fail. Here are some general recommendations on how to configure cookie session cookie, either with the plugin's configuration options or with the SessionCookieConfig:</p>\n<ul>\n<li>Always configure a reasonable timeout so that in the event that duplicate cookies are created, they'll be cleared from the browser automatically</li>\n<li>Use a unique cookie name for each application. If you run multiple applications under the same domain, this will ensure that cookies between applications don't conflict with one-another, unless you intend to share sessions between applications. In that case, make sure cookies are configured EXACTLY the same.</li>\n<li>Avoid changing the cookie configuration after an application is production. Be aware that any browser storing cookie session cookies that haven't expired will like get duplicate cookie names and experience errors the next time they access the site. This can be avoided by having a short session timeout or by renaming the cookie, in which case ALL existing sessions will be lost.</li>\n</ul>\n<h2>Logging</h2>\n<p>The following logback keys are configurable:</p>\n<ul>\n<li>grails.plugin.cookiesession.CookieSessionFilter</li>\n<li>grails.plugin.cookiesession.SessionRepositoryRequestWrapper</li>\n<li>grails.plugin.cookiesession.SessionRepositoryResponseWrapper</li>\n<li>grails.plugin.cookiesession.CookieSessionRepository</li>\n<li>grails.plugin.cookiesession.JavaSessionSerializer</li>\n<li>grails.plugin.cookiesession.KryoSessionSerializer</li>\n<li>grails.plugin.cookiesession.SecurityContextSessionPersistenceListener</li>\n<li>grails.plugin.cookiesession.SerializableSession</li>\n</ul>\n<h2>Configured Beans</h2>\n<ul>\n<li>cookieSessionFilter - the plugin filter</li>\n<li>sessionRepository - an implementation of SessionRepository</li>\n<li>javaSessionSerializer or kryoSessionSerializer - serializer configured with 'serializer' config setting.</li>\n</ul>\n<h2>How this plugin works</h2>\n<p>This plugin consists of the following components:</p>\n<ul>\n<li>CookieSessionFilter - a servlet filter installed in the first position of the filter chain which is responsible for wrapping the request and response object with the SessionRepositoryRequestWrapper and SessionRepositoryResponseWrapper objects.</li>\n<li>SessionRepositoryRequestWrapper - an implementation of HttpServletRequestWrapper which delegates responsibility for retrieving session data from persistence storage to an instance of a SessionRepository object and for managing an instance of SerializableSession.</li>\n<li>SessionRepositoryResponseWrapper - an implementation of HttpServletResponseWrapper which delegates saving sessions to persistent storage using an instance of SessionRepository.</li>\n<li>SerializableSession - an implementation of HttpSession that can be serialized</li>\n<li>SessionRepository - an interface that describes a class that can save and restore a session from a persistent location</li>\n<li>CookieSessionRepository - an implementation of SerializableSession that is responsible for the mechanics of storing session data in cookies and retrieve session data from cookies.</li>\n</ul>\n<h3>Execution sequence outline</h3>\n<p>When a request is received by the server, the CookieSessionFilter is called in the filter chain and performs the following:</p>\n<ol>\n<li>retrieves an instance of a SessionRepository bean from the application context</li>\n<li>creates an instance of the SessionRepositoryRequestWrapper, assigning it the SessionRepository instance and the current request</li>\n<li>uses SessionRepositoryRequestWrapper instance to restore the session</li>\n<li>uses the SessionRepositoryInstance to get the current session</li>\n<li>creates an instance of the SessionRepositoryResponseWrapper, assigning it the current session, the SessionRepository instance and the current response object.</li>\n<li>calls the next filter in the chain</li>\n</ol>\n<p>Throughout the remainder of the request, the SessionRepositoryRequestWrapper is only responsible for returning the stored instances of the SerializableSession.</p>\n<p>As the request processing comes to a conclusion the SessionRepositoryResponseWrapper is used to intercept calls that would cause the response to be committed (i.e. written back to the client). When it intercepts these calls, it uses a SessionRepository object to persist the Session object.</p>\n<p>The CookieSession object is a spring bean that implements the SessionRepository interface. This object is injected injected into the application so that it can be replaced with alternative implementations that can store the session to different locations such as database, shared in-memory store, shared filesystem, etc.</p>\n<h2>How to contribute</h2>\n<p>If you want to contribute a bug fix, please work from the 'develop' branch. Additionally, before submitting a pull request please confirm that all of the tests in test suite pass. The test suite can be run using <code>gradlew check testAll integrationTestAll</code></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "csrf", |
| "repo": "grails-csrf-plugin", |
| "owner": "matrei", |
| "desc": "CSRF Protection for Grails", |
| "labels": [ |
| "csrf", |
| "security" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/matrei/grails-csrf-plugin/issues", |
| "latestVersion": "2.0.0", |
| "updated": "2025-12-19T15:43:12.000Z", |
| "systemIds": [ |
| "io.github.matrei:grails-csrf" |
| ], |
| "vcsUrl": "https://github.com/matrei/grails-csrf-plugin" |
| }, |
| "documentationUrl": "https://github.com/matrei/grails-csrf-plugin#readme", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/io/github/matrei/grails-csrf/maven-metadata.xml" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "csv", |
| "repo": "plugins", |
| "owner": "sachinverma", |
| "desc": "Grails csv plugin", |
| "labels": [ |
| "csv" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/vsachinv/grails-csv/issues", |
| "latestVersion": "1.0.1", |
| "updated": "2018-02-23T07:25:16.181Z", |
| "systemIds": [ |
| "org.grails.plugins:csv" |
| ], |
| "vcsUrl": "https://github.com/vsachinv/grails-csv" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>grails-csv</h1>\n<p>The csv plugin provides utility methods and also support for reading/writing to csv files. It uses <code>opencsv</code> library.</p>\n<h1>Installation</h1>\n<p>Add dependency to your build.gradle for Grails 3.x:</p>\n<pre><code>repositories {\n ...\n maven { url "http://dl.bintray.com/sachinverma/plugins" }\n}\n\ndependencies {\n compile 'org.grails.plugins:grails-csv:1.0.1'\n}\n</code></pre>\n<p>For further info: [https://github.com/vsachinv/grails-csv/wiki/Grails-CSV]</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "cxf", |
| "repo": "grails-plugins", |
| "owner": "ctoestreich", |
| "desc": "Grails CXF Plugin", |
| "labels": [ |
| "cxf", |
| "soap" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/Grails-Plugin-Consortium/grails-cxf/issues", |
| "latestVersion": "3.1.2", |
| "updated": "2018-05-04T00:36:38.345Z", |
| "systemIds": [ |
| "org.grails.plugins:cxf", |
| "org.grails.plugins:grails-cxf" |
| ], |
| "vcsUrl": "https://github.com/Grails-Plugin-Consortium/grails-cxf" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/Grails-Plugin-Consortium/grails-cxf\"><img src=\"https://travis-ci.org/Grails-Plugin-Consortium/grails-cxf.png?branch=master\" alt=\"Build Status\" /></a></p>\n<p><a name=\"Top\"></a></p>\n<p>The docs for the 2.x branch can be found <a href=\"https://github.com/Grails-Plugin-Consortium/grails-cxf/tree/grails-2\">here</a>. A lot of the previous documentation is somewhat applicable, but I will be creating new docs in the coming weeks.</p>\n<h1>Grails CXF Plugin</h1>\n<p>The 3.x branch of the plugin is a grails plugin that contains simplified features to get simple soap endpoints exposed in grails 3 applications.</p>\n<h2>Getting Started</h2>\n<p>At the core, this plugin is a simple wrapper for geeting grails service classes wired up as direct soap endpoints. As many of the previous features from the 2.x branch as could be ported for the initial release were ported. There will be continued support added for the more complex CXF features going forward.</p>\n<h2>Basic Usage</h2>\n<p>Exposing a service class is as simple as adding the <code>GrailsCxfEndpoint</code> annotation and annotating the methods you wish to expose in the service with <code>WebMethod</code> and <code>WebResult</code></p>\n<pre><code>package com.gpc.demo\n\nimport grails.transaction.Transactional\nimport org.grails.cxf.utils.GrailsCxfEndpoint\n\nimport javax.jws.WebMethod\nimport javax.jws.WebResult\n\n@Transactional\n@GrailsCxfEndpoint\nclass DemoService {\n\n @WebMethod\n @WebResult\n String demoMethod() {\n return "demo"\n }\n}\n</code></pre>\n<h2>Returning Domain Classes</h2>\n<p>If you wish to return domain classes you will need to make sure to add the xml annotations to the domain class.</p>\n<pre><code>package org.grails.cxf.test.example\n\nimport grails.transaction.Transactional\nimport org.grails.cxf.utils.GrailsCxfEndpoint\n\nimport javax.jws.WebMethod\nimport javax.jws.WebParam\nimport javax.jws.WebResult\n\n@Transactional\n@GrailsCxfEndpoint\nclass PersonService {\n\n\t@WebMethod\n\t@WebResult(name = "Person", targetNamespace = "")\n\tPerson createPerson(@WebParam(name = 'name') String name) {\n\t\tPerson.findOrSaveByName(name)\n\t}\n}\n</code></pre>\n<pre><code>package org.grails.cxf.test.example\n\nimport javax.xml.bind.annotation.XmlAccessType\nimport javax.xml.bind.annotation.XmlAccessorType\nimport javax.xml.bind.annotation.XmlElement\n\n@XmlAccessorType(XmlAccessType.NONE)\nclass Person {\n\n @XmlElement\n Long id\n\n @XmlElement\n String name\n\n static constraints = {\n name nullable: false, blank: false\n }\n}\n</code></pre>\n<h2>Custom Interceptors</h2>\n<p>Do add a custom interceptor you should define an bean in your application or imported config class. The reference to the logging interceptor is the name of the defined bean.</p>\n<pre><code>package org.grails.cxf.test.soap.interceptor\n\nimport org.apache.cxf.common.injection.NoJSR250Annotations\nimport org.apache.cxf.common.logging.LogUtils\nimport org.apache.cxf.interceptor.AbstractLoggingInterceptor\nimport org.apache.cxf.interceptor.Fault\nimport org.apache.cxf.message.Message\nimport org.apache.cxf.phase.Phase\nimport org.springframework.beans.factory.annotation.Autowired\n\nimport java.util.logging.Logger\n\n/**\n */\n@NoJSR250Annotations\nclass CustomLoggingInInterceptor extends AbstractLoggingInterceptor {\n\n private static final Logger LOG = LogUtils.getLogger(CustomLoggingInInterceptor)\n def name\n\n CustomLoggingInInterceptor() {\n super(Phase.RECEIVE)\n log LOG, 'Creating the custom interceptor bean'\n }\n\n void handleMessage(Message message) throws Fault {\n //get another web service bean here by name and call it\n\n //Check to see if cxf annotations will inject the bean (looks like no!)\n log LOG, injectedBean?.name ?: 'FAIL - NOT SET'\n log LOG, "$name :: I AM IN CUSTOM IN LOGGER!!!!!!!"\n }\n\n @Override\n protected Logger getLogger() {\n LOG\n }\n}\n</code></pre>\n<pre><code>package grails.cxf.demo\n\nimport grails.boot.GrailsApp\nimport grails.boot.config.GrailsAutoConfiguration\nimport org.grails.cxf.test.soap.interceptor.CustomLoggingInInterceptor\nimport org.springframework.context.annotation.Bean\nimport org.springframework.context.annotation.ImportResource\n\nclass Application extends GrailsAutoConfiguration {\n static void main(String[] args) {\n GrailsApp.run(Application, args)\n }\n\n @Bean\n public CustomLoggingInInterceptor customLoggingInInterceptor(){\n return new CustomLoggingInInterceptor(name: 'injected value')\n }\n}\n</code></pre>\n<pre><code>package org.grails.cxf.test.example\n\nimport grails.transaction.Transactional\nimport org.grails.cxf.utils.GrailsCxfEndpoint\n\nimport javax.jws.WebMethod\nimport javax.jws.WebParam\nimport javax.jws.WebResult\n\n@Transactional\n@GrailsCxfEndpoint(inInterceptors = ['customLoggingInInterceptor'])\nclass PersonService {\n\n\t@WebMethod\n\t@WebResult(name = "Person", targetNamespace = "")\n\tPerson createPerson(@WebParam(name = 'name') String name) {\n\t\tPerson.findOrSaveByName(name)\n\t}\n}\n</code></pre>\n<h2>SERVLET MAPPING</h2>\n<p>The default behavior is to expose the CxfServlet at the <code>/services/*</code> endpoint. If you with to override this behavior you can set the following config:</p>\n<pre><code class=\"language-yml\">cxf:\n servlet:\n mapping: /webservices/*\n</code></pre>\n<h2>EXPOSING CLASSES VIA ANNOTATION</h2>\n<p>When using the annotation, the property values will only be used if the corresponding annotation value is not provided or is set to the default value. The following are available to configure via the annotation:</p>\n<pre><code class=\"language-groovy\">/**\n * Annotation to be use to expose a Service or Endpoint class as a CXF Service via Grails.\n */\n@Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.TYPE)\n@interface GrailsCxfEndpoint {\n String address() default ''\n String name() default ''\n EndpointType expose() default EndpointType.JAX_WS\n boolean soap12() default false\n String wsdl() default ''\n //Interceptors\n String[] inInterceptors() default []\n String[] outInterceptors() default []\n String[] inFaultInterceptors() default []\n String[] outFaultInterceptors() default []\n GrailsCxfEndpointProperty[] properties() default []\n}\n\n@Target(ElementType.METHOD)\n@interface GrailsCxfEndpointProperty {\n public String name() default ''\n public String value() default ''\n}\n\n</code></pre>\n<p><strong>ADDRESS</strong></p>\n<p>The address property is used to adjust the endpoint address that the service will be deployed to. By default if not provided or is the value is empty (""), this will be the name of the Service or Endpoint with the first letter lowercase and the word Endpoint or Service removed from the end of the name. The default behavior would deploy the <code>BoatService</code> as <code>/services/boat</code>.</p>\n<p>If you wish to override this and provide your own service name or address (for versioning support for example) you may set this value.</p>\n<pre><code class=\"language-groovy\">@GrailsCxfEndpoint(address='/v2/custom/path')\nclass CarService {\n ...\n}\n</code></pre>\n<p>The above would be deployed to <code>/services/v2/custom/path</code>.</p>\n<p><strong>EXPOSE</strong></p>\n<p>The <code>expose</code> property will tell the plugin how you wish to expose. The default is <code>EndpointType.JAX_WS</code> which is the same as the following:</p>\n<pre><code class=\"language-groovy\">@GrailsCxfEndpoint(expose=EndpointType.JAX_WS)\nclass CarService {\n ...\n}\n</code></pre>\n<p>Simple and JaxRS types are currently not supported. <em>TODO</em></p>\n<p><strong>NAME</strong></p>\n<p>The <code>name</code> property will tell the plugin how you wish to name the service. This will change the wsdl name property from the default for the example below from <code>CarService</code> to simply just <code>Car</code> like this <code><wsdl:definitions name="Car" targetNamespace="http://demo.gpc.com"></code></p>\n<pre><code class=\"language-groovy\">@GrailsCxfEndpoint(name='Car')\nclass CarService {\n ...\n}\n</code></pre>\n<p><strong>PORT</strong></p>\n<p>The <code>port</code> property will tell the plugin how you wish to name the service port binding. This will change the wsdl name property of the port from the default for the example below from <code>CarServicePort</code> to simply just <code>CarPort</code> like this <code><wsdl:port binding="tns:CarServiceSoapBinding" name="CarPort"></code></p>\n<pre><code class=\"language-groovy\">@GrailsCxfEndpoint(port='CarPort')\nclass CarService {\n ...\n}\n</code></pre>\n<p><strong>SOAP12</strong></p>\n<p>To tell a service to default to SOAP 1.2 instead of 1.1 simply set this to <code>true</code>. The default value is <code>false</code> which will use SOAP 1.1.</p>\n<pre><code class=\"language-groovy\">@GrailsCxfEndpoint(soap12=true)\nclass CarService {\n ...\n}\n</code></pre>\n<p><strong>WSDL</strong></p>\n<p>To expose as a wsdl first jax web service endpoint <a href=\"http://cxf.apache.org/docs/jax-ws-configuration.html\">http://cxf.apache.org/docs/jax-ws-configuration.html</a> add the wsdl property and classpath to the wsdl as well as setting the endpoint type to <code>EndpointType.JAX_WS_WSDL</code>.</p>\n<pre><code class=\"language-groovy\">@WebService(name = 'CustomerServiceWsdlEndpoint',\ntargetNamespace = 'http://test.cxf.grails.org/',\nserviceName = 'CustomerServiceWsdlEndpoint',\nportName = 'CustomerServiceWsdlPort')\n@GrailsCxfEndpoint(wsdl = 'org/grails/cxf/test/soap/CustomerService.wsdl', expose = EndpointType.JAX_WS_WSDL)\nclass AnnotatedCustomerServiceWsdlEndpoint {\n\n CustomerServiceEndpoint customerServiceEndpoint\n\n List<Customer> getCustomersByName(final String name) {\n customerServiceEndpoint.getCustomersByName(name)\n }\n}\n</code></pre>\n<p>Example <em>TODO</em></p>\n<p><a name=\"interceptors\"></a>\n<strong>ININTERCEPTORS</strong></p>\n<p>This is a list of bean names in <code>List<String></code> to inject to the cxf service endpoint. You will need to define your interceptor beans via normal spring dsl (in resources.groovy for example).</p>\n<p>This is helpful when the default cxf annotation of <code>@org.apache.cxf.interceptor.InInterceptors (interceptors = {"com.example.Test1Interceptor" })</code> does not satisfy your needs.</p>\n<p>When chosing between the this property and the cxf provided one, if you require value injection, the cxf provided annotation will most likely <strong>NOT</strong> meet your needs and you should use this property instead.</p>\n<p><em>Note: Make sure to set any beans you wish injected into your interceptors to <code>bean.autowire = 'byName'</code> or use the <code>@Autowire</code> annotation.</em></p>\n<p><strong>OUTINTERCEPTORS</strong></p>\n<p>If you wish to inject a custom in interceptor bean, use this property. This is helpful when the default cxf annotation of <code>@org.apache.cxf.interceptor.OutInterceptors (interceptors = {"com.example.Test1Interceptor" })</code> does not satisfy your needs.</p>\n<p>See above for examples of using inInterceptor which should be very similar.</p>\n<p><strong>INFAULTINTERCEPTORS</strong></p>\n<p>If you wish to inject a custom in interceptor bean, use this property. This is helpful when the default cxf annotation of <code>@org.apache.cxf.interceptor.InFaultInterceptors (interceptors = {"com.example.Test1Interceptor" })</code> does not satisfy your needs.</p>\n<p>See above for examples of using inInterceptor which should be very similar.</p>\n<p><strong>OUTFAULTINTERCEPTORS</strong></p>\n<p>If you wish to inject a custom in interceptor bean, use this property. This is helpful when the default cxf annotation of <code>@org.apache.cxf.interceptor.OutFaultInterceptors (interceptors = {"com.example.Test1Interceptor" })</code> does not satisfy your needs.</p>\n<p>See above for examples of using inInterceptor which should be very similar.</p>\n<p><strong>CONCLUSION</strong></p>\n<p>Using the annotation will help reduce the clutter of having many static properties in your class to configure cxf.</p>\n<h2>Demo Project</h2>\n<p>https://github.com/Grails-Plugin-Consortium/grails-cxf-demo</p>\n<p align=\"right\"><a href=\"#Top\">Top</a></p>\n<a name=\"License\"></a>\nLICENSE\n---------------\n<p>Copyright 2013 Christian Oestreich</p>\n<p>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</p>\n<p>http://www.apache.org/licenses/LICENSE-2.0</p>\n<p>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.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "cxf-client", |
| "repo": "grails-plugins", |
| "owner": "ctoestreich", |
| "desc": "Grails CXF Client Plugin", |
| "labels": [ |
| "cxf", |
| "soap", |
| "client" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/Grails-Plugin-Consortium/grails-cxf-client/issues", |
| "latestVersion": "3.0.7", |
| "updated": "2016-04-11T19:21:38.732Z", |
| "systemIds": [ |
| "org.grails.plugins:cxf-client", |
| "org.grails.plugins:grails-cxf-client" |
| ], |
| "vcsUrl": "https://github.com/Grails-Plugin-Consortium/grails-cxf-client" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "database-migration", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Grails database-migration plugin", |
| "labels": [ |
| "liquibase", |
| "migration", |
| "database" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/grails-database-migration/issues", |
| "latestVersion": "5.0.0", |
| "updated": "2024-12-18T22:20:28.000Z", |
| "systemIds": [ |
| "org.grails.plugins:database-migration" |
| ], |
| "vcsUrl": "https://github.com/grails/grails-database-migration" |
| }, |
| "documentationUrl": "https://grails.github.io/grails-database-migration/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/grails/plugins/database-migration/maven-metadata.xml", |
| "readme": null |
| }, |
| { |
| "comment": "There is no published version that is compatible with Grails >= 3 (0.3 is not published as of this writing)", |
| "bintrayPackage": { |
| "name": "daysofweek", |
| "repo": "daysofweek", |
| "owner": "vahid", |
| "desc": "Grails Days Of week plugin using ICU4J libraries to work out international calendar week days", |
| "labels": [ |
| "calendar" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/vahidhedayati/grails-daysofweek-plugin/issues", |
| "latestVersion": "0.2", |
| "updated": "2019-05-17T13:10:27.982Z", |
| "systemIds": [ |
| "org.grails.plugins:daysofweek" |
| ], |
| "vcsUrl": "https://github.com/vahidhedayati/grails-daysofweek-plugin" |
| }, |
| "documentationUrl": "https://vahidhedayati.github.io/grails-daysofweek-plugin/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>daysofweek</h1>\n<h3>Side note - similar / related projects</h3>\n<ul>\n<li>\n<p><a href=\"https://github.com/vahidhedayati/grails-daysofweek-plugin\">grails-daysofweek-plugin (this)</a></p>\n</li>\n<li>\n<p><a href=\"https://github.com/vahidhedayati/grails-icucalendar-plugin\">grails-icucalendar-plugin</a></p>\n</li>\n</ul>\n<p>Grails Days Of week plugin using ICU4J libraries to work out internationl calendar week days</p>\n<p>Dependency Grails 2:</p>\n<pre><code class=\"language-groovy\">\tcompile ":daysofweek:0.1"\n</code></pre>\n<p><a href=\"https://github.com/vahidhedayati/grails-daysofweek-plugin/tree/grails2\">Grails 2 source</a></p>\n<p>Dependency Grails 3 (build.gradle):</p>\n<pre><code class=\"language-groovy\">\tcompile "org.grails.plugins:daysofweek:0.3"\n</code></pre>\n<p><a href=\"https://github.com/vahidhedayati/grails-daysofweek-plugin\">Grails 3 source</a></p>\n<h2>Documentation</h2>\n<h4><a href=\"https://vahidhedayati.github.io/grails-daysofweek-plugin/gapi/index.html\">Class usages</a></h4>\n<p><img src=\"https://raw.githubusercontent.com/vahidhedayati/grails-daysofweek-plugin/master/docs/sample.png\" alt=\"sample image\" /></p>\n<h4>daysofweek provides a bootstrap and jquery-ui method of showing the actual days output, depending on which you prefer or already have installed</h4>\n<p>The plugin without being wired back into validation bean will return a list of selected days of the week by end user\nby default <code>bindToBean</code> is disabled is won't bind to the bean, this needs to be set to true to get it internal validation bean to pickup calculate. Only 1 element on a given form within gsp can bind to the bean. The rest will need to follow this method. Please refer to example below for a better insight.</p>\n<p>To get a final value which this plugin converts to / from you need to run:\n<code>Byte dow = DaysOfWeek.fromListToBit(params.list('daysOfWeek'))</code></p>\n<p>This return a byte value of dow which contains which week days the end user has selected. When this is stored and reloaded in the context of above bean it will show the days as per selection.</p>\n<h4>Using plugin:</h4>\n<p>Simply call <code><dow:week ....{below options} /></code> :</p>\n<p>This will return as above your own <code>fieldName</code> as the params back or by default as above <code>daysOfWeek</code> which contains a 'Byte' value which represents the bitwise value of the week days the end user has selected.</p>\n<p>Simply wire in that same byte value back into same tag lib and set <code>dow</code> to be that value for the plugin to draw out the selected days of the week user selected previously.</p>\n<pre><code>dow="${myDow}" = The byte value if already provided from db or something\ndow="${64 as Byte}" = you setting byte value manually this then populates relevant days.\n\ndaysOfweek="${['SUN','MON','TUE','WED','THU','FRI','SAT']}" = either provide the dow above \n\t\t\t\t\t\tor physical a list of a selection of day names as shown\n\n\ncontext="section2" = Not needed if called only once on page, this is so that js stuff works per call \n \nshowLocale="${true}" = To show the locale in showLabel only works if showLabel is on\n\nshowLabel="${true}" = Show week days label and if showLocale true also shows locale\n\nfieldName="myDow" = This is the variable name of your checkbox by default daysOfWeek \n\nlocale="${new Locale("ar","IQ")}" = Override system locale to show which ever order of days of week\n\t\t\t\t\tPlease note this only overrides the ordering sequence of days and not actual screen\n\t\t\t\t\t text which is done via ?lang=th lang parameter on url line.\n\t\t\t\t\t \n template="/some/path/to/gsp/template/_override_plugin.gsp" =This is to override the template to your\n \t\t\t\t\t\t own custom template if you so wish not to use plugin method of display days etc.\n \n bindToBean="${true}" = This by default is false if set to true one one <dow:week on a given page \n \t\t\t\t\t\tcan auto bind to backend bean as per controllers above.\n \n activateAll="${true}" =this is by defaut false, if there is currently no value provided and there \n \t\t\t\t\t\tare no active selected days, it attempts to pre-select all days for form loading up. \n \t\t\t\t\t\tYou may wish for it to show everything as active as page starts up\n\n</code></pre>\n<h4><a href=\"https://github.com/vahidhedayati/grails-daysofweek-plugin/blob/master/example.md\">Example controller/views: How to use daysofweek</a></h4>\n<h4><a href=\"https://www.youtube.com/watch?v=Jq2fXYep3QU\">Youtube video demonstrating plugin</a></h4>\n<h3>Points of reference</h3>\n<p><a href=\"http://stackoverflow.com/questions/313417/whats-the-best-way-to-store-the-days-of-the-week-an-event-takes-place-on-in-a-r\">Info behind weekdays byte value stackoverflow link</a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "db-reverse-engineer", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Grails db-reverse-engineer plugin", |
| "labels": [ |
| "database" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/grails-db-reverse-engineer/issues", |
| "latestVersion": "4.0.0", |
| "updated": "2017-01-26T14:03:06.363Z", |
| "systemIds": [ |
| "org.grails.plugins:db-reverse-engineer" |
| ], |
| "vcsUrl": "https://github.com/grails-plugins/grails-db-reverse-engineer" |
| }, |
| "documentationUrl": "https://grails-plugins.github.io/grails-db-reverse-engineer/", |
| "mavenMetadataUrl": null, |
| "readme": null |
| }, |
| { |
| "displayName": "oauth", |
| "bintrayPackage": { |
| "name": "desirableobjects.grails.plugins:oauth", |
| "repo": "grails-plugins", |
| "owner": "desirable-objects", |
| "desc": "Grails oauth plugin", |
| "labels": [ |
| "oauth" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/antony/grails-oauth-scribe/issues", |
| "latestVersion": "4.0.0", |
| "updated": "2017-05-17T21:16:51.385Z", |
| "systemIds": [ |
| "org.grails.plugins:oauth" |
| ], |
| "vcsUrl": "https://github.com/antony/grails-oauth-scribe" |
| }, |
| "documentationUrl": "https://antony.github.io/grails-oauth-scribe/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>grails-oauth-scribe</h1>\n<p><a href=\"https://gitter.im/antony/grails-oauth-scribe?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge\"></a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "distributed-lock", |
| "repo": "grails3-plugins", |
| "owner": "bertramlabs", |
| "desc": "This plugin provides a framework and interface for a synchronization mechanism distributed to multiple server instances. In today's world of horizontal computational\nscale and massive concurrency, it becomes increasingly difficult to synchronize operations outside the context of a single computational space (server/process). This plugin aims to make that\neasier by providing a simple service to facilitate this, as well as defining an interface for adding low level providers.\n", |
| "labels": [ |
| "lock" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/bertramdev/distributed-lock/issues", |
| "latestVersion": "7.0.0", |
| "updated": "2024-12-30T16:49:04.000Z", |
| "systemIds": [ |
| "com.bertramlabs.plugins:distributed-lock" |
| ], |
| "vcsUrl": "https://github.com/bertramdev/distributed-lock" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/com/bertramlabs/plugins/distributed-lock/maven-metadata.xml", |
| "readme": "<h1>Grails Distributed Lock</h1>\n<p>This plugin provides a framework and interface for a synchronization mechanism that can be distributed outside the context of the app container it runs in. In today's world of horizontal computational\nscale and massive concurrency, it becomes increasingly difficult to synchronize operations outside the context of a single computational space (server/process/container). This plugin aims to make that\neasier by providing a simple service to facilitate this, as well as defining an interface for adding low level providers.</p>\n<p>In the current release, only a provider for <a href=\"http://redis.io\">redis</a> currently exists, which depends on the <a href=\"http://grails.org/plugin/redis\">grails-redis</a> plugin. Any other providers are welcome contributions.</p>\n<h2>Release Notes</h2>\n<ul>\n<li><strong>0.1:</strong> Initial release</li>\n<li><strong>0.2:</strong> Adding withLock() variations for convenience to LockService impl</li>\n<li><strong>0.2.1:</strong> Minor bug fixes in configuration</li>\n<li><strong>0.2.2:</strong> Minor fix for domain class identification</li>\n</ul>\n<h2>Things to be Done</h2>\n<ul>\n<li>Add Provider for <a href=\"http://memcached.org/\">memcached</a></li>\n<li>Add Provider for <a href=\"http://grails.org/doc/latest/guide/GORM.html\">gorm</a></li>\n<li>Add Provider for <a href=\"http://basho.com/riak\">riak</a></li>\n</ul>\n<h2>Installation</h2>\n<p>Add the plugin to your <strong>BuildConfig.groovy</strong>:</p>\n<pre><code class=\"language-java\">plugins {\n\tcompile ":distributed-lock:0.1.0"\n}\n</code></pre>\n<h2>Configuration</h2>\n<p>First thing is to configure your redis store. Add sample config to your <strong>Config.groovy</strong>:</p>\n<pre><code class=\"language-java\">grails {\n\tredis {\n\t\thost = 'localhost'\n\t\tport = 6379\n\t}\n}\n</code></pre>\n<p><strong>NOTE:</strong> Please see <a href=\"http://grails.org/plugin/redis\">grails-redis</a> for more configuration details for your redis store</p>\n<p>Next, configure your <strong>distributed-lock</strong> options:</p>\n<pre><code class=\"language-java\">distributedLock {\n\tprovider {\n\t\ttype = RedisLockProvider // Currently the only available provider\n\t\t// NOTE: Use only if not using the default redis connection\n\t\t// connection = 'otherThanDefault'\n\t}\n\traiseError = true //optional\n\tdefaultTimeout = 10000l //optional\n\tdefaultTTL = 1000l * 60l * 60l //optional (1 hour)\n\tnamespace = 'example-app' //optional\n}\n</code></pre>\n<p>Configuration options:</p>\n<ul>\n<li>\n<p><strong>provider:</strong> This block is used to describe your implementation provider</p>\n<ul>\n<li><strong>type:</strong> The implementation class of a low level provider (currently only <strong>RedisLockProvider</strong> avail)</li>\n<li><strong>connection:</strong> Used by redis provider to specify specific connection (if using <a href=\"http://grails.org/plugin/redis\">grails-redis</a> multi connection)</li>\n</ul>\n</li>\n<li>\n<p><strong>raiseError:</strong> Config option to throw exceptions on failures as opposed to just returning boolean status (defaults to 'true')</p>\n</li>\n<li>\n<p><strong>namespace:</strong> Specify a namespace for your lock keys (defaults to 'distributed-lock')</p>\n</li>\n<li>\n<p><strong>defaultTimeout:</strong> The default time (in millis) to wait for a lock acquire before failing (defaults to '30000')</p>\n</li>\n<li>\n<p><strong>defaultTTL:</strong> The TTL (in millis) for an active lock. If its not released in this much time, it will be force released when expired. Value defaults to 0 (never expires)</p>\n</li>\n</ul>\n<h2>Usage</h2>\n<p>The plugin provides a single non transactional service that handles all lock negotiation that you can inject in any of your services</p>\n<pre><code class=\"language-java\">class MyService {\n\tdef lockService\n\t\n\tdef someMethod() {\n\t\tdef lockKey = lockService.acquireLock('/lock/a/shared/fs')\n\t}\n}\n</code></pre>\n<p><strong>LockService Methods</strong></p>\n<ul>\n<li><strong>acquireLock(</strong> <em>String lockName, Map options = null</em> <strong>):</strong> attempts to acquire a lock of <em>lockName</em> with the optional <em>options</em>. Returns true on success.</li>\n<li><strong>acquireLockByDomain(</strong> <em>Object domainInstance, Map options = null</em> <strong>):</strong> Convenience method to acquire a lock derived from a domain class instance. Returns true on success..</li>\n<li><strong>releaseLock(</strong> <em>String lockName, Map options = null</em> <strong>):</strong> release a lock <em>lockName</em> when no longer needed. Returns true on success.</li>\n<li><strong>releaseLockByDomain(</strong> <em>Object domainInstance, Map options = null</em> <strong>):</strong> release a lock derived from a domain class instance. Returns true on success.</li>\n<li><strong>renewLock(</strong> <em>String lockName, Map options = null</em> <strong>):</strong> Can renew the lease on an expiring active lock. If no ttl specified in options, lock ceases to become volatile. Returns true on success.</li>\n<li><strong>renewLockByDomain(</strong> Object domainInstance, Map options = null_ <strong>):</strong> Renew a lock derived from a domain class instance. Returns true on success.</li>\n<li><strong>getLocks()</strong>: Returns a Set<String> of lock names that are currently active in the system.</li>\n</ul>\n<p><strong>Options</strong></p>\n<p>The optional Map allows you to override certain configuration settings just for the context of your method call. Options include:</p>\n<ul>\n<li><strong>timeout:</strong> time in millis to wait for for the operation to complete before returning failure</li>\n<li><strong>ttl:</strong> time in millis for an acquired lock to expire itself if not released</li>\n<li><strong>raiseError:</strong> boolean instructing whether to throw an exception on failure or just return boolean status</li>\n</ul>\n<h2>Examples</h2>\n<p>Simple usages of <strong>LockService</strong>:</p>\n<pre><code class=\"language-java\">def lockKey = lockService.acquireLock('mylock')\n\t\nif (lockKey) {\n\t// Perform on operation we want synchronized\n}\nelse {\n\tprintln("Unable to obtain lock")\n}\n\t\n// try/finally to release lock\ntry {\n\tdef lock = lockService.acquireLock('lock2', [timeout:2000l, ttl:10000l, raiseError:false])\n\tif (lock) {\n\t\t// DO SOME SYNCHRONIZED STUFF\n\t}\n}\nfinally {\n\tlockService.releaseLock('lock2',[lock: lock])\n}\n</code></pre>\n<p>Threaded sample using <a href=\"http://grails.org/plugin/executor\">executor</a> plugin:</p>\n<pre><code class=\"language-java\">def lockService\n\t\n(0..10).each { i ->\n\trunAsync {\n\t\tdef lock\n\t\ttry {\n\t\t\tif (lock = lockService.acquireLock('test-run', [timeout:5000l]))\n\t\t\t\tprintln("Lock acquired for thread ${i}")\n\t\t\telse\n\t\t\t\tprintln("Failed to acquire lock for thread ${i}")\n\t\t\t\t\n\t\t\t// Sleep for random amount of time\n\t\t\tsleep(new Random().nextInt(1000) as Long)\n\t\t}\n\t\tfinally {\n\t\t\tlockService.releaseLock('test-run',[lock:lock])\n\t\t}\n\t}\n}\n</code></pre>\n<h2>Extending/Contributing</h2>\n<p>To add additional providers is simple. Simply extend the abstract <strong>com.bertram.lock.LockProvider</strong> class and implement its abstract methods. Once the new provider is implemented, it must be added to the <strong>LockServiceConfigurer</strong> configuration method. Please submit contributions via pull request.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "distributed-mutex", |
| "repo": "grails-plugins", |
| "owner": "budjb", |
| "desc": "The Distributed Mutex plugin provides a way to create mutexes backed by a database row. This helps when writing distributed systems that need to lock a resource but database transactions are not sufficient to encapsulate the resource being accessed.", |
| "labels": [ |
| "lock" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/budjb/grails-distributed-mutex/issues", |
| "latestVersion": "3.0.0", |
| "updated": "2016-09-14T14:47:40.885Z", |
| "systemIds": [ |
| "org.grails.plugins:distributed-mutex" |
| ], |
| "vcsUrl": "https://github.com/budjb/grails-distributed-mutex" |
| }, |
| "documentationUrl": "https://budjb.github.io/grails-distributed-mutex/", |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/budjb/grails-distributed-mutex\"><img src=\"https://travis-ci.org/budjb/grails-distributed-mutex.svg?branch=grails-3.x\" alt=\"Build Status\" /></a></p>\n<h2>Distributed Mutex Plugin for Grails</h2>\n<p>See the documentation at http://budjb.github.io/grails-distributed-mutex/3.x/latest.</p>\n" |
| }, |
| { |
| "displayName": "grails-simple-captcha", |
| "bintrayPackage": { |
| "name": "domurtag.plugins:grails-simple-captcha", |
| "repo": "plugins", |
| "owner": "domurtag", |
| "desc": "Grails grails-simple-captcha plugin", |
| "labels": [ |
| "captcha" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/domurtag/grails-simple-captcha/issues", |
| "latestVersion": "1.0.0-grails3", |
| "updated": "2016-03-31T13:31:54.971Z", |
| "systemIds": [ |
| "domurtag.plugins:grails-simple-captcha" |
| ], |
| "vcsUrl": "https://github.com/domurtag/grails-simple-captcha" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/donalmurtagh/grails-simple-captcha\"><img src=\"https://travis-ci.org/donalmurtagh/grails-simple-captcha.svg?branch=master\" alt=\"Build Status\" /></a></p>\n<h2>Summary</h2>\n<p>Grails plugin that creates simple image CAPTCHAs that protect against automated completion and submission of HTML forms.</p>\n<h2>Grails Versions</h2>\n<p>Versions of this plugin that are compatible with Grails 1.X and 2.X are on the master branch. Grails 3.X compatible versions are on the grails3 branch. The first Grails 3 compatible version is <code>1.0.0-grails3</code>.</p>\n<h2>Description</h2>\n<h3>Overview</h3>\n<p>A CAPTCHA is a small image that is embedded in a HTML form to protect against automated completion and submission of HTML forms.\nThey generally consist of an image of a short string of random characters visually obsfucated in some way (see <a href=\"http://en.wikipedia.org/wiki/Captcha\">wikipedia</a> for more information).</p>\n<p>This plugin generates a small CAPTCHA image when the CaptchaController is invoked. The CAPTCHA image and it's solution is stored in the session by default,\nthough the pugin can be used without session storage if necessary. A typical example of the CAPTCHAs generated by this plugin is shown below.</p>\n<p><img src=\"grails-app/assets/images/captcha-example.png\" alt=\"Example CAPTCHA\" /></p>\n<h3>Why another CAPTCHA plugin?</h3>\n<p>Although there is already a Grails plugin available for reCAPTCHA (a very popular CAPTCHA implementation), there are a number of differences between these two plugins:</p>\n<ul>\n<li>reCAPTCHA can be slow to load because the CAPTCHA image is created and solved at a remote server. This plugin creates its own CAPTCHA images, so no remote requests are required to create or solve the CAPTCHAs</li>\n<li>reCAPTCHA challenges can be very difficult to solve, whereas the CAPTCHAs generated by this plugin are very easy to solve</li>\n<li>The solution of this plugin's CAPTCHA challenges is case insensitive</li>\n<li>The CAPTCHAs generated by this plugin can be displayed in multiple places on the same page, there is no easy way to do this with reCAPTCHA</li>\n</ul>\n<p>On the other hand, reCAPTCHA provides a number of features that are absent from this plugin, e.g. audio CAPTCHAs for those with impaired vision.</p>\n<h3>Usage</h3>\n<p>A CAPTCHA can be added to a form using the following GSP code</p>\n<pre><code class=\"language-html\"><img src="${createLink(controller: 'simpleCaptcha', action: 'captcha')}"/>\n<label for="captcha">Type the letters above in the box below:</label>\n<g:textField name="captcha"/>\n</code></pre>\n<p>As mentioned above, the CAPTCHAs generated by this plugin can be simultaneously displayed in several places on the same page\n(this is only possible with reCAPTCHA if you use JavaScript to clone the CAPTCHA).</p>\n<p>To check whether the solution to the CAPTCHA is correct:</p>\n<pre><code class=\"language-groovy\">class MyController {\n def simpleCaptchaService\n // This is the action that handles the submission of the form with the CAPTCHA\n def save = {\n boolean captchaValid = simpleCaptchaService.validateCaptcha(params.captcha) \n }\n}\n</code></pre>\n<p>The process of validating a CAPTCHA also removes it from the session, so it is only possible to validate each CAPTCHA once.\nThe CAPTCHA is removed from the seesion after validation to ensure that the next time a CAPTCHA is requested, a\ndifferent challenge will be presented.</p>\n<h3>Configuration</h3>\n<p>The plugin provides a number of optional configuration parameters that can be overriden in Config.groovy. The default\nvalues of these parameters are shown below:</p>\n<pre><code class=\"language-groovy\">simpleCaptcha {\n // font size used in CAPTCHA images\n fontSize = 30\n height = 200\n width = 200\n // number of characters in CAPTCHA text\n length = 6\n\n // amount of space between the bottom of the CAPTCHA text and the bottom of the CAPTCHA image\n bottomPadding = 16\n\n // distance between the diagonal lines used to obfuscate the text\n lineSpacing = 10\n\n // the charcters shown in the CAPTCHA text must be one of the following\n chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"\n\n // this param will be passed as the first argument to this java.awt.Font constructor\n // http://docs.oracle.com/javase/6/docs/api/java/awt/Font.html#Font(java.lang.String,%20int,%20int)\n font = "Serif"\n}\n</code></pre>\n<h4>Per-Locale Configuration</h4>\n<p>The characters that are shown in the CAPTCHA can be configured per-locale. For example, if you want only the characters\n\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd \ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd to be shown by the CAPTCHA in the French locale, add the following to <code>messages_fr.properties</code></p>\n<pre><code>simpleCaptcha.chars=\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd \ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\n</code></pre>\n<p>If a locale-specific configuration is found it will override the global configuration in <code>Config.groovy</code></p>\n<h3>Session Storage</h3>\n<p>The plugin stores the CAPTCHA image and its solution in the session by default. If it is not feasible to use session storage,\nthe plugin can instead store a digest (hash) of the solution in a cookie. When a CAPTCHA solution is submitted, it is\nvalidated by comparing the digested solution with this cookie value. This option can be enabled simply by adding the\nfollowing config parameter:</p>\n<pre><code>simpleCaptcha.storeInSession = false\n</code></pre>\n<p>If session storage is disabled it is not possible to display a CAPTCHA in multiple places on the same page.</p>\n" |
| }, |
| { |
| "displayName": "runtime-datasources", |
| "bintrayPackage": { |
| "name": "domurtag.plugins:runtime-datasources", |
| "repo": "plugins", |
| "owner": "domurtag", |
| "desc": "Grails runtime-datasources plugin", |
| "labels": [ |
| "database" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/domurtag/runtime-datasources/issues", |
| "latestVersion": "0.2-grails3", |
| "updated": "2016-03-31T13:31:55.050Z", |
| "systemIds": [ |
| "domurtag.plugins:runtime-datasources" |
| ], |
| "vcsUrl": "https://github.com/domurtag/runtime-datasources" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/donalmurtagh/runtime-datasources\"><img src=\"https://travis-ci.org/donalmurtagh/runtime-datasources.svg?branch=master\" alt=\"Build Status\" /></a></p>\n<h2>Introduction</h2>\n<p>Grails plugin that enables an application to add or remove JDBC datasources at runtime, and provides convenience methods\nfor executing SQL statements against these datasources</p>\n<h2>Versions</h2>\n<p>Versions of this plugin that are compatible with Grails 2.X are on the master branch. Grails 3.X compatible versions are on the grails3 branch. The first Grails 3 compatible version is <code>0.2-grails3</code>.</p>\n<h2>Limitations</h2>\n<p>GORM/Hibernate cannot be used with datasources added at runtime, because GORM requires <a href=\"http://grails.org/doc/latest/guide/conf.html#multipleDatasources\">the mapping between a domain\nclass and datasource</a> to be defined at compile-time</p>\n<h2>Add a DataSource</h2>\n<p>Dependency-inject the <code>runtimeDataSourceService</code> service provided by the plugin and call it like so:</p>\n<pre><code class=\"language-groovy\">import javax.sql.DataSource\nimport org.apache.tomcat.jdbc.pool.DataSource as JdbcDataSource\n\nDataSource runtimeDataSource = runtimeDataSourceService.addDataSource('myDataSource', JdbcDataSource) {\n driverClassName = 'com.mysql.jdbc.Driver'\n url = 'jdbc:mysql://localhost/example'\n username = 'root'\n password = 'password'\n}\n</code></pre>\n<p>If successful, the method returns the created datasource.</p>\n<h3>Arguments</h3>\n<ol>\n<li>The name of the Spring bean that will be registered for this datasource. If a Spring bean with this name already\nexists, an exception will be thrown</li>\n<li>Defines the implementation class of the Spring bean. This class must implement the <code>javax.sql.DataSource</code> interface.</li>\n<li>A closure that defines the properties of this datasource. At a minimum, the properties shown in the example above\nshould be provided. This closure supports the same properties as the closure that is used to set datasource properties\nat compile-time in <tt>DataSource.groovy</tt></li>\n</ol>\n<h2>Remove a DataSource</h2>\n<p>The same service that is used to add datasources can also remove them:</p>\n<pre><code class=\"language-groovy\">runtimeDataSourceService.removeDataSource('myDataSource')\n</code></pre>\n<p>The argument should be the name of the datasource's Spring bean. The method returns <code>true</code> if the datasource was successfully\nremoved, or <code>false</code> if a datasource Spring bean with this name could not be found.</p>\n<h2>Using a Runtime DataSource</h2>\n<p>A reference to a <code>DataSource</code> instance added at runtime can be obtained in one of the following methods</p>\n<ol>\n<li>The <code>DataSource</code> instance is returned upon creation (see examples above)</li>\n<li>The <code>DataSource</code> instance can also be retrieved from the Spring application context, e.g.</li>\n</ol>\n<pre><code class=\"language-groovy\">class MyService implements ApplicationContextAware {\n\n ApplicationContext applicationContext\n \n private DataSource getRuntimeDataSource(String beanName) {\n \n // the second parameter can be omitted\n applicationContext.getBean(beanName, DataSource)\n }\n}\n</code></pre>\n<h3>Executing SQL Against a Runtime DataSource</h3>\n<p>Once you have obtained a reference to a <code>DataSource</code> using one of the methods outlined in the previous section, you\ncan construct a <a href=\"http://groovy.codehaus.org/api/groovy/sql/Sql.html\">groovy.sql.Sql</a> instance and use that to query/update\nthe datasource, e.g.</p>\n<pre><code class=\"language-groovy\">class MyService implements ApplicationContextAware {\n\n ApplicationContext applicationContext\n \n private executeSqlAgainstRuntimeDataSource(String beanName) {\n \n DataSource runtimeDataSource = applicationContext.getBean(beanName, DataSource)\n Sql sql = new Sql(runtimeDataSource)\n \n try {\n // use the Sql instance to execute a query, update data, etc.\n } finally {\n sql.close()\n }\n }\n}\n</code></pre>\n<p>Alternatively, the aforementioned <code>runtimeDataSourceService</code> also provides a couple of convenience methods which makes\nthe process slightly simpler, e.g.</p>\n<h3>Create Sql Instance</h3>\n<p>The <code>getSql</code> method of the service slightly simplifies the process of creating the <code>Sql</code> instance for a runtime datasource.</p>\n<pre><code class=\"language-groovy\">class MyService {\n\n RuntimeDataSourceService runtimeDataSourceService\n \n private executeSqlAgainstRuntimeDataSource(String beanName) {\n \n Sql sql = runtimeDataSourceService.getSql(beanName)\n \n try {\n // use the Sql instance to execute a query, update data, etc.\n } finally {\n sql.close()\n }\n }\n}\n```\n\n### Execute Query\n\nThe `doWithSql` method of the service simplifies the process of executing SQL statements against a datasource, e.g.\n\n````groovy\nclass MyService {\n\n RuntimeDataSourceService runtimeDataSourceService\n \n private executeSqlAgainstRuntimeDataSource(String beanName) {\n \n Integer rowCount = runtimeDataSourceService.doWithSql(beanName) { Sql sql ->\n def queryResult = sql.firstRow('select count(*) from my_table')\t \n queryResult[0]\n }\n }\n}\n</code></pre>\n<p>Notice that the caller is not responsible for closing the <code>Sql</code> instance that is passed to the closure. The value returned\nby the closure is also the return value of <code>doWithSql</code>.</p>\n<h2>Credits</h2>\n<p>The core of this plugin is based on <a href=\"http://stackoverflow.com/a/20634968/2648\">this stackoverflow answer</a> posted by\n<a href=\"https://github.com/timyates\">Tim Yates</a>.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "dropwizard-metrics", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Monitoring And Metrics Plugin For Grails 3", |
| "labels": [ |
| "metrics", |
| "dropwizard" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/grails-dropwizard-metrics/issues", |
| "latestVersion": "2.0.0.RC1", |
| "updated": "2020-03-18T16:05:41.578Z", |
| "systemIds": [ |
| "org.grails.plugins:dropwizard-metrics" |
| ], |
| "vcsUrl": "https://github.com/grails-plugins/grails-dropwizard-metrics" |
| }, |
| "documentationUrl": "https://grails-plugins.github.io/grails-dropwizard-metrics/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails Dropwizard Metrics</h1>\n<p>Documentation is available <a href=\"http://grails-plugins.github.io/grails-dropwizard-metrics/\">here</a>.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "dropwizard-metrics-graphite", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Adds Dropwizard metrics reporting to Graphite For Grails 3", |
| "labels": [ |
| "metrics", |
| "dropwizard", |
| "graphite" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/grails-dropwizard-metrics-graphite/issues", |
| "latestVersion": "2.0.0.RC1", |
| "updated": "2020-03-18T16:18:55.912Z", |
| "systemIds": [ |
| "org.grails.plugins:dropwizard-metrics-graphite" |
| ], |
| "vcsUrl": "https://github.com/grails-plugins/grails-dropwizard-metrics-graphite" |
| }, |
| "documentationUrl": "https://grails-plugins.github.io/grails-dropwizard-metrics-graphite/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails Dropwizard Metrics</h1>\n<p>Documentation is available <a href=\"http://grails-plugins.github.io/grails-dropwizard-metrics/\">here</a>.</p>\n<h1>Grails Dropwizard Metrics - Graphite</h1>\n<p>Documentation is available <a href=\"http://grails-plugins.github.io/grails-dropwizard-metrics-graphite/\">here</a>.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "dynamic-logs-with-rabbit", |
| "repo": "plugins", |
| "owner": "dbpatel219", |
| "desc": "Change Application Log Levels via Rabbit MQ messages at Runtime.", |
| "labels": [ |
| "logging" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/dbpatel219/dynamic-logs-with-rabbit/issues", |
| "latestVersion": "1.0.2", |
| "updated": "2019-10-02T12:05:42.973Z", |
| "systemIds": [ |
| "org.grails.plugins:dynamic-logs-with-rabbit" |
| ], |
| "vcsUrl": "https://github.com/dbpatel219/dynamic-logs-with-rabbit" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>dynamic-logs-with-rabbit</h1>\n<p>Change Application Log Levels via Rabbit MQ messages at Runtime.</p>\n<ul>\n<li>Great for large scale systems where you'd like to dynamically change your log levels on multiple application instances without requiring code changes.</li>\n</ul>\n<h2>Installation</h2>\n<p>Upon install, this will create a new Rabbit Exchange for you called <code>logLevelExchange</code> of type fanout</p>\n<h2>Usage</h2>\n<p><strong>Via Controller</strong></p>\n<ol>\n<li>\n<p>Make sure you have a mapping in UrlMappings to <code>logLevel/$action</code> and any security permissions</p>\n</li>\n<li>\n<p>A controller <code>LogLevelController</code> and view are provided to change the log levels from. Simply go to <em>http[s]://yourapp.com/logLevel</em></p>\n</li>\n<li>\n<p>Simply fill in the form and submit. App Name is the application you would like to change the log level for. <code>LogLevelConsumer</code> matches Grails <strong>application.properties "app.name"</strong> against the one that is passed in from the form.</p>\n</li>\n</ol>\n<p><strong>NOTE:</strong> Highly recommend you lock down <code>logLevel</code> endpoint via Spring Security.</p>\n<p><strong>Via Service</strong></p>\n<ol>\n<li>Inject logLevelService into your services or controllers :</li>\n<li>Create a <code>DynamicLogLevelMsg</code></li>\n</ol>\n<ul>\n<li><code>appName</code> is the Application name you want to target. Uses Grails <strong>application.properties "app.name"</strong></li>\n<li><code>loggerName</code> is the package or class you would like to change the log level for</li>\n<li><code>logLevel</code> is log level as a String you would like to change to: <em>['ALL','DEBUG','ERROR','FATAL','INFO','OFF','TRACE','WARN']</em></li>\n</ul>\n<p><strong>Example</strong></p>\n<pre><code>class Foo {\n def logLevelService\n\n def changeAllServiceLogLevelsToInfo() {\n logLevelService.send new DynamicLogLevelMsg("myApp", "grails.app.services", "INFO")\n }\n}\n</code></pre>\n<h3>Contributors</h3>\n<p>Thanks to <a href=\"https://github.com/burtbeckwith\">Burt Beckwith</a> for his contributions & feedback.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "elasticsearch", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Elasticsearch is a search server based on Lucene. It provides a distributed, multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents. Elasticsearch is developed in Java and is released as open source under the terms of the Apache License. This is the Grails 3 plugin to support Elasticsearch", |
| "labels": [ |
| "search", |
| "elasticsearch" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/elasticsearch-grails-plugin/issues", |
| "latestVersion": "3.0.1", |
| "updated": "2023-06-21T10:07:13.000Z", |
| "systemIds": [ |
| "org.grails.plugins:elasticsearch" |
| ], |
| "vcsUrl": "https://github.com/grails/elasticsearch-grails-plugin" |
| }, |
| "documentationUrl": "https://grails.github.io/elasticsearch-grails-plugin/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/grails/plugins/elasticsearch/maven-metadata.xml", |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "embedded-mongodb", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Executes an embedded mongo database for integration or functional testing", |
| "labels": [ |
| "testing", |
| "database", |
| "mongodb" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/grails-embedded-mongodb/issues", |
| "latestVersion": "2.0.1", |
| "updated": "2022-10-17T08:53:50.000Z", |
| "systemIds": [ |
| "org.grails.plugins:embedded-mongodb" |
| ], |
| "vcsUrl": "https://github.com/grails/grails-embedded-mongodb" |
| }, |
| "documentationUrl": "https://grails.github.io/grails-embedded-mongodb/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/grails/plugins/embedded-mongodb/maven-metadata.xml", |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "embedded-mysql", |
| "repo": "plugins", |
| "owner": "purpleraven", |
| "desc": "Plugin allows to use embedded MySQL in application.", |
| "labels": [ |
| "testing", |
| "database", |
| "mysql" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/purpleraven/embedded-mysql-grails-plugin/issues", |
| "latestVersion": "1.1", |
| "updated": "2019-05-15T09:24:00.089Z", |
| "systemIds": [ |
| "org.grails.plugins:embedded-mysql" |
| ], |
| "vcsUrl": "https://github.com/purpleraven/embedded-mysql-grails-plugin" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>embedded-mysql-grails-plugin</h1>\n<p><a href=\"https://bintray.com/purpleraven/plugins/embedded-mysql/1.1/link\"><img src=\"https://api.bintray.com/packages/purpleraven/plugins/embedded-mysql/images/download.svg?version=1.1\" alt=\"Download\" /></a></p>\n<p>Plugin replaces default embedded H2 datasource in awesome <a href=\"http://grails.org\">Grails</a> framework\nto MySQL. Plugin uses already existing solution <a href=\"https://github.com/wix/wix-embedded-mysql\">wix-embedded-mysql</a>.</p>\n<p>The plugin based on <a href=\"https://github.com/Relaximus/embedded-postgres-grails-plugin\">embedded-postgres-grails-plugin</a></p>\n<p>This plugin is not for production use, the main idea to have\nyour development and u-test environment similar to the standalone production MySQl (of course, if you use this DB in the project).</p>\n<h2>Getting Started</h2>\n<p>To get started with the minimum of configuration start from the following:\nAdd to your <em><strong>build.gradle</strong></em></p>\n<pre><code class=\"language-groovy\">repositories {\n ...\n maven { url "http://dl.bintray.com/purpleraven/plugins" }\n ...\n}\n\nwar {\n rootSpec.exclude("**/wix-embedded-mysql*.jar")\n}\n\ncompile 'org.grails.plugins:embedded-mysql:1.1'\n</code></pre>\n<p>In your <em><strong>application.yml</strong></em> change the dataSource settings to the next one:</p>\n<pre><code class=\"language-yaml\">dataSource:\n embeddedMysql: true\n</code></pre>\n<h3>Prerequisites</h3>\n<p>Plugin configured to work with Grails <strong>3.0.0</strong> or higher, but theoretically can be used even for\nolder version of it. But this was not checked properly, so contributing is welcome.</p>\n<h3>Configuration</h3>\n<p>Plugin uses next parameters in DataSource section:</p>\n<p>|Parameter name|Description|Default value|\n|--------------|-----------|-------------|\n| <em>embeddedMysql</em> | Enabling of the plugin, main switcher. | false |\n| <em>embeddedPort</em> | You can define the particular port, which will be used by MySQL instance | random free port |\n| <em>url</em> | You can specify the url with any additional parameters, which MySQL understands | jdbc:mysql://localhost:<embeddedPort>/embedded_db |\n| <em>username</em> || embedded_db |\n| <em>password</em> || embedded_db |\n| <em>schema</em> || embedded_db |</p>\n<p>All other parameters common for the Grails Datasource configuration section are being used by grails dataSource plugin.\nFor example, you can set</p>\n<pre><code class=\"language-yaml\">dataSource:\n pooled: true\n embeddedMysql: true\n</code></pre>\n<p>In this case embedded MySQL will be created with connection pool in front of it.</p>\n<h2>License</h2>\n<p><a href=\"https://opensource.org/licenses/apache2.0.php\">Apache License, Version 2.0</a></p>\n<h2>Acknowledgments</h2>\n<ul>\n<li>Great respect to the <a href=\"https://github.com/wix/wix-embedded-mysql\">wix-embedded-mysql</a> for Embedded MySQL implementation.</li>\n</ul>\n<h2>Known problems</h2>\n<p><code>apt install libaio1</code>\n'Stream closed': <code>apt install libncurses5</code></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "embedded-postgres", |
| "repo": "plugins", |
| "owner": "relaximus", |
| "desc": "Plugin allows to use embedded postgres in application.", |
| "labels": [ |
| "testing", |
| "database", |
| "postgres" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/Relaximus/embedded-postgres-grails-plugin/issues", |
| "latestVersion": "1.1.2", |
| "updated": "2019-01-17T15:53:30.576Z", |
| "systemIds": [ |
| "org.grails.plugins:embedded-postgres", |
| "embedded.postgres:embedded-postgres", |
| "embedded.postgres:embedded-postgres-grails-plugin" |
| ], |
| "vcsUrl": "https://github.com/Relaximus/embedded-postgres-grails-plugin" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>embedded-postgres-grails-plugin</h1>\n<p><a href=\"https://travis-ci.org/Relaximus/embedded-postgres-grails-plugin\"><img src=\"https://travis-ci.org/Relaximus/embedded-postgres-grails-plugin.svg?branch=master\" alt=\"Build Status\" /></a>\n<a href=\"https://bintray.com/relaximus/plugins/embedded-postgres/1.0/link\"><img src=\"https://api.bintray.com/packages/relaximus/plugins/embedded-postgres/images/download.svg?version=1.0\" alt=\"Download\" /></a></p>\n<p>Plugin replaces default embedded H2 datasource in awesome <a href=\"http://grails.org\">Grails</a> framework\nto Postgres. Plugin uses already existing solution <a href=\"https://github.com/opentable/otj-pg-embedded\">otj-pg-embedded</a>.</p>\n<p>This plugin is not for production use, the main idea to have\nyour development and u-test environment similar to the standalone production Postgres (of course, if you use this DB in the project).</p>\n<h2>Getting Started</h2>\n<p>To get started with the minimum of configuration start from the following:\nAdd to your <em><strong>build.gradle</strong></em></p>\n<pre><code class=\"language-groovy\">repositories {\n maven {\n url "https://dl.bintray.com/grails/plugins" \n }\n}\n</code></pre>\n<pre><code class=\"language-groovy\">compile 'org.grails.plugins:embedded-postgres:1.1.2'\n</code></pre>\n<p>In your <em><strong>application.yml</strong></em> change the dataSource settings to the next one:</p>\n<pre><code class=\"language-yaml\">dataSource:\n embeddedPostgres: true\n</code></pre>\n<h3>Prerequisites</h3>\n<p>Plugin configured to work with Grails <strong>3.0.0</strong> or higher, but theoretically can be used even for\nolder version of it. But this was not checked properly, so contributing is welcome.</p>\n<h3>Configuration</h3>\n<p>Plugin uses next parameters in DataSource section:</p>\n<p>|Parameter name|Description|Default value|\n|--------------|-----------|-------------|\n| <em>embeddedPostgres</em> | Enabling of the plugin, main switcher. | false |\n| <em>embeddedPort</em> | You can define the particular port, which will be used by Postgres instance | random free port |\n| <em>url</em> | You can specify the url with any additional parameters, which Postgres understands | jdbc:postgresql://localhost:<embeddedPort>/postgres |\n| <em>username</em> || postgres |\n| <em>password</em> || postgres |</p>\n<p>All other parameters common for the Grails Datasource configuration section are being used by grails dataSource plugin.\nFor example, you can set</p>\n<pre><code class=\"language-yaml\">dataSource:\n pooled: true\n embeddedPostgres: true\n</code></pre>\n<p>In this case embedded Postgres will be created with connection pool in front of it.</p>\n<h2>License</h2>\n<p><a href=\"https://opensource.org/licenses/apache2.0.php\">Apache License, Version 2.0</a></p>\n<h2>Acknowledgments</h2>\n<ul>\n<li>Great respect to the <a href=\"https://github.com/opentable/otj-pg-embedded\">otj-pg-embedded</a> for Embedded Postgres implementation.</li>\n</ul>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "ember-asset-pipeline", |
| "repo": "asset-pipeline", |
| "owner": "bertramlabs", |
| "desc": "Compiles .hbs or .handlebars files for the asset-pipeline into the Ember TEMPLATES cache", |
| "labels": [ |
| "asset-pipeline", |
| "ember" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/bertramdev/asset-pipeline/issues", |
| "latestVersion": "5.0.9", |
| "updated": "2025-04-13T23:20:08.000Z", |
| "systemIds": [ |
| "com.bertramlabs.plugins:ember-asset-pipeline" |
| ], |
| "vcsUrl": "https://github.com/bertramdev/asset-pipeline" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/com/bertramlabs/plugins/ember-asset-pipeline/maven-metadata.xml", |
| "readme": "<h1>Ember Asset-Pipeline</h1>\n<p><a href=\"https://travis-ci.org/bertramdev/ember-asset-pipeline\"><img src=\"https://travis-ci.org/bertramdev/ember-asset-pipeline.svg\" alt=\"Build Status\" /></a></p>\n<p><strong>MOVED</strong>: This project has moved to a sub project of the main asset-pipeline repository <a href=\"http://github.com/bertramdev/asset-pipeline\">http://github.com/bertramdev/asset-pipeline</a></p>\n<h2>Overview</h2>\n<p>The JVM <code>ember-asset-pipeline</code> is a plugin that provides handlebars template precompiler support for Ember.js to asset-pipeline.</p>\n<p>Current Ember Version: 1.7.0</p>\n<p>For more information on how to use asset-pipeline, visit <a href=\"http://www.github.com/bertramdev/asset-pipeline\">here</a>.</p>\n<h2>Usage</h2>\n<p>Simply create files in your standard <code>assets/javascripts</code> folder with extension <code>.handlebars</code> or <code>.hbs</code>.\nBy default the templateRoot for your template names is specified as 'templates'. This means that any handlebars file within the root assets/javascripts folder will utilize its file name (without the extension) as its template name. Or a file in <code>templates/show.handlebars</code> would be named <code>templates/show</code>. If templates is set as the templateRoot than it would be named <code>show</code></p>\n<p>It is also possible to change the template path seperator for templatenames to be used by handlebars:</p>\n<p>Gradle Example:</p>\n<pre><code class=\"language-groovy\">assets {\n\tconfig = [\n\thandlebars: [\n\t\ttemplateRoot: 'templates',\n\t\ttemplatePathSeperator: '/'\n\t]\n\t]\n}\n</code></pre>\n<p>Grails Example:</p>\n<pre><code class=\"language-groovy\">grails {\n\tassets {\n\t\thandlebars {\n\t\t\ttemplateRoot = 'templates'\n\t\t\ttemplatePathSeperator = "/"\n\t\t}\n\t}\n}\n</code></pre>\n<p>To use the handlebars runtime simply add handlebars js to your application.js or your gsp file</p>\n<pre><code class=\"language-javascript\">//=require handlebars\n</code></pre>\n<h2>Using in the Browser</h2>\n<p>Template functions are stored in the <code>Handlebars.templates</code> object using the template name. If the template name is\n<code>person/show</code>, then the template function can be accessed from <code>Handlebars.templates['person/show']</code>. See the Template Names section for how template names are calculated.</p>\n<p>See the <a href=\"http://handlebarsjs.com/\">Handlebars.js website</a> for more information on using Handlebars template functions.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "events", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Grails Events - EventBus abstraction for Grails", |
| "labels": [ |
| "async", |
| "events" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/grails-async/issues", |
| "latestVersion": "5.0.2", |
| "updated": "2024-01-09T11:43:24.000Z", |
| "systemIds": [ |
| "org.grails.plugins:events" |
| ], |
| "vcsUrl": "https://github.com/grails/grails-async" |
| }, |
| "documentationUrl": "https://async.grails.org/latest/guide/index.html#events", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/grails/plugins/events/maven-metadata.xml", |
| "readme": "" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "exa-datatables", |
| "repo": "plugins", |
| "owner": "exanpe", |
| "desc": "Provides easy integration with DataTables.net (Table plug-in for jQuery)", |
| "labels": [ |
| "datatables.net" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/exanpe/exa-grails-plugins/issues", |
| "latestVersion": "2.0.1", |
| "updated": "2016-12-14T22:46:58.114Z", |
| "systemIds": [ |
| "fr.exanpe.grails:exa-datatables" |
| ], |
| "vcsUrl": "https://github.com/exanpe/exa-grails-plugins" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>exa-grails-plugins</h1>\n<h2><a href=\"https://github.com/exanpe/exa-grails-plugins/tree/master/exa-datatables\">EXA-DATATABLES</a></h2>\n<p>This plugin is pre-configured to ease integration with DataTables (Table plug-in for jQuery).\nMost of the important features are enabled by default like:</p>\n<ul>\n<li>Instant search,</li>\n<li>Pagination,</li>\n<li>Column ordering,</li>\n<li>...</li>\n</ul>\n<p><a href=\"https://github.com/exanpe/exa-grails-plugins/tree/master/exa-datatables/README.md\">Link to documentation and description</a></p>\n<p><a href=\"http://grails-exanpe-grails-exanpe.193b.starter-ca-central-1.openshiftapps.com/exaDatatablesDemo/index\">Link to the live Demo</a></p>\n<h2><a href=\"https://github.com/exanpe/exa-grails-plugins/tree/master/exa-security\">EXA-SECURITY</a></h2>\n<p>This plugin provides features to enhance Grails 2.4.x security, as well as few other useful stuff.</p>\n<ul>\n<li>HTTP response <strong>headers</strong></li>\n<li>Secured <strong>XML</strong> parser</li>\n<li><strong>Link</strong> handling CSRF token</li>\n<li>Enhanced <strong>scaffolding</strong></li>\n<li>Advanced <strong>cookie</strong> configuration</li>\n<li><strong>Redirect</strong> engine</li>\n</ul>\n<p><a href=\"https://github.com/exanpe/exa-grails-plugins/tree/master/exa-security/README.md\">Link to documentation and description</a></p>\n<p><a href=\"http://grails-exanpe-grails-exanpe.193b.starter-ca-central-1.openshiftapps.com/exaSecurityDemo/index\">Link to the live Demo</a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "excel-export", |
| "repo": "plugins", |
| "owner": "touk", |
| "desc": "This plugin helps you export data in Excel (xlsx) format, using Apache POI.", |
| "labels": [ |
| "excel", |
| "export" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/TouK/excel-export/issues", |
| "latestVersion": "2.1", |
| "updated": "2017-05-30T21:24:04.936Z", |
| "systemIds": [ |
| "org.grails.plugins:excel-export", |
| "pl.touk:excel-export" |
| ], |
| "vcsUrl": "https://github.com/TouK/excel-export" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<p>This is the excel-export Grails plugin using <a href=\"https://poi.apache.org/\">Apache POI</a></p>\n<p><a href=\"https://travis-ci.org/TouK/excel-export\"><img src=\"https://travis-ci.org/TouK/excel-export.svg?branch=master\" alt=\"Build Status\" /></a> <a href=\"https://bintray.com/grails-excel-export/plugins/excel-export/_latestVersion\"><img src=\"https://api.bintray.com/packages/grails-excel-export/plugins/excel-export/images/download.svg\" alt=\"Download\" /></a></p>\n<h1>What does it do?</h1>\n<p>This plugin allows for easy exporting of object lists to an Office Open XML workbook (Microsoft Excel 2007+ xlsx) file, while still allowing you to handle the export file on a cell-by-cell basis.</p>\n<p>An alternative to this plugin is James Kleeh's <a href=\"https://github.com/jameskleeh/groovy-excel-builder\">groovy-excel-builder</a> which provides a fantastic Groovy DSL with varying degress of fine-grained control.</p>\n<h1>When should I use it?</h1>\n<p>There are two scenarios for which this plugin was created:</p>\n<ol>\n<li>\n<p>When you want to export data from your controllers for download and want to maintain full control of how you handle this data.</p>\n</li>\n<li>\n<p>When your customer says: 'I want 100 reports in this new project' and nobody has any clue what those reports look like, you can use this plugin as a DSL, i.e. tell your client 'Hey, I've got good news. We have a nice DSL for you, so that you can write all those reports yourself. And it's free!' (or charge them anyway).</p>\n</li>\n</ol>\n<p>In either case, you can export to either a file on disk or to the HTTP response output stream (download as xlsx).</p>\n<p>This plugin has been used like this in commercial projects.</p>\n<h1>How do I use it?</h1>\n<p>Say, in your controller you have a list of objects, like so:</p>\n<pre><code class=\"language-groovy\">List<Product> products = productFactory.createProducts()\n</code></pre>\n<p>To export selected properties of those products to a file on disk, see the following example, where <code>withProperties</code> is a list of properties that are going to be exported to xlsx, in the given order:</p>\n<pre><code class=\"language-groovy\">def withProperties = ['name', 'description', 'validTill', 'productNumber', 'price.value']\nnew XlsxExporter('/tmp/myReportFile.xlsx').\n add(products, withProperties).\n save()\n</code></pre>\n<p>Notice that you can use nested properties (e.g. <code>price.value</code>) of your objects.</p>\n<p>To add a header row to the spreadshet and make the file downloadable from a controller, you do this:</p>\n<pre><code class=\"language-groovy\">def headers = ['Name', 'Description', 'Valid Till', 'Product Number', 'Price']\ndef withProperties = ['name', 'description', 'validTill', 'productNumber', 'price.value']\n\nnew WebXlsxExporter().with {\n setResponseHeaders(response)\n fillHeader(headers)\n add(products, withProperties)\n save(response.outputStream)\n}\n</code></pre>\n<p><code>WebXlsxExporter</code> is the same thing as <code>XlsxExporter</code>, just with the ability to handle HTTP response headers.</p>\n<p>You can also manipulate the file on a cell-by-cell basis:</p>\n<pre><code class=\"language-groovy\">new WebXlsxExporter().with {\n setResponseHeaders(response)\n fillRow(["aaa", "bbb", 13, new Date()], 1)\n fillRow(["ccc", "ddd", 87, new Date()], 2)\n putCellValue(3, 3, "Now I'm here")\n save(response.outputStream)\n}\n</code></pre>\n<p>You can also mix approaches (cell-by-cell, and object list):</p>\n<pre><code class=\"language-groovy\">def withProperties = ['name', 'description', 'validTill', 'productNumber', 'price.value']\n\nnew WebXlsxExporter().with {\n setResponseHeaders(response)\n fillRow(["aaa", "bbb", 13, new Date()], 1)\n fillRow(["ccc", "ddd", 87, new Date()], 2)\n putCellValue(3, 3, "Now I'm here")\n add(products, withProperties, 4) //NOTICE: we are adding objects starting from line 4\n save(response.outputStream)\n}\n</code></pre>\n<h1>What about multiple sheets?</h1>\n<p>If you'd like to work with multiple sheets, just call <code>sheet(sheetName)</code> on your exporter. It returns an instance\nof <code>AdditionalSheet</code> that shares the same row/cell manipulation API as the exporter itself:</p>\n<pre><code class=\"language-groovy\"> List<Product> products = productFactory.createProducts()\n def withProperties = ['name', 'description', 'validTill', 'productNumber', 'price.value']\n\n new WebXlsxExporter().with {\n setResponseHeaders(response) print methods of controller\n sheet('second sheet').with {\n fillHeader(withProperties)\n add( products, withProperties )\n }\n save(response.outputStream)\n }\n</code></pre>\n<p>You can also mix using additional sheets with a default sheet:</p>\n<pre><code class=\"language-groovy\"> List<Product> products = productFactory.createProducts()\n def withProperties = ['name', 'description', 'validTill', 'productNumber', 'price.value']\n\n new WebXlsxExporter().with {\n setResponseHeaders(response)\n fillHeader(withProperties)\n add( products, withProperties )\n sheet('second sheet').with {\n fillHeader(withProperties)\n add( products, withProperties )\n }\n save(response.outputStream)\n }\n</code></pre>\n<p>And if you'd like to change the name of default sheet, just set it before first call:</p>\n<pre><code class=\"language-groovy\"> WebXlsxExporter webXlsxExporter = new WebXlsxExporter()\n webXlsxExporter.setWorksheetName("products")\n webXlsxExporter.with {\n ...\n }\n</code></pre>\n<h1>How to export my own types?</h1>\n<p>This plugin handles basic property types pretty well (String, Date, Boolean, Timestamp, NullObject, Long, Integer, BigDecimal, BigInteger, Byte, Double, Float, Short). It also handles nested properties, and if everything fails, tries to call <code>toString()</code>. But sooner or later, you'll want to export a property of a different type the way you like it.\nWhat you need to write, is a Getter. Or, better, a <code>PropertyGetter</code>. It's super easy, here is example of one that takes Currency and turns it into a String:</p>\n<pre><code class=\"language-groovy\">class CurrencyGetter extends PropertyGetter<Currency, String> { // From Currency, to String\n CurrencyGetter(String propertyName) {\n super(propertyName)\n }\n\n @Override\n protected String format(Currency value) {\n return value.displayName // you can do anything you like in here\n }\n}\n</code></pre>\n<p>The <code>format()</code> method allows you customize the value before the object is saved in an xlsx cell.</p>\n<p>And, of course, to use it, just add it into the <code>withProperties</code> list, like this:</p>\n<pre><code class=\"language-groovy\">def withProperties = ['name', new CurrencyGetter('price.currency'), 'price.value']\n\nnew WebXlsxExporter().with {\n setResponseHeaders(response)\n add(products, withProperties)\n save(response.outputStream)\n}\n</code></pre>\n<p>Of course we could have just used <code>currency.displayName</code> in <code>withProperties</code>, but you get the idea.</p>\n<p>There are two Getters ready for your convenience.</p>\n<p><code>LongToDatePropertyGetter</code> gets a long and saves it as a date in xlsx, while <code>MessageFromPropertyGetter</code> handles i18n. Speaking of which...</p>\n<h1>How to i18n?</h1>\n<p>To get i18n of headers in your controller, just use controller's existing message method:</p>\n<pre><code class=\"language-groovy\">def headers = [message(code: 'product.name.header'),\n message(code: 'product.description.header'),\n message(code: 'product.validTill.header'),\n message(code: 'product.productNumber.header'),\n message(code: 'price.value.header')]\n</code></pre>\n<p>You can do more though. To i18n values, use <code>MessageFromPropertyGetter</code>:</p>\n<pre><code class=\"language-groovy\">MessageSource messageSource //injected in the controller automatically by Grails, just declare it\n\ndef export() {\n List<Product> products = productFactory.createProducts()\n\n def headers = ['name', 'type', 'value']\n def withProperties = ['name', new MessageFromPropertyGetter(messageSource, 'type'), 'price.value']\n\n new WebXlsxExporter().with {\n setResponseHeaders(response)\n fillHeader(headers)\n add(products, withProperties)\n save(response.outputStream)\n }\n}\n</code></pre>\n<p>This will use grails i18n, based on the value of some property (<code>type</code> in the example above) of your objects.</p>\n<h1>I want fancy diagrams, colours, and other stuff in my Excel!</h1>\n<p>Making xlsx files look really great with Apache POI is pretty fun but not very efficient. So we have found out that it's easier to create a template manually (in MS Excel or Open Office), load this template in your code, fill it up with data, and hand it back to the user.</p>\n<p>For this scenario, every constructor takes a path to a template file (just a normal xlsx file).</p>\n<p>After loading the template, fill the data, and save to the output stream</p>\n<pre><code class=\"language-groovy\">new WebXlsxExporter('/tmp/myTemplate.xlsx').with {\n setResponseHeaders(response)\n add(products, withProperties)\n save(response.outputStream)\n}\n</code></pre>\n<p>If you just want to save the file to disk instead of a stream, use a different constructor:</p>\n<pre><code class=\"language-groovy\">new XlsxExporter('/tmp/myTemplate.xlsx', '/tmp/myReport.xlsx')\n</code></pre>\n<p>If you just open an existing file, and save it, like this:</p>\n<pre><code class=\"language-groovy\">new XlsxExporter('/tmp/myReport.xlsx').with {\n add(products, withProperties)\n save()\n}\n</code></pre>\n<p>you are going to overwrite it.</p>\n<h1>But I don't want no template (for whatever reason)</h1>\n<p>Ok, so if you don't want to use a temple, but want to format a cell style directly in the code, you can still do that.</p>\n<p>You can get the cell style like this:</p>\n<pre><code class=\"language-groovy\">xlsxReporter.getCellAt(0, 0).getCellStyle().getDataFormatString()\n</code></pre>\n<p>Of course there is a corresponding <code>setCellStyle()</code> method, but this is a part of the <a href=\"https://poi.apache.org/apidocs/org/apache/poi/xssf/usermodel/XSSFCell.html\">Apache POI API</a>, and is outside the scope of this plugin.</p>\n<h1>How to get it installed?</h1>\n<p>Like any other Grails plugin, just add to the <code>dependencies</code> block of your app's build.gradle file:</p>\n<pre><code class=\"language-groovy\">dependencies {\n compile "org.grails.plugins:excel-export:2.1"\n}\n</code></pre>\n<p>Excluding xerces may or may not be needed, depending on your setup. If you get</p>\n<pre><code>Error executing script RunApp: org/apache/xerces/dom/DeferredElementImpl (Use --stacktrace to see the full trace)\n</code></pre>\n<p>you NEED to exclude xercesImpl to use ApachePOI. Don't worry, it won't break anything.</p>\n<p>If you have more strange problems with xml and you are using Java 7, exclude xml-apis as well.</p>\n<p>To understand why you need to exclude anything, please take a look here: http://stackoverflow.com/questions/11677572/dealing-with-xerces-hell-in-java-maven</p>\n<p>If you want a working example, clone this project: https://github.com/TouK/excel-export-samples</p>\n<h1>Alternative plugins and solutions</h1>\n<p>As noted above, James Kleeh's <a href=\"https://github.com/jameskleeh/groovy-excel-builder\">groovy-excel-builder</a> provides a wonderful Groovy DSL with varying degress of fine-grained control:</p>\n<pre><code class=\"language-groovy\">XSSFWorkbook workbook = ExcelBuilder.build {\n sheet {\n row {\n cell("Test 1")\n cell("Test 2")\n }\n }\n}\n\nworkbook.write(outputStream)\n</code></pre>\n<p>There are others, but most were too simplistic or too 'automagical' for my needs. Apache POI is pretty simple to use itself (and has fantastic API) but we needed something even simpler for several projects. Also a bit DSL-like so our customers could write reports on their own. After preparing a few getters for our custom objects, this is what we ended up with:</p>\n<pre><code class=\"language-groovy\">def withProperties = ["id", "name", "inProduction", "workLogCount", "createdAt", "createdAtDate", asDate("firstEventTime"),\n firstUnacknowledgedTime(), firstUnacknowledged(), firstTakeOwnershipTime(), firstTakeOwnership(),\n firstReleaseOwnershipTime(), firstReleaseOwnership(), firstClearedTime(), firstCleared(),\n firstDeferedTime(), firstDefered(), firstUndeferedTime(), firstUndefered(), childConnectedTime(), childConnected(),\n parentConnectedTime(), parentConnected(), parentDisconnectedTime(), parentDisconnected(),\n childDisconnectedTime(), childDisconnected(), childOrphanedTime(), childOrphaned(), createdTime(), created(),\n updatedTime(), updated(), workLogAddedTime(), workLogAdded()]\n\ndef reporter = new XlsxReporter("/tmp/sampleTemplate.xlsx")\n\nreporter.with {\n fillHeader withProperties\n add events, withProperties\n save "/tmp/sampleReport1.xlsx"\n}\n</code></pre>\n<p>All the methods in <code>withProperties</code> are static imports generating a new instance of a corresponding <code>PropertyGetter</code> implementation. To our surprise, this worked really well with some clients, who started writing their own reports instead of paying us for doing the boring work.</p>\n<p>Hope it helps.</p>\n<h1>License</h1>\n<p>Copyright 2012-2014 TouK</p>\n<p>Licensed under the Apache License, Version 2.0 (the "License");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at</p>\n<pre><code>http://www.apache.org/licenses/LICENSE-2.0\n</code></pre>\n<p>Unless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an "AS IS" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.</p>\n<h1>Changes</h1>\n<p>2.0.1 upgrade poi to 3.12 (thanks to Sergio Maria Matone) and Grails to 3+ (thanks to mansiarora)</p>\n<p>0.2.1 calling toString() on unhandled property types, instead of throwing IllegalArgumentException</p>\n<p>0.2.0 working with multiple sheets and renaming default sheet</p>\n<p>0.1.10 not exporting release plugin dependency anymore (Issue #14)</p>\n<p>0.1.9 upgrade to release plugin 3.0.1 (run 'grails refresh-dependencies' if you have problems in grails 2.3.2)</p>\n<p>0.1.8: fix for grails 2.3.1 (groovy changing how Mixins see private methods)</p>\n<p>0.1.7: fixed Property Type Validation not accepting subclasses</p>\n<p>0.1.6: handling maps in object properties</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "excel-import", |
| "repo": "plugins", |
| "owner": "gpc", |
| "desc": "Grails Excel Import Plugin", |
| "labels": [ |
| "excel", |
| "import" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/gpc/grails-excel-import/issues", |
| "latestVersion": "3.0.2", |
| "updated": "2018-08-15T13:39:59.412Z", |
| "systemIds": [ |
| "org.grails.plugins:excel-import" |
| ], |
| "vcsUrl": "https://github.com/gpc/grails-excel-import" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/gpc/grails-excel-import\"><img src=\"https://travis-ci.org/gpc/grails-excel-import.svg?branch=master\" alt=\"Build Status\" /></a></p>\n<h1>Excel-Import plugin</h1>\n<p>Excel-Import plugin uses Apache POI [http://poi.apache.org/] library (v 3.17) to parse Excel files.</p>\n<p>It's useful for either bootstrapping data, or when you want to allow your users to enter some data using Excel spreadsheets.</p>\n<h2>Usage:</h2>\n<p>The core of the plugin is a utilities class, which contains a number of useful methods for dealing with Excel.</p>\n<h3><code>org.grails.plugins.excelimport.ExcelImportUtils</code></h3>\n<p>There is also an <code>AbstractExcelImporter</code>, which is a class you can extend - it opens and stores the workbook reference.</p>\n<h3>Reading Information Contained in Rows:</h3>\n<p>The plugin is designed to parse data out of spreadsheets into format that can then be used to create objects. For example, if you have data like this:</p>\n<p>|B |C |D |\n|:-----------|--------------|--------:|\n|Author |Book |# Sold |\n|Shakespeare |King Lear | 1000 |\n|Shakespeare |Hamlet | 10000 |\n|Tolstoy |War and Peace | 200 |</p>\n<p>You can pass in parameters map that contains the name of the sheet, row where to start, and how the different columns map to properties of the object you are planning to populate (i.e. values in column B map to title property).</p>\n<pre><code>static Map CONFIG_BOOK_COLUMN_MAP = [\n sheet:'Sheet1', \n\t\t\t startRow: 2,\n columnMap: [\n 'B':'title',\n 'C':'author',\n 'D':'numSold',\n ]\n ]\n\nList bookList = ExcelImportUtils.convertColumnMapConfigManyRows(workbook, CONFIG_BOOK_COLUMN_MAP)\n</code></pre>\n<p>And you'll get back a list of maps:</p>\n<pre><code>assert bookParamsList, [\n [AuthorName:'Shakespeare', BookName:'King Lear', NumSold:1000],\n [AuthorName:'Shakespeare', BookName:'Hamlet', NumSold:10000],\n [AuthorName:'Tolstoy', BookName:'War and Peace', NumSold:200],\n]\n</code></pre>\n<p>You can then pass the maps to constructors to create a bunch of objects, i.e.\n<code>bookParamsList</code>:</p>\n<pre><code> bookParamsList.each { Map bookParamMap ->\n new Book (bookParamMap).save()\n }\n</code></pre>\n<p>Reading Information contained in Individual Cells:</p>\n<pre><code>static Map CONFIG_BOOK_CELL_MAP = [ \n sheet:'Sheet2', \n cellMap: [ 'D3':'title',\n 'D4':'author',\n 'D6':'numSold',\n ]\n] \n\nMap bookParams = ExcelImportUtils.convertFromCellMapToMapWithValues(workbook, CONFIG_BOOK_CELL_MAP )\n</code></pre>\n<p>There is also ability to handle type errors, empty cells, evaluate formulas, etc. There is also ability to pass in configuration information, i.e. to specify what to do if a cell is empty (i.e. to provide a default value), to make sure a cell is of expected type, etc.</p>\n<p>Also, you can do similar things for individual cells, when that is the format, i.e. C10 maps to key "Author", D12 to "AuthorYearBorn', etc. Between targeting individual cells and columns / rows, that satisfied quite many requirements.</p>\n<h3>Sample Application:</h3>\n<p>For a sample of usage, please see a sample application you can download from the Plugins GIT (in the 1.1.x branch) (code below is from <code>Bootstrap.groovy</code>)</p>\n<pre><code>import org.grails.plugins.excelimport.ExcelImportUtils\nimport org.grails.plugins.excelimport.*\nimport sample.*\n\nclass BookExcelImporter extends AbstractExcelImporter {\n\n static Map CONFIG_BOOK_CELL_MAP = [ \n sheet:'Sheet2', \n cellMap: [ 'D3':'title',\n 'D4':'author',\n 'D6':'numSold',\n\t ]\n ] \n \n static Map CONFIG_BOOK_COLUMN_MAP = [\n sheet:'Sheet1', \n\t\t\t startRow: 2,\n columnMap: [\n 'B':'title',\n 'C':'author',\n 'D':'numSold',\n ]\n ]\n\n public BookExcelImporter(fileName) {\n super(fileName)\n }\n\n List<Map> getBooks() {\n List bookList = ExcelImportUtils.convertColumnMapConfigManyRows(workbook, CONFIG_BOOK_COLUMN_MAP)\n }\n\n\n Map getOneMoreBookParams() {\n Map bookParams = ExcelImportUtils.convertFromCellMapToMapWithValues(workbook, CONFIG_BOOK_CELL_MAP )\n }\n\n}\n</code></pre>\n<pre><code>class BootStrap {\n\n def init = { servletContext ->\n\n //String fileName = "c:\\\\dev\\\\HEAD\\\\plugins\\\\excel-import\\\\test\\\\projects\\\\sample\\\\test-data\\\\books.xls"\n String fileName = /.\\test-data\\books.xls/\n BookExcelImporter importer = new BookExcelImporter(fileName);\n \n def booksMapList = importer.getBooks();\n println booksMapList\n\n \t booksMapList.each { Map bookParams ->\n \t def newBook = new Book(bookParams)\n\t if (!newBook.save()) {\n\t println "Book not saved, errors = ${newBook.errors}"\n\t }\n\t }\n\n new Book(importer.getOneMoreBookParams()).save()\n\n\t}\n}\n</code></pre>\n<p><em>Note</em>: Apache POI 3.6 Supports Excel 2007 Files, but I haven't tested those.</p>\n<p>Also, while formulas evaluation works for most cases, in some complicated cases it does not (i..e when you have a lookup of a looked up value using some unsupported formulas).</p>\n<p>The plugin is licensed under Apache V2.</p>\n<h3>Release History:</h3>\n<ul>\n<li>August 15th, 2018 - Release 3.0.2\n<ul>\n<li>No code changes, but fixed that 3.0.0 was build as a fat jar (boot repackaged)</li>\n</ul>\n</li>\n<li>August 13th, 2018 - Release 3.0.0, and 3.1.0.BUILD-SNAPSHOT</li>\n<li>June 19th, 2018 - Grails 3.3.x RC7 release</li>\n<li>June 21st, 2010 - Initial Release</li>\n</ul>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "export", |
| "repo": "plugins", |
| "owner": "gpc", |
| "desc": "Grails export plugin", |
| "labels": [ |
| "export", |
| "csv", |
| "excel", |
| "ods", |
| "pdf", |
| "xml" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/gpc/export/issues", |
| "latestVersion": "2.0.0", |
| "updated": "2016-10-03T14:39:59.214Z", |
| "systemIds": [ |
| "org.grails.plugins:export" |
| ], |
| "vcsUrl": "https://github.com/gpc/export" |
| }, |
| "documentationUrl": "https://gpc.github.io/export/", |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/gpc/export\"><img src=\"https://travis-ci.org/gpc/export.svg\" alt=\"Build Status\" /></a></p>\n<h1>Grails Export Plugin</h1>\n<p>Primary fork of the original export plugin. Sources forked from SVN and maintained here.</p>\n<p>The user guide can be found here: <a href=\"http://gpc.github.com/export/\">Documentation</a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "external-config", |
| "repo": "plugins", |
| "owner": "sbglasius", |
| "desc": "Load configs with grails.config.locations like in Grails 2.x", |
| "labels": [ |
| "config" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/sbglasius/external-config/issues", |
| "latestVersion": "4.0.0", |
| "updated": "2023-12-29T10:18:00.000Z", |
| "systemIds": [ |
| "dk.glasius:external-config" |
| ], |
| "vcsUrl": "https://github.com/sbglasius/external-config" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/dk/glasius/external-config/maven-metadata.xml", |
| "readme": "<p><a href=\"https://github.com/sbglasius/external-config\">See the README</a> on GitHub</p>" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "facebook-sdk", |
| "repo": "plugins", |
| "owner": "agorapulse", |
| "desc": "Grails Facebook SDK plugin", |
| "labels": [ |
| "facebook" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/agorapulse/grails-facebook-sdk/issues", |
| "latestVersion": "4.1.2", |
| "updated": "2021-01-18T11:56:45.552Z", |
| "systemIds": [ |
| "org.grails.plugins:facebook-sdk" |
| ], |
| "vcsUrl": "https://github.com/agorapulse/grails-facebook-sdk" |
| }, |
| "documentationUrl": "https://agorapulse.github.io/grails-facebook-sdk/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Facebook SDK Grails Plugin</h1>\n<p><a href=\"https://travis-ci.org/agorapulse/grails-facebook-sdk\"><img src=\"https://travis-ci.org/agorapulse/grails-facebook-sdk.svg\" alt=\"Build Status\" /></a>\n<a href=\"https://bintray.com/agorapulse/plugins/facebook-sdk/_latestVersion\"><img src=\"https://api.bintray.com/packages/agorapulse/plugins/facebook-sdk/images/download.svg\" alt=\"Download\" /></a></p>\n<h1>Introduction</h1>\n<p>The <a href=\"http://developers.facebook.com/\">Facebook Platform</a> is a set of APIs that make your application more social. Read more about <a href=\"http://developers.facebook.com/docs/guides/web\">integrating Facebook with your web site</a> on the Facebook developer site.</p>\n<p>This project contains the open source <strong>Grails Facebook SDK Plugin</strong> that allows you to integrate the <a href=\"http://developers.facebook.com/\">Facebook Platform</a> on a website/app powered by <a href=\"http://grails.org\">Grails</a>.</p>\n<p>This plugin is a port of the official <a href=\"http://github.com/facebook/facebook-php-sdk\">Facebook PHP SDK</a> to <a href=\"http://grails.org\">Grails 3.0</a>.</p>\n<p>It supports the latest <em>OAuth2.0 authentication</em> (required since October 1st 2011).</p>\n<p><strong>Grails Facebook SDK Plugin</strong> provides the following Grails artefacts:</p>\n<ul>\n<li><strong>FacebookContext</strong> - A Spring bean to get current Facebook context in controllers, when running <a href=\"http://developers.facebook.com/docs/guides/canvas/\">apps on Facebook.com</a> or <a href=\"http://developers.facebook.com/docs/guides/web\">websites with the Facebook Platform</a>.</li>\n<li><strong>FacebookGraphClient</strong> - A client to call <a href=\"http://developers.facebook.com/docs/reference/api/\">Facebook Graph API</a>, which is a wrapper around the rock solid <a href=\"http://restfb.com/\">RestFB java library</a> version 1.32.0 (released October 13, 2016).</li>\n<li><strong>FacebookJSTagLib</strong> - A collection of tags to easily integrate <a href=\"http://developers.facebook.com/docs/reference/javascript/\">Facebook JS SDK</a> in your GSPs.</li>\n</ul>\n<p><strong>WARNING</strong>: Facebook API v3.0 is now used by default.</p>\n<h1>Installation</h1>\n<p>Declare the plugin dependency in the <em>build.gradle</em> file, as shown here:</p>\n<pre><code class=\"language-groovy\">dependencies {\n ...\n compile "org.grails.plugins:facebook-sdk:4:0.0"\n ...\n}\n</code></pre>\n<h1>Config</h1>\n<p>Create a Facebook app on <a href=\"https://developers.facebook.com/apps\">Facebook Developers</a>, in order to get your own app ID and app secret.</p>\n<p>Add your Facebook app parameters to your <em>grails-app/conf/application.yml</em>:</p>\n<pre><code class=\"language-yml\">grails:\n plugin:\n facebooksdk:\n app:\n id: {APP_ID}\n permissions: {APP_PERMISSIONS} // Ex. ['email','user_photos']\n secret: {APP_SECRET}\n</code></pre>\n<p>By default, latest Graph API v3.3 will be used.\nYou can override default settings with <code>apiVersion</code> setting:</p>\n<pre><code class=\"language-yml\">grails:\n plugin:\n facebooksdk:\n apiVersion: v2.3\n</code></pre>\n<p>Since FacebookContext should be instantiated at each request, you must use <code>prototype</code> scope for your Controllers (since Grails 2.3, <code>singleton</code> is the default scope).</p>\n<pre><code class=\"language-yml\">grails:\n controllers:\n defaultScope: prototype\n</code></pre>\n<p>Default jQuery selector is <code>$</code>, if you require another one, you can define it globally in your <em>grails-app/conf/application.groovy</em>:</p>\n<pre><code class=\"language-yml\">grails:\n plugin:\n facebooksdk:\n customSelector: jQuery\n</code></pre>\n<h1>Bugs</h1>\n<p>To report any bug, please use the project <a href=\"http://github.com/agorapulse/grails-facebook-sdk/issues\">Issues</a> section on GitHub.</p>\n<h1>Feedback</h1>\n<p>The <strong>Grails Facebook SDK</strong> is not an official Facebook SDK such as <a href=\"http://developers.facebook.com/docs/reference/javascript/\">Javascript</a>, <a href=\"http://github.com/facebook/facebook-php-sdk\">PHP</a>, <a href=\"http://github.com/facebook/facebook-ios-sdk/\">iOS</a> and <a href=\"http://github.com/facebook/facebook-android-sdk\">Android SDKs</a>.</p>\n<p>It is developed by <a href=\"http://www.agorapulse.com\">AgoraPulse</a>.</p>\n<p>The <strong>Grails Facebook SDK</strong> is licensed under the <a href=\"http://www.apache.org/licenses/LICENSE-2.0.html\">Apache Licence, Version 2.0</a>.</p>\n<h1>Breaking Changes</h1>\n<h2>4.0.1</h2>\n<ul>\n<li>Default return type of <code>fetchObject</code> from <code>FacebookExtensions</code> is back to <code>JsonObject</code> instead of <code>Map</code></li>\n</ul>\n<h2>4.0.0</h2>\n<ul>\n<li>restfb upgrade - see https://github.com/restfb/restfb/blob/master/migrations.md\n<ul>\n<li>removed <code>FacebookRestClient</code> and <code>DefaultFacebookRestClient</code></li>\n<li>avoid using raw <code>JsonObject</code> as the class has completely changed i.g. <code>JsonObject</code> from restfb 2.x implements own method <code>asBoolean()</code> which fails if the value is not <code>boolean</code> so you need to do regular <code>foo != null</code> check for testing the presense of the returned <code>JsonObject</code> value</li>\n</ul>\n</li>\n<li><code>FacebookGraphClient</code> is now deprecated, use <code>FacebookGraphClientService</code> to create instances of <code>FacebookClient</code> with similar capabilities</li>\n<li><code>FacebookExtensions</code> the most useful methods from <code>FacebookGraphClient</code>are now injected using extensions methods to <code>FacebookClient</code> interface directly</li>\n</ul>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "fields", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Grails fields plugin", |
| "labels": [ |
| "forms" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/gpc/fields/issues", |
| "latestVersion": "5.0.3", |
| "updated": "2024-04-08T19:47:32.000Z", |
| "systemIds": [ |
| "io.github.gpc:fields" |
| ], |
| "vcsUrl": "https://github.com/gpc/fields" |
| }, |
| "documentationUrl": "https://gpc.github.io/fields/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/io/github/gpc/fields/maven-metadata.xml", |
| "readme": "Find the latest documentation here: https://gpc.github.io/fields" |
| }, |
| { |
| "displayName": "file-viewer", |
| "comment": "There does not seem to exist a published release version compatible with Grails >= 3 as of this writing.", |
| "bintrayPackage": { |
| "name": "File-Viewer-Grails-Plugin", |
| "repo": "plugins", |
| "owner": "tothenew", |
| "desc": "Grails plugin which allows you to view files stored on the file system.", |
| "labels": [ |
| "file-viewer" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/intelligrape/File-Viewer-Grails-Plugin/issues", |
| "latestVersion": null, |
| "updated": "2016-03-31T13:31:54.746Z", |
| "systemIds": [ |
| "org.grails.plugins:file-viewer" |
| ], |
| "vcsUrl": "https://github.com/tothenew/File-Viewer-Grails-Plugin" |
| }, |
| "documentationUrl": "https://github.com/tothenew/File-Viewer-Grails-Plugin/wiki", |
| "mavenMetadataUrl": null, |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "filterpane", |
| "repo": "grails-plugins", |
| "owner": "ctoestreich", |
| "desc": "", |
| "labels": [ |
| "filter", |
| "filterpane" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/Grails-Plugin-Consortium/grails-filterpane/issues", |
| "latestVersion": "3.0.9", |
| "updated": "2018-05-04T00:32:57.027Z", |
| "systemIds": [ |
| "org.grails.plugins:filterpane", |
| "org.grails.plugins:grails-filterpane" |
| ], |
| "vcsUrl": "https://github.com/Grails-Plugin-Consortium/grails-filterpane" |
| }, |
| "documentationUrl": "https://Grails-Plugin-Consortium.github.io/grails-filterpane/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Filterpane Plugin</h1>\n<p>####Build Status####</p>\n<p><a href=\"https://travis-ci.org/Grails-Plugin-Consortium/grails-filterpane\"><img src=\"https://travis-ci.org/Grails-Plugin-Consortium/grails-filterpane.png?branch=master\" alt=\"Build Status\" /></a></p>\n<p>####Documentation Found Here####</p>\n<p><a href=\"http://grails-plugin-consortium.github.io/grails-filterpane/\">Documentation</a></p>\n<p>###Demo Project###</p>\n<p><a href=\"https://github.com/Grails-Plugin-Consortium/grails-filterpane-demo\">Demo</a></p>\n" |
| }, |
| { |
| "displayName": "fixtures", |
| "bintrayPackage": { |
| "name": "fixtures3", |
| "repo": "plugins", |
| "owner": "purpleraven", |
| "desc": "Load complex domain data via a simple DSL", |
| "labels": [ |
| |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/purple-raven/fixtures/issues", |
| "latestVersion": "3.0.5", |
| "updated": "2019-02-20T07:38:03.728Z", |
| "systemIds": [ |
| "org.grails.plugins:fixtures3" |
| ], |
| "vcsUrl": "https://github.com/purple-raven/fixtures" |
| }, |
| "documentationUrl": "https://purple-raven.github.io/fixtures/", |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/gpc/grails-fixtures\"><img src=\"https://travis-ci.org/gpc/grails-fixtures.svg?branch=master\" alt=\"Build Status\" /></a></p>\n<p><a href=\"https://bintray.com/purpleraven/plugins/fixtures3/3.0.5/link\"><img src=\"https://api.bintray.com/packages/purpleraven/plugins/fixtures3/images/download.svg?version=3.0.5\" alt=\"Download\" /></a></p>\n<h1>Grails Fixtures Plugin for Grails 3</h1>\n<p>Documentation can be found @ <a href=\"http://web.archive.org/web/20150527051907/http://gpc.github.io/grails-fixtures\" title=\"Grails Fixtures Plugin @ GitHub\">http://web.archive.org/web/20150527051907/http://gpc.github.io/grails-fixtures</a></p>\n<pre><code>repositories {\n maven { url "http://dl.bintray.com/purpleraven/plugins" }\n}\n\ndependencies {\n compile 'org.grails.plugins:fixtures3:3.0.5'\n}\n</code></pre>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "force-ssl", |
| "repo": "grails3-plugins", |
| "owner": "bertramlabs", |
| "desc": "Creates a simple annotation to mark controller/actions as SSL restricted and performs the appropriate redirect.", |
| "labels": [ |
| "ssl", |
| "https" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/bertramdev/grails-force-ssl/issues", |
| "latestVersion": "7.0.0", |
| "updated": "2024-12-30T16:52:03.000Z", |
| "systemIds": [ |
| "com.bertramlabs.plugins:grails-force-ssl", |
| "com.bertramlabs.plugins:force-ssl" |
| ], |
| "vcsUrl": "https://github.com/bertramdev/grails-force-ssl" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/com/bertramlabs/plugins/grails-force-ssl/maven-metadata.xml", |
| "readme": "<h1>Grails Force SSL</h1>\n<p>The Grails Force SSL Plugin provides an annotation for controllers to force ssl url endpoints. For example, you may want to restrict a shopping cart page or login page to SSL.</p>\n<h2>Configuration</h2>\n<p>By default, the SSL plugin is enabled for all environments, with the exception of <code>Development</code>. This can be overridden by adjusting your <code>Config.groovy</code></p>\n<pre><code class=\"language-groovy\">grails.plugin.forceSSL.enabled = false\n</code></pre>\n<h3>Grails 3</h3>\n<pre><code class=\"language-yaml\">grails:\n plugin:\n forceSSL:\n enabled: true\n</code></pre>\n<p>The enabled flag can also be defined as a closure which will get passed the request attribute. This allows for evaluation on a per requeset level as to wether or not SSL should be enforced. Can be rather useful for disabling forced SSL for certain URL endpoints (for example server endpoints not behind a load balancer).</p>\n<pre><code class=\"language-groovy\">grails.plugin.forceSSL.enabled = { request ->\n if(request.serverName == 'app1.bertramlabs.com') {\n return false\n }\n return true\n}\n</code></pre>\n<p>It is also possible to override the https port for the redirect if you want to via:</p>\n<pre><code class=\"language-groovy\">grails.plugin.forceSSL.sslPort = 6443 //optional\n</code></pre>\n<h2>Usage</h2>\n<p>Simply import the SSL annotation and apply at the controller level or at the annotation level.</p>\n<pre><code class=\"language-groovy\">import com.bertramlabs.plugins.SSLRequired\n\n@SSLRequired //Will encrypt entire controller\nclass SessionController {\n @SSLRequired //Or here for action level\n def signin() {\n //Signin Code Here\n }\n}\n</code></pre>\n<p>Another option is to use a configuration mapping to identify which controllers you wish to be restricted to SSL:</p>\n<pre><code class=\"language-groovy\"> grails {\n plugin {\n forceSSL {\n enabled = true\n dashboard {\n index = true\n }\n home = true\n }\n } \n }\n</code></pre>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "geb", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Geb Functional Testing for Grails framework", |
| "labels": [ |
| "testing", |
| "geb" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/geb/issues", |
| "latestVersion": "4.1.1", |
| "updated": "2024-12-22T00:53:39.000Z", |
| "systemIds": [ |
| "org.grails.plugins:geb" |
| ], |
| "vcsUrl": "https://github.com/grails/geb" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/grails/plugins/geb/maven-metadata.xml", |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "gorm-graphql", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "GORM GraphQL - Generates a GraphQL schema based on entities in GORM", |
| "labels": [ |
| "graphql" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/gorm-graphql/issues", |
| "latestVersion": "2.0.0", |
| "updated": "2020-04-06T19:35:05.149Z", |
| "systemIds": [ |
| "org.grails.plugins:gorm-graphql-plugin", |
| "org.grails.plugins:gorm-graphql" |
| ], |
| "vcsUrl": "https://github.com/grails/gorm-graphql" |
| }, |
| "documentationUrl": "https://grails.github.io/gorm-graphql/latest/guide/index.html", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Gorm GraphQL</h1>\n<h2>An automatic GraphQL schema generator for GORM</h2>\n<p><a href=\"https://travis-ci.org/grails/gorm-graphql\"><img src=\"https://travis-ci.org/grails/gorm-graphql.svg?branch=master\" alt=\"Build Status\" /></a></p>\n<p>Current documentation https://grails.github.io/gorm-graphql/latest/guide/index.html</p>\n<h3>Dependencies</h3>\n<ul>\n<li><a href=\"https://github.com/graphql-java/graphql-java\">Graphql Java</a></li>\n</ul>\n" |
| }, |
| { |
| "deprecated": "This entry in the registry is a duplicate of the entry with the name 'gorm-graphql'. This entry should probably be removed from the registry to avoid confusion.", |
| "bintrayPackage": { |
| "name": "gorm-graphql-plugin", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "GORM GraphQL - Generates a GraphQL schema based on entities in GORM", |
| "labels": [ |
| "graphql" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/gorm-graphql/issues", |
| "latestVersion": "2.0.0", |
| "updated": "2020-04-06T19:35:05.149Z", |
| "systemIds": [ |
| "org.grails.plugins:gorm-graphql-plugin" |
| ], |
| "vcsUrl": "https://github.com/grails/gorm-graphql" |
| }, |
| "documentationUrl": "https://grails.github.io/gorm-graphql/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Gorm GraphQL</h1>\n<h2>An automatic GraphQL schema generator for GORM</h2>\n<p><a href=\"https://travis-ci.org/grails/gorm-graphql\"><img src=\"https://travis-ci.org/grails/gorm-graphql.svg?branch=master\" alt=\"Build Status\" /></a></p>\n<p>Current documentation https://grails.github.io/gorm-graphql/latest/guide/index.html</p>\n<h3>Dependencies</h3>\n<ul>\n<li><a href=\"https://github.com/graphql-java/graphql-java\">Graphql Java</a></li>\n</ul>\n" |
| }, |
| { |
| "displayName": "logical-delete", |
| "bintrayPackage": { |
| "name": "grails-logical-delete", |
| "repo": "plugins", |
| "owner": "grails-plugins", |
| "desc": "Adds support for logical (soft) deletion in Grails applications.", |
| "labels": [ |
| "database", |
| "logical-delete", |
| "soft-delete" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/grails-logical-delete/issues", |
| "latestVersion": "2.0.0.M2", |
| "updated": "2017-12-23T16:32:31.613Z", |
| "systemIds": [ |
| "org.grails.plugins:grails-logical-delete" |
| ], |
| "vcsUrl": "https://github.com/grails-plugins/grails-logical-delete" |
| }, |
| "documentationUrl": "https://grails-plugins.github.io/grails-logical-delete/latest", |
| "mavenMetadataUrl": null, |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "gorm-tools", |
| "repo": "grails-plugins", |
| "owner": "9ci", |
| "desc": "repository pattern, data services, fast data binding and json/rest/map based query plugin for grails gorm", |
| "labels": [ |
| "database" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/yakworks/gorm-tools/issues", |
| "latestVersion": "7.3.96", |
| "updated": "2025-12-22T17:48:33.000Z", |
| "systemIds": [ |
| "org.yakworks:gorm-tools", |
| "org.grails.plugins:gorm-tools" |
| ], |
| "vcsUrl": "https://github.com/yakworks/gorm-tools" |
| }, |
| "documentationUrl": "https://yakworks.github.io/gorm-tools/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/yakworks/gorm-tools/maven-metadata.xml", |
| "readme": "<p><a href=\"https://circleci.com/gh/yakworks/gorm-tools\"><img src=\"https://img.shields.io/circleci/project/github/yakworks/gorm-tools/master.svg?longCache=true&style=for-the-badge&logo=circleci\" alt=\"CircleCI\" /></a>\n<a href=\"http://9ci.com\"><img src=\"https://img.shields.io/badge/BUILT%20BY-9ci%20Inc-blue.svg?longCache=true&style=for-the-badge\" alt=\"9ci\" /></a>\n<img src=\"https://forthebadge.com/images/badges/built-with-love.svg\" height=\"28\">\n<img src=\"https://forthebadge.com/images/badges/gluten-free.svg\" height=\"28\">\n<img src=\"https://forthebadge.com/images/badges/made-with-groovy.svg\" height=\"28\"></p>\n<pre style=\"line-height: normal; background-color:#2b2929; color:#76ff00; font-family: monospace; white-space: pre;\">\n\n ________ _.-````'-,_\n / _____/ ___________ _____ ,-'` `'-.,_\n / \\ ___ / _ \\_ __ \\/ \\ /) (\\ 9ci's '``-.\n \\ \\_\\ ( <_> ) | \\/ Y Y \\ ( ( .,-') ) Yak Works ```\n \\______ /\\____/|__| |__|_| / \\ ' (_/ !!\n \\/ \\/ | /) ' !!!\n ___________ .__ ^\\ ~' ' ! !!!!\n \\__ ___/___ ____ | | ______ ! _/! , ! ! ! ! ! !!!\n | | / _ \\ / _ \\| | / ___/ \\Y, |!!! ! ! !! !! !!!!!!!\n | |( <_> | <_> ) |__\\___ \\ `!!! !!!! !! )!!!!!!!!!!!!!\n |____| \\____/ \\____/|____/____ > !! ! ! \\( \\( !!!|/! |/!\n \\/ /_( /_(/_( /_( /_( \n Version: 7.0.8-v.10\n \n</pre>\n<p><strong>6.1.x is for grails 3.3.x and gorm 6.1.x</strong></p>\n<p><strong>7.0.x is for grails 4.x and gorm 7.0.x</strong></p>\n<blockquote>\n<p><em>DOCS ARE OUT OF DATE AND BEING UPDATED FOR BREAKING CHANGES IN 6.1.12-v.X</em>\n<em>ALSO MERGING IN DOCS FOR THE REST-API AND AUDITSTAMP THAT WAS MERGED INTO HERE</em>\nMore breaking changes in 7.0.8-v6. is required on domain entity now or it needs to implement @GormRepoEntity</p>\n</blockquote>\n<p><a href=\"docs/release-notes.md\">RELEASE NOTES</a></p>\n<p>| Guide | API |\n|------|--------|\n|<a href=\"https://yakworks.github.io/gorm-tools/\">Released Docs</a> | <a href=\"https://yakworks.github.io/gorm-tools/api\">Released Api</a>\n|<a href=\"https://yakworks.github.io/gorm-tools/snapshot\">snapshot</a> | <a href=\"https://yakworks.github.io/gorm-tools/snapshot/api\">snapshot</a></p>\n<pre><code>compile "org.grails.plugins:gorm-tools:6.1.12-v.2"\n</code></pre>\n<p>Gorm-tools allows your Grails/Gorm project to start with a design of best practices that they can customize along the way.\nThis brings an opinionated starting point to a Grails/Gorm project but without being locked in.\nDevelopers are free to easily customize, replace and disable these patterns when their opinions differ.</p>\n<h2>Overview</h2>\n<p>This is a library of tools to help standardize and simplify the service and Restful controller layer business logic for\ndomains and is the basis for the <a href=\"https://yakworks.github.io/gorm-rest-api/\">Gorm Rest API plugin</a>{.new-tab}.</p>\n<p>Gorm-Tools is the next iteration on the <a href=\"https://grails.org/plugin/dao\">DAO plugin</a> and has been in use for about 10 years processing millions of transactions per day.</p>\n<p>There are 3 primary patterns this library enables as detailed below for Repositories,\nMango ( A mongo/graphql like query way to get gorm entity data with a Map) and\nBatch or Bulk inserting and updating with data binding</p>\n<h2>Domain Repository Services</h2>\n<p><small><a href=\"docs/repository/ref.md\">jump to reference</a></small></p>\n<p>A repository is a <a href=\"docs/usefulLinks.md#references\">Domain Driven Design</a> pattern. Used a a place logic to validate, bind, persist and query data that resides\neither in a database or NoSql (via GORM usually of course).\nThe design pattern here is a bit similiar to <a href=\"https://docs.spring.io/spring-data/data-commons/docs/current/reference/html/\">Spring's Repository pattern</a>\nand Grails GORM's new <a href=\"http://gorm.grails.org/6.1.x/hibernate/manual/#dataServices\">Data Services</a> pattern.</p>\n<h3>Goals</h3>\n<ul>\n<li><strong>Standardization</strong>: a clean common pattern across our apps for domain service layer logic that\nreduces boiler plate in both services as well as controllers.</li>\n<li><strong>Transactional Saves</strong>: every save() or persist() is wrapped in a transaction if one doesn't already exist.\nThis is critical when there are cascading saves and updates.</li>\n<li><strong>RuntimeException Rollback by default</strong>: saves or <code>persist()</code> always occur with failOnError:true so a RuntimeException is\nthrown for both DataAccessExceptions as well a validation exceptions.\nThis is critical for deeply nested domain logic dealing with saving multiple domains chains.</li>\n<li><strong>Events & Validation</strong>: the Repository allows a central place to do events such as beforeSave, beforeValidate, etc\nso as not to pollute the domain class. This pattern makes it easier to keeps the special logic in a transaction as well.\nAllows validation outside of constraints to persistence without needing to modify the domain source.</li>\n<li><strong>Events with Flushing</strong>: As mentioned in the Gorm docs, "Do not attempt to flush the session within an event\n(such as with obj.save(flush:true)). Since events are fired during flushing this will cause a StackOverflowError.".\nPutting the event business logic in the Repository keeps it all in a normal transaction and a flush is perfectly fine.</li>\n<li><strong>Easy Override/Replace Plugin's Domain Logic</strong>: Since the Repository is a service this also easily allows default logic in a provided\nplugin to be overriden in an application. For example, I may have a CustomerRepo in a plugin that deals with deault common\nlogic to validate address. I can then implement a CustomerRepo in an application and it will override the spring bean\njust as it does for a service.</li>\n</ul>\n<h2>Fast Data Binder & Batch Insert/Update</h2>\n<p>We process millions of transactions per day and needed more performant binding performance.</p>\n<h3>Goals</h3>\n<ul>\n<li><strong>FAST Data Binding Service</strong>: databinding from maps (and thus JSON) has to be fast.\nWe sacrfice a small amount of functionality for a big performance gain\nMaps and json are a first class citizen in the data service layer instead of the controller layer.\nEliminates boiler plate in getting data from the database to Gorm to JSON Map then back again.</li>\n<li><strong>Asynchronous batch processing PERFORMANCE</strong>: GORM insert and updates can be chunked and processed in parrallel\nusing GPARS or RxJava making it easy to processes millions of records from JSON, CSV or Excel</li>\n</ul>\n<h2>JSON Query and Filtering (Mango Query)</h2>\n<p>The primary motive here is to create an easy dynamic map based way to query any Gorm Datastore (SQL or NoSQL).\nUsing a simple map that can come from json, yaml, groovy config etc...\nA huge motivating factor being able is to be able to have a powerful and flexible way to query using json from a REST\nbased client without having to use <em>GraphQL</em> (the only other clean alternative)\nThe Repositories and RestApiController come with a <code>query(criteriaMap, closure)</code> method. It allows you to get a paginated\nlist of entities restricted by the properties in the <code>criteriaMap</code>.</p>\n<ul>\n<li>A lot of inspiration was drawn from <a href=\"https://restdb.io/docs/querying-with-the-api\">Restdb.io</a></li>\n<li>the query language is similar to <a href=\"https://docs.mongodb.com/manual/reference/operator/query/\">Mongo's</a></li>\n<li>and CouchDB's new <a href=\"http://docs.couchdb.org/en/latest/api/database/find.html#selector-syntax\">Mango selector-syntax</a> .</li>\n<li>Also inspired by <a href=\"https://github.com/2do2go/json-sql/\">json-sql</a></li>\n</ul>\n<blockquote>\n<p>:memo:\nWhilst selectors have many similarities with MongoDB query documents,\nthese arise more from a similarity of purpose and do not necessarily extend to commonality of function or result.</p>\n</blockquote>\n<p><strong>Example</strong>\nfor example, sending a JSON search param that looks like this</p>\n<pre><code class=\"language-js\">{\n "name": "Bill%",\n "type": "New",\n "age": {"$gt": 65}\n}\n</code></pre>\n<p>would get converted to the equivalent criteria</p>\n<pre><code class=\"language-javascript\">criteria.list {\n ilike "name", "Bill%"\n eq "type", "New"\n gt "age", 65\n}\n</code></pre>\n<h2>Developer Notes</h2>\n<h3>Running docs locally</h3>\n<p>Docs are built with https://yakworks.github.io/docmark/\nRun <code>./build.sh dockmark-serve</code> or <code>make dockmark-serve</code></p>\n<h3>Publishing Plugin Releases</h3>\n<p>See <a href=\"docs/developer.md\">Developer Docs</a> for info on our release process</p>\n<p><strong>Using latests SNAPSHOT</strong></p>\n<p>Configure 9ci repo in build.gradle</p>\n<pre><code class=\"language-groovy\">repositories {\n maven { url "http://repo.9ci.com/oss-snapshots" }\n }\n</code></pre>\n<p>See <a href=\"version.properties\">version.properties</a> for snapshot version</p>\n<pre><code class=\"language-groovy\">dependencies {\n compile('org.grails.plugins:gorm-tools:x.y.z-SNAPSHOT') { changing = true } \n}\n</code></pre>\n" |
| }, |
| { |
| "displayName": "advanced-config", |
| "bintrayPackage": { |
| "name": "grails-advanced-config", |
| "repo": "plugins", |
| "owner": "reid", |
| "desc": "Grails Advanced Config Plugin", |
| "labels": [ |
| "config" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/RealizeIdeas/grails-advanced-config/issues", |
| "latestVersion": "1.0", |
| "updated": "2018-02-23T07:24:40.766Z", |
| "systemIds": [ |
| "net.realizeideas:grails-advanced-config" |
| ], |
| "vcsUrl": "https://github.com/RealizeIdeas/grails-advanced-config" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grail Advanced Config Plugin</h1>\n<p>A small Gradle plugin built to help with Grails config files.</p>\n<p>It takes config files from different locations and composes it into <strong>application.yml</strong></p>\n<p><img src=\"https://github.com/RealizeIdeas/grails-advanced-config/blob/master/src/docs/img/config_structure.png\" alt=\"Config structure\" /></p>\n<h2>Setup</h2>\n<p>Basic setup in <strong>build.gradle</strong>:</p>\n<pre><code class=\"language-groovy\">buildscript {\n repositories {\n maven { url "https://dl.bintray.com/reid/plugins" }\n }\n dependencies {\n classpath 'net.realizeideas:grails-advanced-config:1.0'\n }\n}\napply plugin: "net.realizeideas.grails-advanced-config"\n</code></pre>\n<p>By default plugin takes all input config files from:</p>\n<ul>\n<li>grails-app/conf/configurations/common</li>\n<li>grails-app/conf/configurations/"${grails.env}"</li>\n</ul>\n<p>You can override this behavior and set required config files manually:</p>\n<pre><code class=\"language-groovy\">advancedConfig {\n configFiles = files(\n 'grails-app/conf/config1.yml',\n 'grails-app/conf/config2.yml',\n ) as List\n}\n</code></pre>\n<h2>Supported file format</h2>\n<p>For input files:</p>\n<ul>\n<li>yml</li>\n<li>groovy</li>\n<li>json</li>\n<li>xml</li>\n</ul>\n<p>Output file - <strong>application.yml</strong></p>\n" |
| }, |
| { |
| "displayName": "appinfo", |
| "bintrayPackage": { |
| "name": "grails-appinfo", |
| "repo": "plugins", |
| "owner": "ikalizpet", |
| "desc": "A Grails plugin to provide applicaiton system information for health-check and runtime inspection", |
| "labels": [ |
| "health-check" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/ikaliZpet/grails-appinfo/issues", |
| "latestVersion": "2.2", |
| "updated": "2019-06-25T15:29:24.171Z", |
| "systemIds": [ |
| "org.grails.plugins:grails-appinfo" |
| ], |
| "vcsUrl": "https://github.com/ikaliZpet/grails-appinfo" |
| }, |
| "documentationUrl": "https://binlecode.github.io/grails-appinfo/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>grails-appinfo</h1>\n<p>Grails plugin to check and monitor application status with a dashboard UI</p>\n<p><a href=\"https://travis-ci.org/binlecode/grails-appinfo\"><img src=\"https://travis-ci.org/binlecode/grails-appinfo.svg?branch=master\" alt=\"Build Status\" /></a></p>\n<h2>INTRODUCTION</h2>\n<p>Grails-appinfo Grails plugin is a set of convenient utilities for application\nsystem details, health-check, configuration and monitoring at runtime.</p>\n<p>This Grails plugin builds on top of spring boot actuator API with Grails specific\nenhancements on stock actuator endpoints.</p>\n<p>To consume actuator JSON endpoints, the testing Grails application also provides a monitoring\ndashboard inspired by <a href=\"https://github.com/dmahapatro/grails-actuator-ui\">grails-actuator-ui</a>.</p>\n<p>The dashboard UI is built on bootstrap with CSS framework from <a href=\"https://adminlte.io/\">AdminLTE</a>.</p>\n<p>This repository contains source code of Grails-appinfo plugin, and a testing host Grails application.</p>\n<h2>INSTALL</h2>\n<p>In host Grails application's build.gradle file:</p>\n<pre><code class=\"language-groovy\">plugins {\n compile ':grails-appinfo:$version'\n}\n</code></pre>\n<h2>PREREQUISITES</h2>\n<p>Hosting Grails application version 3.0+.</p>\n<h2>CONFIGURATION</h2>\n<p>In host Grails application grails-app/conf/application.yml</p>\n<pre><code class=\"language-yaml\"># Appinfo grails plugin settings\nappinfo:\n health:\n mongodb:\n # hide or show password in the mongodb connection url if it contains credential info\n # if set to false (default if not set), the password will be replaced as '<pswd>'\n showPassword: false # default to false\n urls: # list of webservice endpoints to check\n - url: 'http://localhost:8080'\n name: 'web root' # name of the endpoint\n method: 'GET' # http method, default to 'HEAD' if not given\n - url: 'http://localhost:8080/info'\n name: 'web_info'\n aws:\n s3:\n # either:\n bucket: 'bucket-name' # bucket name used in s3 health check\n # or: (for multiple buckets)\n #buckets:\n # - 'bucket-name'\n # - 'another-bucket-name'\n info:\n # add 'grails-system-info' to Actuator info endpoint, default (if not set) is not enabled\n system: true\n # add 'grails-logging-info' to Actuator info endpoint, default (if not set) is not enabled\n logging: true\n # add following keys to Actuator info endpoint, default (if not set) is not enabled\n # - 'jvm-version'\n # - 'groovy-version'\n # - 'grails-runtime-environment'\n # - 'grails-reload-enabled'\n # - 'grails-runtime-threads-info'\n runtime: true\n</code></pre>\n<h2>SAMPLE APPLICATION</h2>\n<p>The plugin provides RESTful json view by itself with endpoints as below:\n<code><root-context>/</code> followed by <code>autoconfig</code>, <code>configprops</code>, <code>dump</code>, <code>env</code>, <code>health</code>, <code>info</code>, <code>metrics</code>, <code>mappings</code>, <code>shutdown</code>, <code>trace</code>, <code>beans</code>.</p>\n<p>Most of them are decorators of Spring Boot Actuator native endpoints. But with enhanced information and connectivity support such as mongodb, s3, generic web url endpoint, etc.</p>\n<p>For example, <code>localhost:8080/health</code> endpoint returns:</p>\n<pre><code class=\"language-json\">{\n "status": "DOWN",\n "diskSpace": {\n "status": "UP",\n "total": 499963170816,\n "free": 281595985920,\n "threshold": 262144000\n },\n "urlHealthCheck_web_info": {\n "status": "UP",\n "url": "http://localhost:8080/info",\n "method": "HEAD",\n "timeout.threshold": "10000 ms"\n },\n "databaseHealthCheck": {\n "status": "UP",\n "database": "H2",\n "hello": 1\n },\n "urlHealthCheck_webroot": {\n "status": "UP",\n "url": "http://localhost:8080",\n "method": "GET",\n "timeout.threshold": "10000 ms"\n },\n "mongodbHealthCheck": {\n "status": "DOWN",\n "url": "mongodb://localhost/test_grails_appinfo",\n "db": "test_grails_appinfo",\n "error": "java.lang.Exception: MongoDB check timed out after 3000 ms"\n },\n "s3HealthCheck": {\n "status": "DOWN",\n "endpoint": "https://s3.amazonaws.com",\n "error": "java.lang.Exception: S3 check fail: Unable to load AWS credentials from any provider in the chain"\n }\n}\n</code></pre>\n<p>The sample application also includes a Bootstrap styled dashboard with url:\n<code><root-context>/appinfoDashboard</code> which renders information with ajax call to above endpoints.</p>\n<p>The web UI components are straightforward:</p>\n<ul>\n<li>gsp in folder <code>views/appinfoDashboard</code></li>\n<li>layout template <code>views/layouts/appinfo.gsp</code></li>\n<li>taglib <code>taglib/grails/plugin/appinfo/AvatarTaglib.groovy</code></li>\n</ul>\n<p>UI static resource files are:</p>\n<ul>\n<li><code>grails-app/assets/images/appinfo</code></li>\n<li><code>grails-app/assets/javascripts/appinfo</code></li>\n<li><code>grails-app/assets/stylesheets/appinfo</code></li>\n</ul>\n<p>Here are some screenshots of v1.3 sample application UI:</p>\n<ul>\n<li>dashboard\n<img src=\"screenshots/appinfo-ui-dashboard.png?raw=true\" alt=\"Alt appinfo UI dashboard\" title=\"appinfo-ui dashboard\" /></li>\n<li>URL mappings\n<img src=\"screenshots/appinfo-ui-mappings.png?raw=true\" alt=\"Alt appinfo UI URL mappings\" title=\"appinfo-ui url mappings trace\" /></li>\n<li>http call trace\n<img src=\"screenshots/appinfo-ui-trace.png?raw=true\" alt=\"Alt appinfo UI http trace\" title=\"appinfo-ui http trace\" /></li>\n<li>runtime beans\n<img src=\"screenshots/appinfo-ui-beans.png?raw=true\" alt=\"Alt appinfo UI beans\" title=\"appinfo-ui beans\" /></li>\n</ul>\n<h2>CHANGELOG</h2>\n<h4>1.3.1</h4>\n<ul>\n<li>fix: sample app boot-up fails when aws-s3 setting is commented out in app yaml</li>\n<li>document enhancement with sample app UI dashboard config and screenshot</li>\n</ul>\n<h4>1.3</h4>\n<ul>\n<li>support both AWS SDK Grails plugin version 1.x and 2.x.</li>\n</ul>\n<h4>1.2</h4>\n<ul>\n<li>fix mongodb check timeout error during healthcheck</li>\n<li>enhancements of loggingInfo exposure in Actuator endpoint</li>\n<li>restore runtime logger management web UI because of SpringBoot Actuator v1.4's lack of loggers RESTful endpoint</li>\n</ul>\n<h4>v1.1</h4>\n<ul>\n<li>add password shadowing option for mongodb connection url</li>\n</ul>\n<h4>v1.0</h4>\n<ul>\n<li>stable release for Grails 3.2.x, with Spring Boot 1.4 and GORM 6.0</li>\n</ul>\n<h4>v0.9</h4>\n<ul>\n<li>support both multi-dataSources and single dataSource in health check</li>\n<li>support mongodb in health check</li>\n</ul>\n<h2>CONTRIBUTORS</h2>\n<p>Bin Le (bin.le.code@gmail.com)</p>\n<h2>LICENSE</h2>\n<p>Apache License Version 2.0. (http://www.apache.org/licenses/)</p>\n" |
| }, |
| { |
| "displayName": "bootstrap-forms", |
| "bintrayPackage": { |
| "name": "grails-bootstrap-forms", |
| "repo": "plugins", |
| "owner": "jvilaplana", |
| "desc": "Easy form fields generation taglib.", |
| "labels": [ |
| "bootstrap" |
| ], |
| "licenses": [ |
| "MIT" |
| ], |
| "issueTrackerUrl": "https://github.com/jvilaplana/grails-bootstrap-forms/issues", |
| "latestVersion": "0.3.3", |
| "updated": "2020-08-19T09:16:59.593Z", |
| "systemIds": [ |
| "grails.bootstrap.forms:grails-bootstrap-forms" |
| ], |
| "vcsUrl": "https://github.com/jvilaplana/grails-bootstrap-forms" |
| }, |
| "documentationUrl": "https://jvilaplana.github.io/grails-bootstrap-forms/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails Bootstrap Forms</h1>\n<p>A Grails 3 plugin to automatically generate form fields using Bootstrap 4.</p>\n<h2>Overview</h2>\n<p>The grails-bootstrap-forms plugin offers an easy-to-use TagLib to render fields in views.</p>\n<h2>Basic usage</h2>\n<p>Add the Bintray repository to your <code>build.gradle</code> file:</p>\n<pre><code>buildscript {\n repositories {\n ...\n maven { url "http://dl.bintray.com/jvilaplana/plugins" }\n }\n}\n</code></pre>\n<p>Add the dependency to your project's <code>build.gradle</code> file:</p>\n<pre><code>dependencies {\n ...\n compile 'grails.bootstrap.forms:grails-bootstrap-forms:0.3.3'\n}\n</code></pre>\n<p>Add the stylesheet to your project's <code>application.css</code> file:</p>\n<pre><code>*= require bootstrap-forms\n</code></pre>\n<p>There is a tag to display a field for <code>show.gsp</code> views and another one to render form fields.</p>\n<p>To show a field you can use:</p>\n<p><code><bf:showField bean="${user}" property="username" /></code></p>\n<p>To render a form field you can use:</p>\n<p><code><bf:formField bean="${user}" property="username" /></code></p>\n<h3>Documentation</h3>\n<h4>showField attributes</h4>\n<p>| Attribute | Description |\n| --------- | ----------- |\n| <code>bean</code> | Instance |\n| <code>property</code> | Property of the <code>bean</code> to be rendered |\n| <code>width</code> | <a href=\"http://getbootstrap.com/docs/4.1/layout/grid/\">Column width</a>, defaults to <code>3</code> |\n| <code>type</code> | Type of the property to be rendered. One of <code>text</code>, <code>textarea</code>, <code>number</code>, <code>date</code>, <code>time</code>, <code>datetime</code> or <code>select</code>. If not specified, the type will be guessed.\n| <code>addon</code> | If specified, its value will be appended to the field. |\n| <code>cssClass</code> | A CSS class that will be added to the field |</p>\n<h4>formField attributes</h4>\n<p>| Attribute | Description |\n| --------- | ----------- |\n| <code>bean</code> | Instance |\n| <code>property</code> | Property of the <code>bean</code> to be rendered |\n| <code>width</code> | <a href=\"http://getbootstrap.com/docs/4.1/layout/grid/\">Column width</a>, defaults to <code>3</code> |\n| <code>type</code> | Type of the property to be rendered. One of <code>text</code>, <code>textarea</code>, <code>number</code>, <code>date</code>, <code>time</code>, <code>transient</code> or <code>select</code>. If not specified, the type will be guessed.\n| <code>addon</code> | If specified, its value will be appended to the field. |\n| <code>cssClass</code> | A CSS class that will be added to the field |\n| <code>required</code> | Set its value to <code>required</code> to set the field as required. |\n| <code>height</code> | Set the <a href=\"http://getbootstrap.com/docs/4.1/components/forms/#sizing\">sizing of the field</a> to <code>lg</code> or <code>sm</code>.\n| <code>rows</code> | Set the number of rows for fields with <code>type="textarea"</code>.\n| <code>name</code> | Set the <code>name</code> and <code>id</code> attributes of the field. Defaults to <code>property</code>. |</p>\n<p><a href=\"https://bintray.com/jvilaplana/plugins/grails-bootstrap-forms/_latestVersion\"><img src=\"https://api.bintray.com/packages/jvilaplana/plugins/grails-bootstrap-forms/images/download.svg\" alt=\"Download\" /></a></p>\n" |
| }, |
| { |
| "displayName": "executor", |
| "deprecated": "Source repository is archived. As per the readme: This plugin is not maintained - use grails-async. This entry in the registry should probably be removed.", |
| "bintrayPackage": { |
| "name": "grails-executor", |
| "repo": "plugins", |
| "owner": "uberall", |
| "desc": "Full plugin description", |
| "labels": [ |
| "async" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/uberall/grails-executor/issues", |
| "latestVersion": "0.4", |
| "updated": "2016-08-22T06:44:29.831Z", |
| "systemIds": [ |
| "org.grails.plugins:grails-executor" |
| ], |
| "vcsUrl": "https://github.com/uberall/grails-executor" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>grails-executor</h1>\n<p><em>DEPRECATION NOTE: this plugin is not maintained anymore, as grails 3.x already has a feature build-in which allows creating a thread that has a session bound. Check out the grails-async documentation for more information: https://async.grails.org/</em></p>\n<p>Concurrency / asynchronous / background process plugin for grails 3</p>\n<p>grails2 version can be found here: https://github.com/basejump/grails-executor</p>\n<h2>Summary</h2>\n<p>This grails plugin incorporates the java concurrency Executor Framework into a plugin so your grails app can take advantage of asynchronous (background thread / concurrent) processing. The main need for this as opposed to just using an <a href=\"http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html\">ExecutorService</a> from <a href=\"http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Executors.html\">Executors</a> is that we need to wrap the calls so there is a Hibernate or other Data provider session bound to the thread.\nThis uses the following pattern to wrap Runnable/Closures so they get a session for whatever Gorm you are using. Hibernate being the default but this is also tested with Mongo (no heavily) See the info on the <a href=\"http://grails.org/doc/latest/api/org/codehaus/groovy/grails/support/PersistenceContextInterceptor.html\">PersistenceContextInterceptor</a> grails bean for more info</p>\n<pre><code>// injected spring bean\nPersistenceContextInterceptor persistenceInterceptor\n\nprotected wrap(Closure wrapped) {\n\tpersistenceInterceptor.init()\n\ttry {\n\t\twrapped()\n\t} finally {\n\t\tpersistenceInterceptor.flush()\n\t\tpersistenceInterceptor.destroy()\n\t}\n}\n</code></pre>\n<p>Here are a couple of links to get give you some background information.</p>\n<p><a href=\"http://www.ibm.com/developerworks/java/library/j-jtp1126.html\">http://www.ibm.com/developerworks/java/library/j-jtp1126.html</a><br />\n<a href=\"http://www.vogella.de/articles/JavaConcurrency/article.html\">http://www.vogella.de/articles/JavaConcurrency/article.html</a></p>\n<p>and here are few good write up on groovy concurrency<br />\n<a href=\"http://groovy.codehaus.org/Concurrency+with+Groovy\">http://groovy.codehaus.org/Concurrency+with+Groovy</a><br />\nand a slide show<br />\n<a href=\"http://www.slideshare.net/paulk_asert/groovy-and-concurrency-paul-king\">http://www.slideshare.net/paulk_asert/groovy-and-concurrency-paul-king</a></p>\n<h2>Installation</h2>\n<p>Edit build.gradle, by adding the following:</p>\n<pre><code class=\"language-groovy\">repositories {\n ...\n maven { url "http://dl.bintray.com/uberall/plugins" }\n ...\n}\n\ndependencies {\n ...\n compile 'org.grails.plugins:grails-executor:0.2'\n ...\n}\n</code></pre>\n<h2>Setup</h2>\n<p>The plugin sets up a Grails service bean called executorService so you need do nothing really. It delegates to an implementation of an Java <a href=\"http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html\">ExecutorService</a> (not to be confused with a Grails Service) interface so read up on that for more info on what you can do with the executorService. It basically wraps another thread pool <a href=\"http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html\">ExecutorService</a>. By default it uses the java <a href=\"http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Executors.html\">Executors</a> utility class to setup the injected thread pool ExecutorService implementation. The default Grails executorService config looks like this</p>\n<pre><code> executorService(PersistenceContextExecutorWrapper) { bean ->\n bean.destroyMethod = 'destroy'\n persistenceInterceptor = ref("persistenceInterceptor")\n executor = Executors.newCachedThreadPool()\n }\n</code></pre>\n<p>You can override it and inject your own special thread pool executor using <a href=\"http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Executors.html\">Executors</a> by overriding the bean in conf/spring/resources.groovy or the doWithSpring closure in your plugin.</p>\n<pre><code> executorService(PersistenceContextExecutorWrapper) { bean ->\n bean.destroyMethod = 'destroy'\n persistenceInterceptor = ref("persistenceInterceptor")\n // this can be whatever from Executors (don't write your own and pre-optimize)\n executor = Executors.newCachedThreadPool(new YourSpecialThreadFactory()) \n }\n</code></pre>\n<h2>Usage</h2>\n<p>You can inject the executorService into any bean. It's a <a href=\"http://github.com/uberall/grails-executor/blob/master/src/groovy/grails/plugin/executor/PersistenceContextExecutorWrapper.groovy\">PersistenceContextExecutorWrapper</a> that delegates any calls to a concrete <a href=\"http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html\">ExecutorService</a> implementation.Remember that a <a href=\"http://groovy.codehaus.org/api/groovy/lang/Closure.html\">Closure</a> is a <a href=\"http://download.oracle.com/javase/6/docs/api/java/lang/Runnable.html\">Runnable</a> so you can pass it to any of the methods that accept a runnable. A great example exists <a href=\"http://groovy.codehaus.org/Concurrency+with+Groovy\">here on the groovy site</a></p>\n<p>The plugin adds shortcut methods to any service/controller/domain artifacts.</p>\n<ul>\n<li><strong>runAsync <em>closure</em></strong> - takes any closure and passes it through to the executorService.execute</li>\n<li><strong>callAsync <em>closure</em></strong> - takes any closure that returns a value and passes it through to the executorService.submit . You will get a <a href=\"http://download-llnw.oracle.com/javase/6/docs/api/java/util/concurrent/Future.html\">Future</a> back that you can work with. This will not bind a session in java 1.5 and only works on 1.6 or later</li>\n</ul>\n<p>NOTE ON TRANSACTIONS: keep in mind that this is spinning off a new thread and that any call will be outside of the transaction you are in. Use .withTransaction inside your closure, runnable or callable to make your process run in a transaction that is not calling a transactional service method (such as when using this in a controller).</p>\n<h2>Examples</h2>\n<p>in a service/domain/controller just pass a Closure or <a href=\"http://download.oracle.com/javase/6/docs/api/java/lang/Runnable.html\">Runnable</a> to runAsync</p>\n<pre><code>class someService {\n\n\tdef myMethod(){\n\t\t..do some stuff\n\t\trunAsync {\n\t\t\t//this will be in its own trasaction \n\t\t\t//since each of these service methods are Transactional\n\t\t\tcalcAging() \n\t\t}\n\t\t.. do some other stuff while aging is calced in background\n\t}\n\n\tdef calcAging(){\n\t\t...do long process\n\t}\n}\n</code></pre>\n<p>or inject the executorService</p>\n<pre><code>class someService {\n\tdef executorService\n\n\tdef myMethod(){\n\t\t....do stuff\n\t\tdef future = executorService.submit({\n\t\t\treturn calcAging() //you can of course leave out the "return" here\n\t\t} as Callable)\n\t\t.. do some other stuff while its processing\n\t\t//now block and wait with get()\n\t\tdef aging = future.get()\n\t\t..do something\n\t}\n\n\tdef calcAging(){\n\t\t...do long process\n\t\treturn agingCalcObject\n\t}\n\n}\n</code></pre>\n<p>or during a domain event</p>\n<pre><code>class Book {\n\tdef myNotifyService\n\t\n\tString name\n\t\n\tdef afterInsert(){\n\t\trunAsync {\n\t\t\tmyNotifyService.informLibraryOfCongress(this)\n\t\t}\n\t}\n}\n</code></pre>\n<p>the callAsync allows you to spin of a process and calls the underlying executorService submit</p>\n<pre><code>class someService {\n\tdef myMethod(){\n\t\t....do stuff\n\t\tdef future = callAsync {\n\t\t\treturn calcAging() //you can of course leave out the "return" here\n\t\t}\n\t\t.. do some other stuff while its processing\n\t\t//now block and wait with get()\n\t\tdef aging = future.get()\n\t\t..do something with the aging\n\t}\n\n\tdef calcAging(){\n\t\t...do stuff\n\t\treturn agingCalcObject\n\t}\n}\n</code></pre>\n<h2>TODOs</h2>\n<ul>\n<li>TODO - setup a wrapper so we can use a <a href=\"http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ScheduledExecutorService.html\">ScheduledExecutorService</a> too.</li>\n</ul>\n<h2>Release Notes</h2>\n<ul>\n<li>0.2 - released 2016-08-17\n<ul>\n<li>First publicly announced version</li>\n</ul>\n</li>\n<li>0.4 - released 2016-08-19\n<ul>\n<li>Fixed "submit returns void future"</li>\n</ul>\n</li>\n</ul>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "google-visualization", |
| "repo": "plugins", |
| "owner": "bmuschko", |
| "desc": "Grails grails-google-visualization plugin", |
| "labels": [ |
| "google" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/bmuschko/grails-google-visualization/issues", |
| "latestVersion": "2.2.1", |
| "updated": "2016-12-07T08:21:55.677Z", |
| "systemIds": [ |
| "org.grails.plugins:grails-google-visualization" |
| ], |
| "vcsUrl": "https://github.com/bmuschko/grails-google-visualization" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/bmuschko/grails-google-visualization\"><img src=\"https://travis-ci.org/bmuschko/grails-google-visualization.svg\" alt=\"Travis CI build status\" /></a></p>\n<h1>Grails Google Visualization plugin</h1>\n<h2>Overview</h2>\n<p><a href=\"http://grails.org/plugin/google-visualization\">This Grails plugin</a> provides a taglib for the interactive charts of the <a href=\"https://developers.google.com/chart/\">Google Visualization API</a>.</p>\n<h2>Documentation</h2>\n<p>You can find the full documentation in the corresponding GitHub wiki <a href=\"https://github.com/bmuschko/grails-google-visualization/wiki\">here</a>.</p>\n<h2>News</h2>\n<ul>\n<li><strong>December 7, 2016</strong>: Release version 2.2.1: Reverted changes introduced in release 2.1.1 as per issue #67</li>\n<li><strong>September 15, 2016</strong>: Release version 2.2 (not recommended): new config paramater <code>google.maps.key</code> required to use Google Map based visualization as mentioned in issue #65.</li>\n<li><strong>August 21, 2016</strong>: Release version 2.1.1 (not recommended): renames url mapping file to avoid conflicts as stated in issue #63.</li>\n<li><strong>August 17, 2016</strong>: Release version 2.1 with bugfix for issue #54 and added support for AnnotationChart.</li>\n<li><strong>October 09, 2015</strong>: Release version 2.0 providing Grails 3 support.</li>\n<li><strong>January 07, 2015</strong>: Bug fix release 1.0.1 to add "title" config option to the Calendar chart.</li>\n<li><strong>January 04, 2015</strong>: We are pleased to announce the release of version 1.0 with quite a few changes, that potentially could present some backward compatibility issues. Please check the changelog for more details: https://github.com/bmuschko/grails-google-visualization/wiki/changelog</li>\n</ul>\n<h2>Features</h2>\n<ul>\n<li>Supports the following visualizations: Annotated Time Line, Annotation Chart, Area Chart, Bar Chart, Bubble Chart, Candlestick Chart, Column Chart, Combo Chart, Gauge, Geo Chart Geo Map, Intensity Map, Line Chart, Map, Motion Chart, Organizational Chart, Pie Chart, Scatter Chart, Stepped Area Chart, Table Chart, Time Line Chart and Tree Map. See the <a href=\"https://developers.google.com/chart/interactive/docs/gallery\">gallery</a> for more information.</li>\n<li>Implements redesigned charts (Area, Bar, Bubble, Candlestick, Column, Combo, Line, Pie, Scatter and Stepped Area Charts) from the previously known as "Core Chart package" as well as the deprecated versions.</li>\n<li>Provides implementations for <a href=\"https://developers.google.com/chart/interactive/docs/gallery/table#Formatters\">table formatters</a> TableArrowFormat, TableBarFormat, TableColorFormat, TableDateFormat, TableNumberFormat and TablePatternFormat.</li>\n<li>Visualization <a href=\"https://developers.google.com/chart/interactive/docs/events\">Event Handling</a>.</li>\n<li>Provides support for <a href=\"https://developers.google.com/chart/interactive/docs/roles\">Data Tables Roles</a> (since version 1.0)</li>\n</ul>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "gscripting", |
| "repo": "maven", |
| "owner": "frnktrgr", |
| "desc": "Run Groovy scripts in Grails", |
| "labels": [ |
| "scripting" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/frnktrgr/grails-gscripting/issues", |
| "latestVersion": "1.1.0", |
| "updated": "2018-11-09T15:02:48.639Z", |
| "systemIds": [ |
| "org.grails.plugins:gscripting" |
| ], |
| "vcsUrl": "https://github.com/frnktrgr/grails-gscripting" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>grails-gscripting</h1>\n<p>Run Groovy scripts in Grails</p>\n<p>##Logging (Config.groovy):</p>\n<pre><code>debug 'grails.plugin.gscripting',\n 'grails.app.services.grails.plugin.gscripting'\n</code></pre>\n<p>##Create a script and run it</p>\n<pre><code class=\"language-groovy\">def gscriptingService\ndef sre = gscriptingService.createScriptRuntimeEnv("Foo", '''\nprocess([c:"hello", d:"world"]) {\n // call another service\n\t// app.fooService.bar();\n\tlog.info("callParams: "+ctx.callParams);\n\tlog.info("scriptParams: "+scriptParams);\n\tlog.debug("metadata: "+ctx.metadata); 3 + 4 + 2\n}\n''')\nsre.run([a:23, b:42])\nsre.run()\n</code></pre>\n<p><code>gscriptingService.createScriptRuntimeEnv(String label, String sourcecode)</code> creates a new script with the default DSL provider. In the closure given as an argument to <code>process(Map scriptParams) { <HERE> }</code> you can use some DSL properties as described below:</p>\n<ul>\n<li><code>log</code>: logger</li>\n<li><code>scriptParams</code>: the map given as first argument to <code>process</code></li>\n<li><code>grailsApplication</code>: grailsApplication instance like in controllers or services</li>\n<li><code>app.<serviceName></code>: services of your Grails application, e.g. gscriptingService</li>\n<li><code>ctx</code>: the default context as described below:\n<ul>\n<li><code>ctx.callParams</code>: the map given as an argument to <code>run</code></li>\n<li><code>ctx.metadata</code>: a map with <code>qualifiedName</code>, <code>sourcecode</code>, and <code>instanceIndex</code> (see below)</li>\n<li><code>ctx.state</code>: a map for variables, can also be access directly, e.g. <code>ctx.state.foo = 42</code> is the same as <code>foo = 42</code></li>\n<li><code>ctx.shared</code>: a map shared by every instance of the script (not synchronized)\nYou can run a script multiple times, once you created it. Simple call <code>run()</code> or <code>run(Map callParams)</code> on the script. <code>stats()</code> returns simple statistics like min/max/average execution time.</li>\n</ul>\n</li>\n</ul>\n<p>##Register script and run by qualified name</p>\n<pre><code class=\"language-groovy\">def gscriptingService\ngscriptingService.registerScriptRuntimeEnv("foo.Bar", '''\nprocess([first:"hello", second:"world"]) {\n\t// call another service\n\t// app.fooService.bar();\n\tlog.info("callParams: "+ctx.callParams);\n\tlog.info("scriptParams: "+scriptParams);\n\tlog.debug("metadata: "+ctx.metadata); 3 + 4 + 2\n}\n''')\ngscriptingService.run("foo.Bar")\ngscriptingService.run("foo.Bar", [a:23, b:42])\n</code></pre>\n<p>In order to provide a script to your whole application, you can register a script under a qualified name. Register an updated script again with the same qualified name in order to reload it.</p>\n<p>##Multi-threading and thread-safety\nRunning scripts is thread-safe. If a script is still running and you invoke run again, e.g. in another thread, a new instance will be created and started. The actual instance index can be accessed via the context (see above <code>instanceIndex</code>).</p>\n" |
| }, |
| { |
| "deprecated": "Source repository is archived. This entry should probably be removed from the registry.", |
| "bintrayPackage": { |
| "name": "hibernate-filter", |
| "repo": "grails-plugins", |
| "owner": "piotrchowaniec", |
| "desc": "", |
| "labels": [ |
| "database" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/fingo/grails-hibernate-filter/issues", |
| "latestVersion": "0.2.0", |
| "updated": "2017-11-07T07:34:55.834Z", |
| "systemIds": [ |
| "org.grails.plugins:grails-hibernate-filter" |
| ], |
| "vcsUrl": "https://github.com/fingo/grails-hibernate-filter" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>grails-hibernate-filter</h1>\n<h1>Description</h1>\n<p>This is a fork of the original <a href=\"http://grails.org/plugin/hibernate-filter\">Grails Hibernate Filter Plugin</a>\ncreated from fork <a href=\"https://github.com/appcela/grails-hibernate-filter\">appcela/grails-hibernate-plugin</a>\nto make it work with the Grails 3 and Hibernate 4.</p>\n<p>This repo contains two projects:</p>\n<ol>\n<li>hibernate-filter-plugin - with plugin code</li>\n<li>hibernate-filter-example - with example application using plugin</li>\n</ol>\n<h1>Usage</h1>\n<h2>Build Plugin File</h2>\n<p>Clone the repository and execute in main directory command:</p>\n<pre><code>./gradlew hibernate-filter-plugin:jar\n</code></pre>\n<p>You can publish it to your maven local repository using:</p>\n<pre><code>./gradlew hibernate-filter-plugin:publishToMavenLocal\n</code></pre>\n<h2>Running example application</h2>\n<p>To run example application use command:</p>\n<pre><code>./gradlew hibernate-filter-example:bootRun\n</code></pre>\n<h2>Use plugin in your application</h2>\n<p>Add dependency in build.gradle:</p>\n<pre><code>compile "org.grails.plugins:grails-hibernate-filter:0.2.0"\n</code></pre>\n<p>Configure dataSource in application.yml</p>\n<pre><code>configClass: org.grails.plugin.hibernate.filter.HibernateFilterDomainConfiguration\n</code></pre>\n<h1>Usage</h1>\n<p>Please refer to the official <a href=\"http://grails.org/plugin/hibernate-filter\">Grails Hibernate Filter Plugin</a> for usage.</p>\n<h1>Continuous integration server</h1>\n<p><a href=\"https://travis-ci.org/fingo/grails-hibernate-filter\"><img src=\"https://travis-ci.org/fingo/grails-hibernate-filter.svg?branch=master\" alt=\"Build Status\" /></a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "comment": "Does not work with Grails > 3.2.* as of v0.5.5 (according to https://github.com/alexkramer/grails-hibernate-filter/issues/13)", |
| "name": "hibernate-filter", |
| "repo": "grails3-plugins", |
| "owner": "goodstartgenetics", |
| "desc": "Provides utilities to define hibernate filters on classes and collections. Meant to be used with Grails 3.2 and higher, Hibernate 5, and GORM 6", |
| "labels": [ |
| "database" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/alexkramer/grails-hibernate-filter/issues", |
| "latestVersion": "0.5.5", |
| "updated": "2019-05-30T00:38:57.314Z", |
| "systemIds": [ |
| "org.grails.plugins:hibernate-filter-plugin" |
| ], |
| "vcsUrl": "https://github.com/alexkramer/grails-hibernate-filter" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>grails-hibernate-filter</h1>\n<h1>Description</h1>\n<p>This is a fork of the original <a href=\"http://grails.org/plugin/hibernate-filter\">Grails Hibernate Filter Plugin</a>\ncreated from fork <a href=\"https://github.com/fingo/grails-hibernate-filter\">fingo/grails-hibernate-plugin</a>\nto make it work with Grails 3.2.3 > *, Hibernate 5, and GORM 6.</p>\n<p>This repo contains two projects:</p>\n<ol>\n<li>hibernate-filter-plugin - with plugin code</li>\n<li>hibernate-filter-example - with example application using plugin</li>\n</ol>\n<h1>Usage</h1>\n<h2>Build Plugin File</h2>\n<p>Clone the repository and execute in main directory command:</p>\n<pre><code>./gradlew hibernate-filter-plugin:jar\n</code></pre>\n<p>You can publish it to your maven local repository using:</p>\n<pre><code>./gradlew hibernate-filter-plugin:publishToMavenLocal\n</code></pre>\n<h2>Running example application</h2>\n<p>To run example application use command:</p>\n<pre><code>./gradlew hibernate-filter-example:bootRun\n</code></pre>\n<h2>Installation</h2>\n<p>Add dependency in build.gradle:</p>\n<pre><code>repositories {\n maven { url "https://dl.bintray.com/goodstartgenetics/grails3-plugins/" }\n}\n\ndependencies {\n compile "org.grails.plugins:hibernate-filter-plugin:0.5.5"\n}\n</code></pre>\n<h1>Usage</h1>\n<p>Please refer to this project's <a href=\"https://github.com/alexkramer/grails-hibernate-filter/wiki\">wiki</a> for usage.</p>\n<h1>Continuous integration server</h1>\n<p><a href=\"https://travis-ci.org/alexkramer/grails-hibernate-filter\"><img src=\"https://travis-ci.org/alexkramer/grails-hibernate-filter.svg?branch=master\" alt=\"Build Status\" /></a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "isomorphic", |
| "repo": "plugins", |
| "owner": "zacharyklein", |
| "desc": "Grails Isomorphic Rendering Plugin", |
| "labels": [ |
| "isomorphic", |
| "ssr", |
| "javascript", |
| "react" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/ZacharyKlein/grails-isomorphic/issues", |
| "latestVersion": "1.2", |
| "updated": "2016-12-02T17:18:40.820Z", |
| "systemIds": [ |
| "org.grails.plugins:grails-isomorphic" |
| ], |
| "vcsUrl": "https://github.com/ZacharyKlein/grails-isomorphic" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>grails-isomorphic</h1>\n<p>Grails Isomorphic Rendering Plugin</p>\n<p><a href=\"https://travis-ci.org/ZacharyKlein/grails-isomorphic\"><img src=\"https://travis-ci.org/ZacharyKlein/grails-isomorphic.svg?branch=master\" alt=\"Build Status\" /></a></p>\n<p>This plugin provides a single GSP taglib, <code><iso:javascript/></code> which will allow rendering a JavaScript file through Nashorn on the server, as well as loading the same JavaScript on the client. This plugin was designed to be used with React, but is not limited to that library.</p>\n<h2>Usage</h2>\n<p>The <code><iso:javascript /></code> tag requires two attributes, <code>path</code> and <code>data</code>. <code>path</code> should be a resource path to a JavaScript file. Since for true isomorphic behavior the JavaScript needs to be loaded on the client in addition to the server, <code>/src/main/webapp</code> is an ideal location (however it will not work if you deploy your app as a JAR file). Otherwise, a <code>publicPath</code> attribute is supported to supply an alternate path for the client JavaScript file.</p>\n<p>Example:</p>\n<pre><code> <iso:javascript path='bundle.js' data={[some: data]}/> <!-- this will load /src/main/webapp/bundle.js for both server and client (because resources in src/main/webapp are made available by default, e.g., static/bundle.js -->\n \n <iso:javascript path='bundle.js' publicPath='assets/bundle.js' data={[some: data]}/> <!-- this will load /src/main/resources/bundle.js for the server and grails-app/assets/javascripts/bundle.js for the client -->\n</code></pre>\n<p>The <code>data</code> attribute takes a map of data to be converted into a JSON object, which can be parsed and used in your JavaScript to supply initial data.</p>\n<p>Example:</p>\n<p><code><iso:javascript path='bundle.js' data={[a: 1, b: 2]}/></code></p>\n<p>The actual JavaScript bundle can contain any valid JavaScript code, however it is important to note that Nashorn does not support DOM features, CSS, or other browser-specific APIs. React code using JSX will need to be transpiled via Babel/webpack or some other means in order to be correctly evaluated by Nashorn.</p>\n<p>In addition, the plugin expects that the JavaScript bundle will include two top-level "render" functions, one for the browser and one for the server. These functions should take the initial JSON object as a single argument. By default, these functions are expected to be named <code>renderClient</code> and <code>renderServer</code> - you can customize these names via the <code>clientRenderFunction</code> and <code>serverRenderFunction</code> attrs on the <code>iso:javascript</code> tag.</p>\n<p>Here is a simple JavaScript bundle that can be evaluated on both the browser and the server, assuming that the <code>data</code> attribute was supplied with <code>[a:1, b:2]</code>:</p>\n<pre><code>//bundle.js\n\nif (typeof window !== 'undefined' && typeof document !== 'undefined' && typeof document.createElement === 'function') {\n window.renderClient = (data) => {\n return data.a + data.b; //will return 3.0\n }\n}\nelse {\n global.renderServer = (data) => {\n let json = JSON.parse(data);\n return json.a + json.b; //will return 3.0\n };\n}\n</code></pre>\n<p>When writing isomorphic React, it is important to make sure that the client and server-side rendered code is identically, or React will be unable to reuse the server-side rendered code. For this reason, the plugin will always supply both the client and server render functions with the same data - this should evaluate your React code the same way on both platforms.</p>\n<p>Please see this <a href=\"https://github.com/ZacharyKlein/grails-isomorphic-react\">sample project to see the plugin usage</a> in conjunction with webpack, using the <a href=\"https://github.com/grails-profiles/react\">React profile</a> for Grails.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "java8", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Provides support for Java 8 specific features in Grails", |
| "labels": [ |
| "java-date-time" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/grails-java8/issues", |
| "latestVersion": "1.2.3", |
| "updated": "2020-07-06T19:52:59.484Z", |
| "systemIds": [ |
| "org.grails.plugins:grails-java8" |
| ], |
| "vcsUrl": "https://github.com/grails-plugins/grails-java8" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>grails-java8</h1>\n<p><a href=\"https://travis-ci.org/grails-plugins/grails-java8\"><img src=\"https://travis-ci.org/grails-plugins/grails-java8.svg?branch=master\" alt=\"Build Status\" /></a></p>\n<p>A plugin to support Java 8 specific functionality</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "comment": "This plugin has been updated to Grails 4 but there is no release yet that works with Grails > 3", |
| "name": "json-apis", |
| "repo": "plugins", |
| "owner": "gregopet", |
| "desc": "", |
| "labels": [ |
| "json" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/gregopet/grails-json-apis/issues", |
| "latestVersion": "0.98", |
| "updated": "2016-03-31T13:31:54.983Z", |
| "systemIds": [ |
| "org.grails.plugins:json-apis" |
| ], |
| "vcsUrl": "https://github.com/gregopet/grails-json-apis" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>json-apis</h1>\n<h2>Grails plugin for managing multiple JSON apis using domain class annotations</h2>\n<p>The goal of this plugin is to help convert Grails domain classes into various\nJSON representations needed in different parts of your web application or to\nsupport various API versions.</p>\n<p>Features:</p>\n<ul>\n<li>Allows you to declare multiple named JSON configurations for different use cases</li>\n<li>Configuration is very straightforward: all that is required is to mark domain class\nproperties with a single annotation naming the configurations under which that\nproperty should be included in the serialized JSON object</li>\n<li>Works for collections as well as <code>belongsTo</code> properties</li>\n<li>Enables developers to avoid the circular object reference problem elegantly by\ndefining appopriate namespaces - this way it is possible to start the serialization\neither in a parent or child entity, depending on the use case</li>\n<li>Works for objects serialized inside a <a href=\"http://grails.org/doc/latest/guide/theWebLayer.html#moreOnJSONBuilder\">JSON builder</a></li>\n<li>Uses the Grails' <code>ObjectMarshaller</code> mechanism under the hood</li>\n<li>Detects API changes during development time live reloads</li>\n</ul>\n<h2>Example of use</h2>\n<p>Several API variants can be easily defined in domain classes by annotating properties with\n<code>JsonApi</code> and providing a list of API profile names under which that property should appear in the\nresulting JSON. Marking a property with the <code>JsonApi</code> annotation but providing no API names will\ninclude that property in all APIs. The database identity property will always be included\nautomatically. One could for instance define the following domain class:</p>\n<pre><code class=\"language-groovy\">import grails.plugins.jsonapis.JsonApi\n\nclass User {\n\t@JsonApi\n\tString screenName\n\n\t@JsonApi('userSettings')\n\tString email\n\n\t@JsonApi(['userSettings', 'detailedInformation'])\n\tString twitterUsername\n}\n</code></pre>\n<p>Then in the controller one would call the desired named JsonApi configuration to get only\nthe fields defined for that API. The following code:</p>\n<pre><code class=\"language-groovy\">JSON.use("detailedInformation") {\n\trender person as JSON\n}\n</code></pre>\n<p>...would convert the <code>person</code> object into JSON containing the <code>id</code>, <code>screenName</code> and <code>twitterUsername</code>\nproperties but not the <code>email</code>. It works for collections as well, converting each collection\nmember using the same API profile that was used to convert the parent:</p>\n<pre><code class=\"language-groovy\">static hasMany = [\n\tpets: Pet\n]\n@JsonApi('detailedInformation')\nSet pets\n</code></pre>\n<p>To include a domain object's parent in a JSON API, declare a <code>belongsTo</code> property explicitly\nand annotate it with <code>JsonApi</code> (but be careful not to create circular paths by including both\nends of a <code>belongsTo</code>/<code>hasMany</code> pair):</p>\n<pre><code class=\"language-groovy\">static belongsTo = [\n\tuser:User\n]\n\n@JsonApi('petDetails')\nUser user\n</code></pre>\n<p>JSONBuilder is supported, too:</p>\n<pre><code class=\"language-groovy\">JSON.use("userSettings") {\n\trender(contentType: "text/json") {\n\t\tuser = User.first()\n\t\tpet = Pet.first()\n\t}\n}\n</code></pre>\n<h2>Testing support</h2>\n<p>To register named marshallers in unit tests, you can use a static method that accepts the marshaller name\nthe classes you need registered:</p>\n<pre><code class=\"language-groovy\">JsonApiRegistry.registerMarshaller("detailedInformation", ViciousPet)\n</code></pre>\n<h2>Future plans</h2>\n<ul>\n<li>Detect circular APIs and display a warning on startup, perhaps disable them entirely</li>\n<li>Add a script/controller that would document the registered APIs in one or more formats</li>\n<li>Read the domain class annotations and produce configurations for those 3rd party JSON\nrenderers which currently seem to perform better than the native Grails implementation</li>\n</ul>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "mailgun", |
| "repo": "grails-plugin", |
| "owner": "orkonano", |
| "desc": "Grails grails-mailgun plugin", |
| "labels": [ |
| "mail", |
| "mailgun" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/orkonano/grails-mailgun/issues", |
| "latestVersion": "2.0.3-b", |
| "updated": "2017-05-23T16:48:32.561Z", |
| "systemIds": [ |
| "org.grails.plugins:grails-mailgun" |
| ], |
| "vcsUrl": "https://github.com/orkonano/grails-mailgun" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/orkonano/grails-mailgun.svg?branch=master\"><img src=\"https://travis-ci.org/orkonano/grails-mailgun.svg?branch=develop\" alt=\"Build Status\" /></a>\n<a href=\"https://stillmaintained.com/orkonano/grails-mailgun\"><img src=\"https://stillmaintained.com/orkonano/grails-mailgun.png\" alt=\"Project Status\" /></a>\n<a href=\"http://waffle.io/orkonano/grails-mailgun\"><img src=\"https://badge.waffle.io/orkonano/grails-mailgun.svg?label=ready&title=Ready\" alt=\"Stories in Ready\" /></a></p>\n<h1>grails-mailgun</h1>\n<p>Grails plugin to use Mailgun Api.</p>\n<p><strong>\ufffd\ufffd\ufffd\ufffdIMPORTANT!</strong>\nYou need to create your own mailgun account. The plugin doesn't work without a valid api-key and a valid domain</p>\n<h2>Config parameters</h2>\n<p>You need to set into your Config.groovy the following properties:</p>\n<pre><code class=\"language-groovy\">mailgun{\n apiKey = 'test'\n domain = 'test'\n\n message{\n defaultFrom = 'test'\n defaultTo = 'test'\n defaultSubject = 'BigHamlet tiene promociones para vos'\n format = 'html'\n defaulTemplate = '/test/mailgunTest'\n defaultReplyTo = 'test'\n }\n}\n</code></pre>\n<p>The full list of properties is:</p>\n<pre><code class=\"language-groovy\">mailgun{\n apiKey = 'test'\n domain = 'test'\n\n message{\n defaultFrom = 'test'\n defaultTo = 'test'\n defaultSubject = 'BigHamlet tiene promociones para vos'\n format = 'html'\n defaulTemplate = '/test/mailgunTest'\n defaultReplyTo = 'test'\n }\n\n tracking{\n enabled = 'yes'\n clicks{\n enabled = 'yes'\n }\n opens{\n enabled = 'yes'\n }\n }\n}\n</code></pre>\n<h2>Mailgun Features</h2>\n<p>The plugin allows to work with some features of mailgun:</p>\n<ul>\n<li>Lists all mail list created in mailgun: Mailgun endpoint --> GET: https://api.mailgun.net/v3/lists</li>\n<li>Sends message across Mailgun Api: Mailgun endpoint --> POST: https://api.mailgun.net/v3/$domain/messages</li>\n</ul>\n<h2>Email Html Render</h2>\n<p>The plugin define a default email html render. <strong>DefaultEmailHtmlRender.groovy</strong>\nIt render a view (gsp) passing a model as params</p>\n<pre><code class=\"language-groovy\">\n String render(Map params){\n groovyPageRenderer.render view: params.view, model: params.model\n }\n \n</code></pre>\n<h2>Examples</h2>\n<pre><code class=\"language-groovy\"> class TestController {\n\n def mailgunService\n\n def index() {\n RestResponse resp = mailgunService.allLists\n\n render resp.json.items\n }\n\n def send() {\n RestResponse resp = mailgunService.sendMessage()\n\n render resp.status\n }\n}\n</code></pre>\n<h2>Examples</h2>\n<pre><code class=\"language-groovy\"> class TestController {\n\n def mailgunService\n\n def index() {\n RestResponse resp = mailgunService.allLists\n\n render resp.json.items\n }\n\n def send() {\n RestResponse resp = mailgunService.sendMessage()\n\n render resp.status\n }\n}\n</code></pre>\n<p><strong>MailgunService</strong> implements all features.</p>\n<p>The method <em>allLists</em>, lists all mail lists created in mailgun.</p>\n<p>The method <em>sendMessage</em>, sends a new message across mailgun api.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "mailwatcher", |
| "repo": "plugins", |
| "owner": "junehasissues", |
| "desc": "This Plugin reads unread mails from provided mail account Id. To Grails 3 updated Version of https://github.com/IntelliGrape/Grails-Mail-Watcher-Plugin.", |
| "labels": [ |
| "mail" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/JuNeHasIssues/grails-mailwatcher/issues", |
| "latestVersion": "0.4.1", |
| "updated": "2019-06-27T09:56:24.945Z", |
| "systemIds": [ |
| "org.grails.plugins:mailwatcher" |
| ], |
| "vcsUrl": "https://github.com/JuNeHasIssues/grails-mailwatcher" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>grails-mailwatcher</h1>\n<p>To Grails 3 updated Version of https://github.com/IntelliGrape/Grails-Mail-Watcher-Plugin</p>\n<h3>Usage Information</h3>\n<p>Configure: The plugin needs the following <strong>properties</strong></p>\n<pre><code>grails {\n mailwatcher {\n email = "_youremailId_"\n password = "_password_"\n readTimeOut = 10000\n folderToRead="Inbox"\n protocol = "imaps"\n host = "imap.gmail.com"\n port = "993"\n excludeSender = "test@test.com,test1@test1.com"\n filterSubject = "/\\test-pattern.*$/"\n }\n}\n</code></pre>\n<ul>\n<li>\n<p><strong>readTimeOut</strong> Timeout For WatcherJob</p>\n</li>\n<li>\n<p><strong>folderToRead</strong> This is the name of the Folder that app reads. Defaults to Inbox.Any other folder in your mail can also be specified.</p>\n</li>\n<li>\n<p><strong>protocol</strong> Protocol used for reading mail</p>\n</li>\n<li>\n<p><strong>host</strong> Hostname for the mail server</p>\n</li>\n<li>\n<p><strong>port</strong> Port to which app connects</p>\n</li>\n<li>\n<p><strong>excludeSender</strong> (optional) Mails from this sender/these senders won't be saved</p>\n</li>\n<li>\n<p><strong>filterSubject</strong> (optional) Only mails whose subject matches this regex pattern are saved</p>\n</li>\n</ul>\n<p>To log the mails that are read, change the logging level to <strong>info</strong></p>\n<hr />\n<p><strong>RoadMap</strong></p>\n<ul>\n<li>\n<p>Folder to look for in Mail can be given as regex</p>\n</li>\n<li>\n<p>Can fire mail received event when a mail with specific pattern is received.</p>\n</li>\n</ul>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "melody", |
| "repo": "plugins", |
| "owner": "sergiomichels", |
| "desc": "Integrate JavaMelody monitoring into Grails application.", |
| "labels": [ |
| "javamelody" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/javamelody/grails-melody-plugin/issues", |
| "latestVersion": "1.80.0", |
| "updated": "2019-12-12T21:36:08.862Z", |
| "systemIds": [ |
| "org.grails.plugins:grails-melody-plugin" |
| ], |
| "vcsUrl": "https://github.com/javamelody/grails-melody-plugin" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>grails-melody-plugin</h1>\n<p><a href=\"https://github.com/javamelody/javamelody/wiki\">JavaMelody</a> monitoring <a href=\"http://plugins.grails.org/plugin/sergiomichels/grails-melody-plugin\">plugin</a> for Grails 3, to monitor application performance.</p>\n<p><a href='Screenshots#charts'><img src='https://github.com/javamelody/javamelody/wiki/resources/screenshots/graphs.png' alt='Screenshots' width='50%' title='Screenshots' /></a></p>\n<p><em>The goal of JavaMelody is to monitor applications in QA and production environments. It is not a tool to simulate requests from users, it is a tool to measure and calculate statistics on real operation of an application depending on the usage of the application by users.</em></p>\n<h3>Installation</h3>\n<p>To install the plugin, just add a dependency as given at the top of <a href=\"http://plugins.grails.org/plugin/sergiomichels/grails-melody-plugin\">this page</a> (but runtime is enough instead of compile). For example:</p>\n<pre><code class=\"language-yaml\">dependencies {\n runtime 'org.grails.plugins:grails-melody-plugin:1.xx.0'\n}\n</code></pre>\n<p>Then you will be able to monitor the application at <code>http://localhost:8080/<YourContext>/monitoring</code>.</p>\n<p><a href=\"https://bintray.com/sergiomichels/plugins/grails-melody-plugin/_latestVersion\"><img src=\"https://api.bintray.com/packages/sergiomichels/plugins/grails-melody-plugin/images/download.svg\" alt=\"Download\" /></a></p>\n<p><a href=\"https://github.com/javamelody/javamelody/wiki/ReleaseNotes\">Release Notes</a></p>\n<h3>More configuration</h3>\n<p>A few things you might want to know:</p>\n<ul>\n<li>the plugin overwrites original grails 'dataSource' bean in spring context with a JavaMelody datasource proxy.</li>\n<li>the plugin uses groovy meta programming to intercept grails services method calls.</li>\n</ul>\n<p>All parameters described in the <a href=\"https://github.com/javamelody/javamelody/wiki/UserGuide#6-optional-parameters\">JavaMelody User's guide</a>\ncan be configured in your grails-app/conf/application.yml file. For example, add the following to disable the monitoring:</p>\n<pre><code class=\"language-yaml\">javamelody:\n disabled: true\n</code></pre>\n<p>JavaMelody uses URIs to resolve HTTP requests. This means that</p>\n<pre><code>/book/show/1 and \n/book/show/23 \n</code></pre>\n<p>will resolve as different requests. While that's desirable in some cases, often you want the statistics to be gathered for the show action, irrespective of parameters. In that case, add the following configuration in your grails-app/conf/application.yml file and the above URIs will show up as /book/show/$.</p>\n<pre><code class=\"language-yaml\">javamelody:\n # filter out numbers from URI\n http-transform-pattern: \\d+\n</code></pre>\n<p>Similar issue may come for SQL monitoring - you can use a similar Regex to filter it.</p>\n<pre><code class=\"language-yaml\">javamelody:\n sql-transform-pattern: \\d+\n</code></pre>\n<p>Other parameters such as storage-directory, url-exclude-pattern, log, monitoring-path, authorized-users or allowed-addr-pattern can also be configured.</p>\n<p>You can also add <a href=\"https://grails-plugins.github.io/grails-spring-security-core/v3/index.html#requestMappings\">rules for the spring security plugin</a>, if installed:</p>\n<pre><code class=\"language-yaml\">grails.plugin.springsecurity.controllerAnnotations.staticRules = [ [pattern: '/monitoring', access: ['ROLE_ADMIN']] ]\n</code></pre>\n<p>or add an authorized-users parameter:</p>\n<pre><code class=\"language-yaml\">javamelody:\n authorized-users: user1:pwd1, user2:pwd2\n</code></pre>\n<p><em>Please submit github pull requests and github issues.</em></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "comment": "Only Grails 3.2, 3.3 supported as of 1.2", |
| "name": "memcached-web-plugin", |
| "repo": "plugins", |
| "owner": "purpleraven", |
| "desc": "Store pages of page fragments in memcached", |
| "labels": [ |
| "cache", |
| "memcached" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/purpleraven/grails-memcached-web-plugin/issues", |
| "latestVersion": "1.2", |
| "updated": "2019-12-10T11:11:15.652Z", |
| "systemIds": [ |
| "org.grails.plugins:grails-memcached-web-plugin" |
| ], |
| "vcsUrl": "https://github.com/purpleraven/grails-memcached-web-plugin" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>grails-cows-cache-plugin</h1>\n<p><a href=\"https://bintray.com/purpleraven/plugins/grails-memcached-web-plugin/_latestVersion\"><img src=\"https://api.bintray.com/packages/purpleraven/plugins/grails-memcached-web-plugin/images/download.svg\" alt=\"Download\" /></a></p>\n<p>The plugin provides possibility to store pages of page fragments in <a href=\"https://www.memcached.org/\">memcached</a> and use it directly from web servers</p>\n<p>thx. to ehcache web for web filter code</p>\n<p>Grails 3.2, 3.3 supported</p>\n<h2>Usage</h2>\n<p>Base logic:</p>\n<ul>\n<li>on first page access, nginx request memcached and receives empty result.</li>\n<li>as a fallback, nginx request web application.</li>\n<li>if action marked as memcached, page will be rendered and added to memcached</li>\n<li>response from web application will be returned to user</li>\n<li>on next requests, content from memcached will be used without calling web application</li>\n<li>dynamic parts of page can be requested by SSI <a href=\"https://en.wikipedia.org/wiki/Server_Side_Includes\">doc</a> on server side or by ajax from client</li>\n</ul>\n<p>Plugin can be disabled by <code>memcached.disabled=true</code> setting</p>\n<p>Controllers actions can be marked by <code>@Memcached(value = 7200, packed = true)</code> annotation or by MemcachedHelper.mark(request, 7200)</p>\n<p>cached content can be removed by <code>memcachedService.remove(url)</code> or <code>memcachedService.flush()</code></p>\n<p>SSI for dynamic content supported , see <a href=\"https://en.wikipedia.org/wiki/Server_Side_Includes\">doc</a></p>\n<pre><code class=\"language-html\"><!--# include virtual="${createLink(controller: 'controller', action: 'action', id:id)}" wait='yes'-->\n</code></pre>\n<p>or</p>\n<pre><code class=\"language-html\"><mc:memcachedTile url="${createLink(controller:'controller',action:'action', id:id))}">\n <span>Content for non-cached page</span>\n</mc:memcachedTile>\n</code></pre>\n<p><code><mc:memcachedLog/></code> shows caching time if memcached activated fror the page</p>\n<h2>Installation</h2>\n<p>Add the following dependencies in <code>build.gradle</code></p>\n<pre><code>repositories {\n...\n maven { url "http://dl.bintray.com/purpleraven/plugins" }\n...\n}\ndependencies {\n...\n compile 'org.grails.plugins:grails-memcached-web-plugin:1.2'\n...\n}\n</code></pre>\n<p>In web application config, example for Nginx</p>\n<pre><code>\n upstream app.port {\n server localhost:8080; # tomcat port\n }\n \n upstream memcached.port {\n server localhost:11211; # memcached port\n }\n \n # without compression, bug ssi supported\n location / {\n ssi on; \n set $memcached_key "$uri?$args";\n memcached_pass memcached.port;\n memcached_gzip_flag 2;\n default_type text/html;\n charset utf-8;\n gunzip on;\n proxy_set_header Accept-Encoding "gzip";\n error_page 404 405 400 500 502 503 504 = @fallback;\n }\n \n location @fallback {\n ssi on;\n proxy_pass http://app.port;\n proxy_max_temp_file_size 0;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_http_version 1.1;\n proxy_set_header Connection "";\n error_page 400 500 502 503 504 /offline.html;\n }\n \n # without compression, ssi NOT supported\n location /compressed/example {\n set $memcached_key "$uri?$args";\n memcached_pass memcached.port;\n memcached_gzip_flag 2;\n default_type text/html;\n charset utf-8;\n gunzip on;\n proxy_set_header Accept-Encoding "gzip";\n error_page 404 405 400 500 502 503 504 = @compressed_fallback;\n }\n\n location @compressed_fallback {\n proxy_pass http://app.port;\n proxy_max_temp_file_size 0;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_http_version 1.1;\n proxy_set_header Connection "";\n error_page 400 500 502 503 504 /offline.html;\n }\n\n\n</code></pre>\n<h2>License</h2>\n<p>Apache 2</p>\n" |
| }, |
| { |
| "deprecated": "This entry in the registry is a duplicate of the entry named 'middleware' by the same author. This entry should probably be removed to avoid confusion.", |
| "bintrayPackage": { |
| "name": "grails-middleware", |
| "repo": "plugins", |
| "owner": "lduarte", |
| "desc": "Grails grails-middleware plugin", |
| "labels": [ |
| "middleware" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/driverpt/grails-middleware/issues", |
| "latestVersion": "0.0.3", |
| "updated": "2016-03-31T13:31:56.173Z", |
| "systemIds": [ |
| "org.grails.plugins:middleware", |
| "org.grails.plugins:grails-middleware" |
| ], |
| "vcsUrl": "https://github.com/driverpt/grails-middleware" |
| }, |
| "documentationUrl": "https://luisduarte.net/grails-middleware/latest/", |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/driverpt/grails-middleware\"><img src=\"https://travis-ci.org/driverpt/grails-middleware.svg\" alt=\"Build Status\" /></a></p>\n<h1>Grails Middleware Plugin</h1>\n<p>See <a href=\"https://driverpt.github.io/grails-middleware/latest\">documentation</a> for further information.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "comment": "Only Grails < 4 supported as of 0.11", |
| "name": "phonenumbers", |
| "repo": "plugins", |
| "owner": "ataylor284", |
| "desc": "Adds support for using Google's libphonenumber library to validate phone numbers", |
| "labels": [ |
| "validation" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/ataylor284/grails-phonenumbers/issues", |
| "latestVersion": "0.11", |
| "updated": "2016-07-21T10:03:35.705Z", |
| "systemIds": [ |
| "ca.redtoad:grails-phonenumbers" |
| ], |
| "vcsUrl": "https://github.com/ataylor284/grails-phonenumbers" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails Phonenumbers Plugin</h1>\n<p><a href=\"https://travis-ci.org/ataylor284/grails-phonenumbers\"><img src=\"https://travis-ci.org/ataylor284/grails-phonenumbers.png?branch=master\" alt=\"Build Status\" /></a></p>\n<p>This plugin adds phone number validation to grails based on google's\nlibphonenumber (http://code.google.com/p/libphonenumber/) project.</p>\n<h2>Getting Started</h2>\n<p>Install the grails plugin. Add the phoneNumber constraint to fields\nof type String to validate them with libphonenumber.</p>\n<pre><code>class MyDomain {\n String phoneNumber\n static constraints = {\n phoneNumber(phoneNumber: true)\n }\n}\n</code></pre>\n<p>By default, the validator runs in loose mode. This rejects strings\nthat have obvious problems that would prevent them from being parsed\nas phone numbers.</p>\n<h2>Region Sensitive Validation</h2>\n<p>A strict mode is available, uses region specific rules. It ensures\nthat there is at least one region where the phone number is valid.\nStrict mode can be enabled on an individual field as shown below, or\nit can be enabled globally by adding\n<code>grails.plugins.phonenumbers.defaultStrict = true</code> to <code>Config.groovy</code>.</p>\n<pre><code>class MyDomain {\n String phoneNumber\n static constraints = {\n phoneNumber(phoneNumber: [strict: true])\n }\n}\n</code></pre>\n<p>The list of regions can be further restricted, either per-field, or\nglobally, as well. By default, the phone number must be valid in any\nregion supported by libphonenumber. To restrict it to one particular\nregion, or set of regions, the allowRegion can be set to a list of\ntwo-character country codes. To accept only US phone numbers, set\n<code>grails.plugins.phonenumbers.defaultAllowedRegions = ['US']</code> in\n<code>Config.groovy</code>, or set it in the constraint as follows.</p>\n<pre><code>class MyDomain {\n String phoneNumber\n static constraints = {\n phoneNumberField(phoneNumber: [strict: true, allowedRegions: ['US']])\n }\n}\n</code></pre>\n<h2>Getting the Region at Validation Time</h2>\n<p>If the region is available in a country field on the domain object, it\ncan be used by the validator dynamically. <code>allowRegions</code> can be set\nto a closure returning a country code or list of country codes. The\nclosure delegate will be the domain object being validated. Example:</p>\n<pre><code>class MyDomain {\n String country\n String phoneNumber\n static constraints = {\n phoneNumber(phoneNumber: [strict: true, allowedRegions: { -> country }])\n }\n}\n</code></pre>\n<h2>Formatting Phone Numbers</h2>\n<p>PhoneNumberService exposes a simple format method for reformatting\nphone number strings. For Example:</p>\n<pre><code>class MyDomain {\n def phoneNumberService\n\n String phoneNumber\n\n void setPhoneNumber(String val) {\n phoneNumber = phoneNumberService?.format(val) ?: val\n }\n}\n</code></pre>\n<h2>Phone Number Geolocation</h2>\n<p>PhoneNumberService also provides a geolocation service that can\ndetermine the country and region from phone number strings. For\nExample:</p>\n<pre><code>class MyDomain {\n def phoneNumberService\n\n String phoneNumber\n String geoCountryName\n String geoCountryCode\n String geoDescription\n\n void setPhoneNumber(String val) {\n phoneNumber = phoneNumberService?.format(val) ?: val\n def geolocationInfo = phoneNumberService?.geolocate(val)\n if (geolocationInfo) {\n geoCountryName = geolocationInfo?.country\n geoCountryCode = Locale.availableLocales.find { it.displayCountry == geoCountryName }?.country\n geoDescription = geolocationInfo?.description\n }\n }\n}\n</code></pre>\n<h2>Using PhoneNumberUtil Directly</h2>\n<p>The phonenumbers plugin publishes the PhoneNumberUtil object as a\nspring bean so it can be autowired into your controllers and services.\nDefine a field called phoneNumberUtil and it will be automatically\ninitialized by spring.</p>\n<pre><code>class MyController {\n def phoneNumberUtil\n}\n</code></pre>\n<h2>TODO</h2>\n<ul>\n<li>GSP tag for javascript AsYouTypeFormatter</li>\n</ul>\n<h2>See Also</h2>\n<p>http://code.google.com/p/libphonenumber</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "pretty-time", |
| "repo": "plugins", |
| "owner": "cazacugmihai", |
| "desc": "A plugin that allows you to display human readable, relative timestamps.", |
| "labels": [ |
| "date" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/cazacugmihai/grails-pretty-time/issues", |
| "latestVersion": "4.0.0", |
| "updated": "2016-03-31T13:31:54.739Z", |
| "systemIds": [ |
| "org.grails.plugins:grails-pretty-time" |
| ], |
| "vcsUrl": "https://github.com/cazacugmihai/grails-pretty-time" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>PrettyTime</h1>\n<p>PrettyTime is an OpenSource time formatting library. PrettyTime creates human readable, relative timestamps like those seen on Digg, Twitter, and Facebook. It\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffds simple, get started \ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdright now!\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd and in over 25 languages!</p>\n<p>This plugin allows you to display human readable, relative timestamps. It is based on <a href=\"http://ocpsoft.org/prettytime/\">PrettyTime</a> OpenSource time formatting library.</p>\n<h2>Installation</h2>\n<pre><code>compile ":pretty-time:3.0.2.Final-1.0.0"\n</code></pre>\n<h2>Installation for 2.x</h2>\n<pre><code>grails install-plugin pretty-time\nplugins {\n compile ":pretty-time:2.1.3.Final-1.0.1"\n}\n</code></pre>\n<h2>Requirements</h2>\n<ul>\n<li>Grails 2.0 or above</li>\n<li>for Grails 1.x use version 0.3</li>\n</ul>\n<h2>Usage</h2>\n<pre><code><prettytime:display date="${someDate}" />\n</code></pre>\n<p>outputs:</p>\n<pre><code>"right now", "2 days ago", or "3 months from now"\n</code></pre>\n<h2>Internationalization (I18n)</h2>\n<p>Build in - uses prettytime library translations. TagLib included in this plugin respects current locale.</p>\n<h2>Tag attributes</h2>\n<table>\n <tr>\n <th>Attribute</th>\n <th>Description</th>\n </tr>\n <tr class=\"table-odd\">\n <td><strong class=\"bold\">date</strong></td>\n <td>The date object to format.</td>\n </tr>\n <tr class=\"table-even\">\n <td><strong class=\"bold\">capitalize</strong></td>\n <td>Capitalize the output text (default: false). Ex: \"<strong class=\"bold\">m</strong>oments ago\" will be capitalized to \"<strong class=\"bold\">M</strong>oments ago\".</td>\n </tr>\n <tr class=\"table-odd\">\n <td><strong class=\"bold\">showTime</strong></td>\n <td>Show the time (default: false). Ex: \"2 days ago<strong class=\"bold\">, 12:00:25 AM</strong>\".</td>\n </tr>\n <tr class=\"table-even\">\n <td><strong class=\"bold\">html5wrapper</strong></td>\n <td>Wrap the output text (default: false). Ex: \"moments ago\" will be wrapped with \"<time datetime="some date" title="some date">moments ago</time>\".</td>\n </tr>\n <tr class=\"table-odd\">\n <td><strong class=\"bold\">format</strong></td>\n <td>The format to use for the date (default: \"hh:mm:ss a\"). The default value is set by \"default.date.format\" in I18n.</td>\n </tr>\n</table>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "pushover", |
| "repo": "maven", |
| "owner": "frnktrgr", |
| "desc": "Provides easy access to Pushover API", |
| "labels": [ |
| "pushover", |
| "push-notification" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/frnktrgr/grails-pushover/issues", |
| "latestVersion": "1.0.2", |
| "updated": "2016-12-22T12:27:30.004Z", |
| "systemIds": [ |
| "org.grails.plugins:pushover" |
| ], |
| "vcsUrl": "https://github.com/frnktrgr/grails-pushover" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>grails-pushover</h1>\n<p>Provides easy access to Pushover API.</p>\n<h2>Installation</h2>\n<p>Add following line to <code>dependencies</code> section in <code>build.gradle</code>.</p>\n<pre><code class=\"language-gradle\">compile 'org.grails.plugins:pushover:1.0.1'\n</code></pre>\n<h2>Configuration</h2>\n<p>Add following lines to <code>grails-app/conf/application.yml</code>:</p>\n<pre><code class=\"language-yaml\">grails:\n\tpushover:\n\t\ttoken: <API_TOKEN>\n\t\tdefaultUser: <DEFAULT_USER>\n</code></pre>\n<p>Get your free API Token from <a href=\"https://pushover.net\">Pushover</a>.</p>\n<p>The specified <code>token</code> is used in every Pushover call if no explicit token option is given.</p>\n<p>If <code>pushoverService.message()</code> is called without a user/group token, the <code>defaultUser</code> is used.</p>\n<h2>Getting started</h2>\n<h3>Send message to default user</h3>\n<p>Send message <code>hello world</code> to <code>defaultUser</code> with configured <code>token</code> (see Configuration).</p>\n<pre><code class=\"language-groovy\">pushoverService.message("hello world")\n</code></pre>\n<h3>Send message to some user/group</h3>\n<p>Send message <code>hello world</code> to <code><USER/GROUP_TOKEN></code>.</p>\n<pre><code class=\"language-groovy\">pushoverService.message("hello world", [user: '<USER/GROUP_TOKEN>'])\n</code></pre>\n<h3>Send message using another API token</h3>\n<p>Send message <code>hello world</code> using <code><ANOTHER_API_TOKEN></code> API token.</p>\n<pre><code class=\"language-groovy\">pushoverService.message("hello world", [token: '<ANOTHER_API_TOKEN>'])\n</code></pre>\n<h2>API</h2>\n<p>All methods and options are named after their Pushover API counterparts. Please read <a href=\"https://pushover.net/api\">Pushover API</a>.</p>\n<h3>Send message</h3>\n<pre><code class=\"language-groovy\">pushoverService.message(String message, Map options=[:])\n</code></pre>\n<ul>\n<li><code>message</code>: your message</li>\n<li><code>options</code>\n<ul>\n<li><code>token</code>: your application's API token (optional if <code>token</code> in config is set)</li>\n<li><code>user</code>: the user/group key (optional if <code>defaultUser</code> in config is set)</li>\n<li><code>device</code>: see <a href=\"https://pushover.net/api#messages\">Pushover Message API</a> (optional)</li>\n<li><code>title</code>: see <a href=\"https://pushover.net/api#messages\">Pushover Message API</a> (optional)</li>\n<li><code>url</code>: see <a href=\"https://pushover.net/api#messages\">Pushover Message API</a> (optional)</li>\n<li><code>url_title</code>: see <a href=\"https://pushover.net/api#messages\">Pushover Message API</a> (optional)</li>\n<li><code>priority</code>: see <a href=\"https://pushover.net/api#messages\">Pushover Message API</a> (optional)</li>\n<li><code>timestamp</code>: see <a href=\"https://pushover.net/api#messages\">Pushover Message API</a> (optional)</li>\n<li><code>sound</code>: see <a href=\"https://pushover.net/api#messages\">Pushover Message API</a> (optional)</li>\n</ul>\n</li>\n<li>return value: map of Pushover response (see <a href=\"https://pushover.net/api#response\">https://pushover.net/api#response</a>)</li>\n</ul>\n<h3>Retrieve the list of current sounds</h3>\n<pre><code class=\"language-groovy\">pushoverService.sounds(Map options=[:])\n</code></pre>\n<ul>\n<li><code>options</code>\n<ul>\n<li><code>token</code>: your application's API token (optional if <code>token</code> in config is set)</li>\n</ul>\n</li>\n<li>return value: map of Pushover response (see <a href=\"https://pushover.net/api#response\">https://pushover.net/api#response</a>)</li>\n</ul>\n<h3>User/Group verification</h3>\n<pre><code class=\"language-groovy\">pushoverService.validateUser(String user, Map options=[:])\n</code></pre>\n<ul>\n<li><code>user</code>: the user/group key</li>\n<li><code>options</code>\n<ul>\n<li><code>token</code>: your application's API token (optional if <code>token</code> in config is set)</li>\n<li><code>device</code>: see <a href=\"https://pushover.net/api\">Pushover API</a> (optional)</li>\n</ul>\n</li>\n<li>return value: map of Pushover response (see <a href=\"https://pushover.net/api#response\">https://pushover.net/api#response</a>)</li>\n</ul>\n<h3>Retrieve information about a group</h3>\n<pre><code class=\"language-groovy\">pushoverService.groups(String group, Map options=[:])\n</code></pre>\n<ul>\n<li><code>group</code>: group key</li>\n<li><code>options</code>\n<ul>\n<li><code>token</code>: your application's API token (optional if <code>token</code> in config is set)</li>\n</ul>\n</li>\n<li>return value: map of Pushover response (see <a href=\"https://pushover.net/api#response\">https://pushover.net/api#response</a>)</li>\n</ul>\n<h3>Adding a user to a group</h3>\n<pre><code class=\"language-groovy\">pushoverService.groupsAddUser(String group, String user, Map options=[:])\n</code></pre>\n<ul>\n<li><code>group</code>: group key</li>\n<li><code>user</code>: user key</li>\n<li><code>options</code>\n<ul>\n<li><code>token</code>: your application's API token (optional if <code>token</code> in config is set)</li>\n<li><code>device</code>: see <a href=\"https://pushover.net/api/groups#add_user\">Pushover Groups API</a> (optional)</li>\n<li><code>memo</code>: see <a href=\"https://pushover.net/api/groups#add_user\">Pushover Groups API</a> (optional)</li>\n</ul>\n</li>\n<li>return value: map of Pushover response (see <a href=\"https://pushover.net/api#response\">https://pushover.net/api#response</a>)</li>\n</ul>\n<h3>Removing a user from a group</h3>\n<pre><code class=\"language-groovy\">pushoverService.groupsDeleteUser(String group, String user, Map options=[:])\n</code></pre>\n<ul>\n<li><code>group</code>: group key</li>\n<li><code>user</code>: user key</li>\n<li><code>options</code>\n<ul>\n<li><code>token</code>: your application's API token (optional if <code>token</code> in config is set)</li>\n</ul>\n</li>\n<li>return value: map of Pushover response (see <a href=\"https://pushover.net/api#response\">https://pushover.net/api#response</a>)</li>\n</ul>\n<h3>Temporarily disabling a user in a group</h3>\n<pre><code class=\"language-groovy\">pushoverService.groupsDisableUser(String group, String user, Map options=[:])\n</code></pre>\n<ul>\n<li><code>group</code>: group key</li>\n<li><code>user</code>: user key</li>\n<li><code>options</code>\n<ul>\n<li><code>token</code>: your application's API token (optional if <code>token</code> in config is set)</li>\n</ul>\n</li>\n<li>return value: map of Pushover response (see <a href=\"https://pushover.net/api#response\">https://pushover.net/api#response</a>)</li>\n</ul>\n<h3>Re-enabling a user in a group</h3>\n<pre><code class=\"language-groovy\">pushoverService.groupsEnableUser(String group, String user, Map options=[:])\n</code></pre>\n<ul>\n<li><code>group</code>: group key</li>\n<li><code>user</code>: user key</li>\n<li><code>options</code>\n<ul>\n<li><code>token</code>: your application's API token (optional if <code>token</code> in config is set)</li>\n</ul>\n</li>\n<li>return value: map of Pushover response (see <a href=\"https://pushover.net/api#response\">https://pushover.net/api#response</a>)</li>\n</ul>\n<h3>Renaming a group</h3>\n<pre><code class=\"language-groovy\">pushoverService.groupsRename(String group, String name, Map options=[:])\n</code></pre>\n<ul>\n<li><code>group</code>: group key</li>\n<li><code>name</code>: new name of the group</li>\n<li><code>options</code>\n<ul>\n<li><code>token</code>: your application's API token (optional if <code>token</code> in config is set)</li>\n</ul>\n</li>\n<li>return value: map of Pushover response (see <a href=\"https://pushover.net/api#response\">https://pushover.net/api#response</a>)</li>\n</ul>\n<p>##TODOs\nSee also https://pushover.net/api</p>\n<ul>\n<li>[ ] obey limitations https://pushover.net/api#limits</li>\n<li>[ ] check response https://pushover.net/api#response</li>\n<li>[ ] Receipts and Callbacks https://pushover.net/api#receipt</li>\n<li>[ ] Being Friendly to our API https://pushover.net/api#friendly</li>\n<li>[ ] Subscription API https://pushover.net/api/subscriptions</li>\n<li>[ ] Licensing API https://pushover.net/api/licensing</li>\n</ul>\n" |
| }, |
| { |
| "comment": "Only Grails < 4 supported as of 0.7.2", |
| "bintrayPackage": { |
| "name": "quick-search", |
| "repo": "plugins", |
| "owner": "tadodotcom", |
| "desc": "\nSearch plugin for domain class properties. Lightweight plugin which puts the ability for searching, it adds utility\nfunctions for building the search result into a string format representation sufficient for auto-complete as well as\nfunctions for listing the results based on the search query.\n", |
| "labels": [ |
| "search" |
| ], |
| "licenses": [ |
| "BSD" |
| ], |
| "issueTrackerUrl": "https://github.com/tadodotcom/grails-quick-search/issues", |
| "latestVersion": "0.7.2", |
| "updated": "2021-02-22T10:01:03.157Z", |
| "systemIds": [ |
| "org.grails.plugins:grails-quick-search", |
| "grails.plugin:grails-quick-search" |
| ], |
| "vcsUrl": "https://github.com/tadodotcom/grails-quick-search" |
| }, |
| "documentationUrl": "https://tadodotcom.github.io/grails-quick-search/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>grails-quick-search</h1>\n<p>Grails plugin for quick search implementation. Supports search for domain class properties and adds utility functions and tag libraries for autocomplete functionality.</p>\n<p>Version 0.7.x of this plugin has been upgraded to Grails 3.1.x.</p>\n<p>See <a href=\"http://tadodotcom.github.io/grails-quick-search/guide/index.html\">documentation</a> for further information.</p>\n" |
| }, |
| { |
| "comment": "Integration with SendGrid is outdated and does not currently seem to work.", |
| "bintrayPackage": { |
| "name": "sendgrid", |
| "repo": "grails-plugins", |
| "owner": "desirable-objects", |
| "desc": "Grails SendGrid Plugin", |
| "labels": [ |
| "mail", |
| "sendgrid" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/desirable-objects/grails-sendgrid/issues", |
| "latestVersion": "2.0.1", |
| "updated": "2016-08-27T11:44:17.969Z", |
| "systemIds": [ |
| "desirableobjects.grails.plugins:grails-sendgrid" |
| ], |
| "vcsUrl": "https://github.com/desirable-objects/grails-sendgrid" |
| }, |
| "documentationUrl": "https://desirable-objects.github.io/grails-sendgrid/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>grails-sendgrid</h1>\n<p><a href=\"http://slack-signup.grails.org\"><img src=\"http://slack-signup.grails.org/badge.svg\" alt=\"Slack Signup\" /></a>\n<a href=\"https://travis-ci.org/desirable-objects/grails-sendgrid\"><img src=\"https://travis-ci.org/desirable-objects/grails-sendgrid.svg\" alt=\"Travis CI\" /></a></p>\n<h2>Introduction</h2>\n<p>The Grails SendGrid plugin allows you to use the services offered by <a href=\"http://sendgrid.com\">SendGrid</a> to send email from your application.</p>\n<p>The plugin works for Grails <code>3.x</code>. For Grails <code>2.x</code> please refer to the <a href=\"https://github.com/desirable-objects/grails-sendgrid/tree/1.x\">1.x</a> branch</p>\n<h2>Installation</h2>\n<p>Add the following dependencies in <code>build.gradle</code></p>\n<pre><code>dependencies {\n...\n compile 'desirableobjects.grails.plugins:grails-sendgrid:2.0.1'\n...\n}\n</code></pre>\n<h2>Configuration</h2>\n<p>Configuration takes place in your application's yaml file.</p>\n<p>The basic configuration you will need to use the plugin is:</p>\n<pre><code class=\"language-yaml\"> sendgrid:\n username: 'your-username'\n password: 'your-password'\n</code></pre>\n<p>Where your-username and your-password should be replaced with your sendgrid login details.</p>\n<p>If you need to override the sengrid API endpoint (such as for development/integration environments, to replace it with a fake 'fixture'), you can do that in the same place:</p>\n<pre><code class=\"language-yaml\"> sendgrid:\n api:\n url: 'http://localhost:8080/your-application/fixture/'\n username: 'your-username'\n password: 'your-password'\n</code></pre>\n<p>Note that your @fixture@ controller must have the 'mail.send.json' action configured, and sending and receiving @application/json@ content, as this is what the plugin expects to call.</p>\n<h2>Sending Email</h2>\n<p>In a pinch, you can send email using the SendGridService in one of two ways:</p>\n<ul>\n<li>Using the sendMail method of the SendGridService directly:</li>\n</ul>\n<pre><code class=\"language-groovy\">sendGridServicesendMail {\n from 'antony@example.com'\n to 'aiten@example.net'\n to 'wirah@example.org'\n bcc 'yourbcc@example.com'\n subject 'This is the subject line'\n body 'This is our message body'\n}\n</code></pre>\n<ul>\n<li>Using the email builder</li>\n</ul>\n<p>This is useful when you might want a more programmatic approach to sending email.</p>\n<pre><code class=\"language-groovy\">SendGridEmail email = new SendGridEmailBuilder()\n .from('antony@example.com')\n .to('aiten@example.net')\n .subject('This is the subject line')\n .withText('This is our message body')\n .build()\n</code></pre>\n<p>When you've built your email, pass it to the SendGridService's send method:</p>\n<pre><code class=\"language-groovy\">sendGridService.send(email)\n</code></pre>\n<p>The email builder is written as a natural-language type DSL, so you might find that there is more than one way to build your email, but under the covers, they are exactly the same.</p>\n<p>For further details, see the sendgrid api [http://docs.sendgrid.com/documentation/api/web-api/mail/]</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "shiro", |
| "repo": "plugins", |
| "owner": "nerderg", |
| "desc": "Secure your Grails application quickly and easily using the Apache Shiro security framework.", |
| "labels": [ |
| "security", |
| "shiro" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/nerdErg/grails-shiro/issues", |
| "latestVersion": "5.0.0", |
| "updated": "2024-11-14T11:14:11.000Z", |
| "systemIds": [ |
| "org.nerderg.plugins:grails-shiro" |
| ], |
| "vcsUrl": "https://github.com/nerdErg/grails-shiro" |
| }, |
| "documentationUrl": "https://nerderg.com/docs/shiro/guide.html", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/nerderg/plugins/grails-shiro/maven-metadata.xml", |
| "readme": "This is the Grails Shiro plugin for Grails version 5+ and Shiro 2.0.1. ee https://github.com/nerdErg/grails-shiro/blob/master/docs/Guide.adoc" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "spring-websocket", |
| "repo": "maven", |
| "owner": "zyro", |
| "desc": "This plugin aims at making the websocket support introduced in Spring 4.0 available to Grails applications.", |
| "labels": [ |
| "websocket" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/zyro23/grails-spring-websocket/issues", |
| "latestVersion": "2.5.0.RC1", |
| "updated": "2020-07-06T19:52:50.415Z", |
| "systemIds": [ |
| "org.grails.plugins:grails-spring-websocket" |
| ], |
| "vcsUrl": "https://github.com/zyro23/grails-spring-websocket" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Spring Websocket Grails Plugin</h1>\n<p>This plugin aims at making the websocket support introduced in Spring 4.0 available to Grails applications.</p>\n<p>You can also use the corresponding Spring docs/apis/samples as a reference.</p>\n<p>That is mentioned multiple times in this readme because there is everything explained in fine detail.</p>\n<p>Grails version requirements:</p>\n<table>\n <tr>\n <th>grails-spring-websocket</th>\n <th>Grails</th>\n </tr>\n <tr>\n <td>2.4.x</td>\n <td>3.2.7+</td>\n </tr>\n <tr>\n <td>2.5.x</td>\n <td>4.0.0+</td>\n </tr>\n</table>\n<h2>Installation</h2>\n<p>To install the plugin into a Grails application add the following line to your <code>build.gradle</code> dependencies section:</p>\n<pre><code>implementation "org.grails.plugins:grails-spring-websocket:2.5.0.RC1"\n</code></pre>\n<p>The plugin is published to bintray, and linked to <code>grails/plugins</code> as well as <code>jcenter</code>.</p>\n<h2>Usage</h2>\n<p>The plugin makes the Spring websocket/messaging web-mvc annotations useable in Grails, too.</p>\n<p>Those annotations can be used in:</p>\n<ul>\n<li>Regular Grails controllers</li>\n<li><code>WebSocket</code> Grails artefacts (<code>grails create-web-socket my.package.name.MyWebSocket</code>)</li>\n<li>Spring <code>@Controller</code> beans</li>\n</ul>\n<p>I think basic usage is explained best by example code.</p>\n<p>But: the code below is just some very minimal it-works proof.</p>\n<p>Check the Spring docs/apis/samples for more advanced use-cases, e.g. security and authentication.</p>\n<h3>Controller (annotated handler method)</h3>\n<p><em>/grails-app/controllers/example/ExampleController.groovy</em>:</p>\n<pre><code class=\"language-groovy\">package example\n\nimport org.springframework.messaging.handler.annotation.MessageMapping\nimport org.springframework.messaging.handler.annotation.SendTo\n\nclass ExampleController {\n\n def index() {}\n\n @MessageMapping("/hello")\n @SendTo("/topic/hello")\n protected String hello(String world) {\n return "hello, ${world}!"\n }\n\n}\n</code></pre>\n<p>Unless you want your handler method to be exposed as a Grails controller action, you should define the annotated method as protected or add an additional annotation <code>@grails.web.controllers.ControllerMethod</code>.</p>\n<p>Alternatively, <code>WebSocket</code> Grails artefacts and/or Spring <code>@Controller</code> beans can be used as well, for example:</p>\n<p><em>/grails-app/websockets/example/ExampleWebSocket.groovy</em>:</p>\n<pre><code class=\"language-groovy\">package example\n\nimport org.springframework.messaging.handler.annotation.MessageMapping\nimport org.springframework.messaging.handler.annotation.SendTo\n\nclass ExampleWebSocket {\n\n @MessageMapping("/hello")\n @SendTo("/topic/hello")\n String hello(String world) {\n return "hello, ${world}!"\n }\n\n}\n</code></pre>\n<h3>Client-side (webstomp.js)</h3>\n<p><em>/grails-app/views/example/index.gsp</em>:</p>\n<pre><code class=\"language-gsp\"><!DOCTYPE html>\n<html>\n <head>\n <meta name="layout" content="main"/>\n\n <asset:javascript src="application" />\n <asset:javascript src="spring-websocket" />\n\n <script type="text/javascript">\n $(function() {\n var socket = new SockJS("${createLink(uri: '/stomp')}");\n var client = webstomp.over(socket);\n\n client.connect({}, function() {\n client.subscribe("/topic/hello", function(message) {\n $("#helloDiv").append(message.body);\n });\n });\n\n $("#helloButton").click(function() {\n client.send("/app/hello", JSON.stringify("world"));\n });\n });\n </script>\n </head>\n <body>\n <button id="helloButton">hello</button>\n <div id="helloDiv"></div>\n </body>\n</html>\n</code></pre>\n<p>This would be the index view of the controller above. The js connects to the message broker and subscribes to <code>/topic/hello</code>.</p>\n<p>For this example, I added a button allowing to trigger a send/receive roundtrip.</p>\n<p>While this example shows jquery used with the asset-pipeline plugin, the use of jquery is <strong>not required</strong>.</p>\n<h3>Service (brokerMessagingTemplate bean)</h3>\n<p>To send messages directly, the <code>brokerMessagingTemplate</code> bean (of type <code>SimpMessageSendingOperations</code>) can be used.</p>\n<p>The plugin provides a <code>WebSocket</code> trait that autowires the <code>brokerMessagingTemplate</code> and delegates to it.</p>\n<p>That <code>WebSocket</code> trait is automatically implemented by <code>WebSocket</code> artefacts but you can implement it from other beans as well, e.g. from a service.</p>\n<p><em>/grails-app/services/example/ExampleService.groovy</em>:</p>\n<pre><code class=\"language-groovy\">package example\n\nimport grails.plugin.springwebsocket.WebSocket\n\nclass ExampleService implements WebSocket {\n\n void hello() {\n convertAndSend "/topic/hello", "hello from service!"\n }\n\n}\n</code></pre>\n<p>Or, if you prefer, you can also inject and use the <code>brokerMessagingTemplate</code> bean directly.</p>\n<p><em>/grails-app/services/example/ExampleService.groovy</em>:</p>\n<pre><code class=\"language-groovy\">package example\n\nimport org.springframework.messaging.simp.SimpMessageSendingOperations\n\nclass ExampleService {\n\n SimpMessageSendingOperations brokerMessagingTemplate\n\n void hello() {\n brokerMessagingTemplate.convertAndSend "/topic/hello", "hello from service!"\n }\n\n}\n</code></pre>\n<h2>Configuration</h2>\n<p>Configuration relies on Spring java config, especially <code>@EnableWebSocketMessageBroker</code>.</p>\n<h3>Default Configuration</h3>\n<p>By default, a configuration bean named <code>webSocketConfig</code> of type <code>grails.plugin.springwebsocket.DefaultWebSocketConfig</code> is used.</p>\n<ul>\n<li>An in-memory <code>Map</code>-based message broker implementation is used.</li>\n<li>The prefixes for broker destinations ("outgoing messages") are: <code>/queue</code> or <code>/topic</code></li>\n<li>The prefix for application destinations ("incoming messages") is: <code>/app</code></li>\n<li>The stomp-endpoint URI is: <code>/stomp</code></li>\n<li>A <code>GrailsSimpAnnotationMethodMessageHandler</code> bean is defined to allow Grails controller methods to act as message handlers</li>\n<li>A <code>GrailsWebSocketAnnotationMethodMessageHandler</code> bean is defined to allow Grails webSocket methods to act as message handlers</li>\n</ul>\n<p>If the default values are fine for your application, you are good to go. No configuration required then.</p>\n<h3>Custom Configuration</h3>\n<p>If you want to customize the defaults, you should override the config bean providing your own bean named <code>webSocketConfig</code>.</p>\n<p>As starting point, you can create a config class/bean very similar to the default config with:</p>\n<pre><code>grails create-web-socket-config my.package.name.MyClassName\n</code></pre>\n<p>That class will be placed under <code>src/main/groovy</code> and needs to be registered as a Spring bean named <code>webSocketConfig</code>, e.g. like this:</p>\n<p><em>/grails-app/conf/spring/resources.groovy</em>:</p>\n<pre><code class=\"language-groovy\">beans = {\n webSocketConfig my.package.name.MyClassName\n}\n</code></pre>\n<p>From there, check the Spring docs/apis/samples for the available configuration options.</p>\n<h3>Full-Featured Broker</h3>\n<p>To use a full-featured (e.g. RabbitMQ, ActiveMQ, etc.) instead of the default simple broker, please refer to the Spring docs regarding configuration.\nAdditionally, add two dependencies for TCP connection management.</p>\n<pre><code>implementation platform("io.netty:netty-bom:4.1.34.Final")\nimplementation platform("io.projectreactor:reactor-bom:Californium-SR6")\nimplementation "io.netty:netty-all"\nimplementation "io.projectreactor.netty:reactor-netty"\n</code></pre>\n<p>It is a good idea to align the BOM versions with the ones your current spring-boot BOM is using.</p>\n<h2>User Destinations</h2>\n<p>To send messages to specific users, you can (among other ways) annotate message handler methods with <code>@SendToUser</code> and/or use the <code>SimpMessagingTemplate.convertAndSendToUser(...)</code> methods.</p>\n<p><em>/grails-app/controllers/example/ExampleController.groovy</em>:</p>\n<pre><code class=\"language-groovy\">class ExampleController {\n\n @MessageMapping("/hello")\n @SendToUser("/queue/hello")\n protected String hello(String world) {\n return "hello from controller, ${world}!"\n }\n\n}\n</code></pre>\n<p>To receive messages for the above <code>/queue/hello</code> user destination, the js client would have to subscribe to <code>/user/queue/hello</code>.</p>\n<p>If a user is not logged in, <code>@SendToUser</code> will still work and only the user who sent the ingoing message will receive the outgoing one returned by the method.</p>\n<p><em>/grails-app/services/example/ExampleService.groovy</em>:</p>\n<pre><code class=\"language-groovy\">class ExampleService implements WebSocket {\n\n void hello() {\n convertAndSendToUser("myTargetUsername", "/queue/hello", "hello, target user!")\n }\n\n}\n</code></pre>\n<p>Again, to receive messages for the above <code>/queue/hello</code> user destination, the js client would have to subscribe to <code>/user/queue/hello</code>.</p>\n<h2>Security</h2>\n<p>To secure websocket messaging, we can leverage the first-class websocket security support of Spring Security 4.0+.</p>\n<p>Check the Spring Security docs and the Spring Guides to get a jump-start into the topic.</p>\n<p>There is a variety of options how to build your solution, including:</p>\n<ul>\n<li>Securing message handler methods in a declarative fashion using annotations (e.g. <code>@PreAuthorize</code>)</li>\n<li>Securing message handler methods by using an <code>@AuthenticationPrincipal</code>-annotated argument.</li>\n<li>Filtering messages and subscriptions (e.g. with an <code>SecurityWebSocketMessageBrokerConfigurer</code>)</li>\n</ul>\n<p>I will only show a short example of securing message handler methods with security annotations and filtering inbound messages. I hope you do not mind the lack of import statements in the following code snippets ;)</p>\n<p>A working Spring Security setup is required. For the sake of brevity, here a super-minimalistic Spring Security dummy configuration:</p>\n<p><em>/build.gradle</em>:</p>\n<pre><code class=\"language-groovy\">dependencies {\n implementation "org.springframework.security:spring-security-config"\n implementation "org.springframework.security:spring-security-messaging"\n implementation "org.springframework.security:spring-security-web"\n}\n</code></pre>\n<p><em>/src/main/groovy/example/WebSecurityConfig.groovy</em>:</p>\n<pre><code class=\"language-groovy\">@Configuration\n@EnableGlobalMethodSecurity(prePostEnabled = true)\n@EnableWebSecurity\nclass WebSecurityConfig extends WebSecurityConfigurerAdapter {\n\n @Override\n protected void configure(HttpSecurity http) throws Exception {\n http.httpBasic()\n http.authorizeRequests().anyRequest().authenticated()\n }\n\n @Autowired\n void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {\n auth.inMemoryAuthentication()\n .withUser("user").password("password").roles("USER")\n }\n\n}\n</code></pre>\n<p>Spring security will by default enable CSRF protection for websocket messages.</p>\n<p>To include the required token in the stomp headers, your js code could look like this:</p>\n<p><em>/grails-app/views/example/index.gsp</em>:</p>\n<pre><code class=\"language-javascript\">$(function() {\n var url = "${createLink(uri: '/stomp')}";\n var csrfHeaderName = "${request._csrf.headerName}";\n var csrfToken = "${request._csrf.token}";\n var socket = new SockJS(url);\n var client = webstomp.over(socket);\n var headers = {};\n headers[csrfHeaderName] = csrfToken;\n client.connect(headers, function() {\n // subscriptions etc. [...]\n });\n});\n</code></pre>\n<p>There are still embedded GSP GString expressions present, which means that snippet will only work in a GSP as-is. If you plan on extracting the js properly into an own js file (or similar), you will have to pass those values along.</p>\n<h3>Securing Message Handler Methods</h3>\n<p>Securing message handler methods can be achieved with annotations in a declarative fashion.</p>\n<p>The following example shows a Grails controller with a secured message handler method and an message exception handler method.</p>\n<p><em>/grails-app/controllers/example/ExampleController.groovy</em>:</p>\n<pre><code class=\"language-groovy\">class ExampleController {\n\n @ControllerMethod\n @MessageMapping("/hello")\n @PreAuthorize("hasRole('ROLE_USER')")\n @SendTo("/topic/hello")\n String hello(String world) {\n return "hello from secured controller, ${world}!"\n }\n \n @ControllerMethod\n @MessageExceptionHandler\n @SendToUser(value = "/queue/errors", broadcast = false)\n String handleException(Exception e) {\n return "caught ${e.message}"\n }\n \n}\n</code></pre>\n<p>Besides the security handling itself, this snippet shows one important catch: if you want to secure Grails controller actions with <code>@PreAuthorize</code>, the secured method has to be public. However, as we still do not want the method to be exposed as a controller action but only as message handler, in this case the use of <code>@ControllerMethod</code> is required.</p>\n<p>If you use Grails <code>WebSocket</code> artefacts or Spring <code>@Controller</code> beans as message handlers, you do obviously not require those additional <code>@ControllerMethod</code> annotations.</p>\n<h3>Filtering messages</h3>\n<p>The following example shows how you can filter inbound messages by type and/or by destination pattern.</p>\n<p><em>/src/main/groovy/example/WebSecurityConfig.groovy</em>:</p>\n<pre><code class=\"language-groovy\">@Configuration\nclass WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {\n \n @Override\n void configureInbound(MessageSecurityMetadataSourceRegistry messages) {\n messages\n .nullDestMatcher().authenticated()\n .simpSubscribeDestMatchers("/user/queue/errors").permitAll()\n .simpDestMatchers("/app/**").hasRole("USER")\n .simpSubscribeDestMatchers("/user/**", "/topic/**").hasRole("USER")\n .simpTypeMatchers(SimpMessageType.MESSAGE, SimpMessageType.SUBSCRIBE).denyAll()\n .anyMessage().denyAll()\n }\n \n}\n</code></pre>\n<h2>Event Handling</h2>\n<p>Starting with Grails 3, grails-plugin-events is a core plugin allowing to use the Reactor framework for event handling.</p>\n<p>While there is no special event integration regarding websocket messaging (because it is not really necessary anymore), a service that handles application events can look like the follwing snippet. I am <em>not</em> talking about Spring <code>ApplicationEvent</code>s here, but Reactor <code>Event</code>s.</p>\n<p><em>/grails-app/services/example/ExampleService.groovy</em>:</p>\n<pre><code class=\"language-groovy\">@Consumer\nclass ExampleService implements WebSocket {\n \n @Selector("myEvent")\n void hello(Event<String> event) {\n convertAndSend("/topic/myEventTopic", "myEvent: ${event.data}")\n }\n \n}\n</code></pre>\n<p>Events can be fired/sent from all application artefacts/beans that implement the trait <code>Events</code>. Grails service beans do so by convention. Those beans also allow dynamic registration of event listeners. E.g.:</p>\n<p><em>/grails-app/services/example/ExampleService.groovy</em>:</p>\n<pre><code class=\"language-groovy\">class ExampleService {\n \n void fireMyEvent() {\n notify "myEvent", "hello from myEvent!"\n }\n \n}\n</code></pre>\n<p><em>/grails-app/init/BootStrap.groovy</em>:</p>\n<pre><code class=\"language-groovy\">class BootStrap implements Events, WebSocket {\n\n def init = {\n on("myEvent") { Event<String> event ->\n convertAndSend("/topic/myEventTopic", "myEvent: ${event.data}")\n }\n }\n\n}\n</code></pre>\n<p>For further information check the Grails async docs.</p>\n<h2>Misc</h2>\n<h3>Startup performance</h3>\n<p>Scanning Grails controllers for message handler methods can impact application startup time if you have many controllers.</p>\n<p>One way around this is to put your message handler methods into Grails <code>WebSocket</code> artefacts instead of Grails controllers and then use a custom websocket config class without the <code>GrailsSimpAnnotationMethodMessageHandler</code>.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "twilio", |
| "repo": "plugins", |
| "owner": "novadge", |
| "desc": "Provides SMS sending capabilities to a Grails application.", |
| "labels": [ |
| "twilio", |
| "sms" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/Novadge/grails-twilio/issues", |
| "latestVersion": "0.1.4", |
| "updated": "2016-08-13T23:01:56.281Z", |
| "systemIds": [ |
| "org.grails.plugins:grails-twilio", |
| "com.novadge.plugins:grails-twilio" |
| ], |
| "vcsUrl": "https://github.com/Novadge/grails-twilio" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<p>Twilio Grails</p>\n<h2>Description</h2>\n<p>The twilio-grails plug-in provides sms sending capability to a Grails application via twilio api.</p>\n<h2>Configuration</h2>\n<p>Add your twilio properties to grails configuration file: Example\nAssuming you have a twilio account, then add the required information to your grails config file.</p>\n<code>\n<pre><code>twilio {\n // Enter your host address\n host = 'https://api.twilio.com'\n apiID = 'enter your api Id'\n apiPass = 'enter your api password'\n smsUrl = '/2010-04-01/Accounts/' + apiID + '/Messages.json'\n number = ""\n}\n</code></pre>\n</code>\n<h2>BuildConfig.groovy</h2>\nCopy and paste the following to your BuildConfig.groovy File\n<code>\ncompile(group:'org.apache.httpcomponents',name:'httpclient',version:'4.3.6')\n compile(group:'org.apache.httpcomponents',name:'fluent-hc',version:'4.3.6')\n compile(group:'org.apache.httpcomponents',name:'httpclient-cache',version:'4.3.6')\n compile(group:'org.apache.httpcomponents',name:'httpmime',version:'4.3.6')\n</code>\n<h2>Usage</h2>\n<p>Inject smsService into your class</p>\n<p><code>def smsService</code></p>\n<p><em>smsService</em> is a Grails service that provides a method called send() that can take mapped parameters.\nPlease note that 'send()' is overloaded 'see http://en.wikipedia.org/wiki/Function_overloading' and can take various variations of parameters.</p>\n<br/>\nOne simple form is:\n<code>\nsend(Map map)\n</code>\n<p>Where ......</p>\n<p>map contains parameters...\nmap.to: phone number of recipient eg +1234444444</p>\n<p>map.from: your twilio assigned number eg. +09899898989</p>\n<p>map.body: "The body of your message"\nmap.mediaUrl: "Url for any attachment" (optional )</p>\n<h2>Example</h2>\n<p>An example usage can be seen below.</p>\n<code>\n<pre><code>Class YourController{\n \n def smsService\n ...\n def yourMethod(){\n def map = [to:"070987878787",from:"09808000000",body:"SMS BODY"]\n smsService.send(map)\n \n }\n\n}\n</code></pre>\n</code>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "vaadin", |
| "repo": "plugins", |
| "owner": "ondrej-kvasnovsky", |
| "desc": "Vaadin plugin for Grails.", |
| "labels": [ |
| "vaadin" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/ondrej-kvasnovsky/grails-vaadin-plugin", |
| "latestVersion": "2.0.3", |
| "updated": "2018-03-09T04:04:10.013Z", |
| "systemIds": [ |
| "com.vaadinongrails:grails-vaadin-plugin" |
| ], |
| "vcsUrl": "https://github.com/ondrej-kvasnovsky/grails-vaadin-plugin" |
| }, |
| "documentationUrl": "https://ondrej-kvasnovsky.github.io/grails-vaadin-plugin/", |
| "mavenMetadataUrl": null, |
| "readme": "<p>Welcome to the official source code repository of grails-vaadin plugin.</p>\n<p><a href=\"https://www.gitbook.io/book/ondrej-kvasnovsky/vaadin-on-grails\">Vaadin on Grails Book</a></p>\n<p><a href=\"http://vaadinongrails.com\">vaadinongrails.com</a></p>\n<p><a href=\"https://twitter.com/VaadinOnGrails\">Twitter @VaadinOnGrails</a></p>\n" |
| }, |
| { |
| "displayName": "json-views", |
| "bintrayPackage": { |
| "name": "grails-views", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Grails JSON Views", |
| "labels": [ |
| "json", |
| "rest", |
| "views" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/grails-views/issues", |
| "latestVersion": "3.2.3", |
| "updated": "2024-04-04T11:02:57.000Z", |
| "systemIds": [ |
| "org.grails.plugins:views-json" |
| ], |
| "vcsUrl": "https://github.com/grails/grails-views" |
| }, |
| "documentationUrl": "https://views.grails.org/latest/#_json_views", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/grails/plugins/views-json/maven-metadata.xml", |
| "readme": "<h1>Grails Views</h1>\n<p>Additional View Technologies for Grails 3.0 and above.</p>\n<p>Initial implementation includes JSON views powered by Groovy's JsonBuilder, however this project provides the basis for implementation other view types.</p>\n<p>View <a href=\"https://grails.github.io/grails-views/latest/\">the latest documentation</a> for details.</p>\n<p><a href=\"https://github.com/grails/grails-views/actions/workflows/gradle.yml\"><img src=\"https://github.com/grails/grails-views/actions/workflows/gradle.yml/badge.svg?branch=master\" alt=\"Java CI\" /></a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "x-frame-options-plugin", |
| "repo": "plugins", |
| "owner": "mrhaki", |
| "desc": "Servlet filter that adds a X-FRAME-OPTIONS response header", |
| "labels": [ |
| "security" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/mrhaki/grails-x-frame-options-plugin/issues", |
| "latestVersion": "1.1.0", |
| "updated": "2017-03-09T10:57:09.659Z", |
| "systemIds": [ |
| "org.grails.plugins:x-frame-options", |
| "org.grails.plugins:grails-x-frame-options-plugin" |
| ], |
| "vcsUrl": "https://github.com/mrhaki/grails-x-frame-options-plugin" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<div class=\"sect1\">\n<h2 id=\"_grails_x_frame_options_plugin\">Grails X-Frame-Options Plugin</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Filter to set HTTP response header X-Frame-Options to defend against\n<a href=\"http://en.wikipedia.org/wiki/Clickjacking\">ClickJacking</a>.</p>\n</div>\n<div class=\"paragraph\">\n<p>More information about using X-Frame-Options for defending against clickjacking:</p>\n</div>\n<div class=\"ulist\">\n<ul>\n<li>\n<p><a href=\"https://www.owasp.org/index.php/Clickjacking_Defense_Cheat_Sheet#Defending_with_X-Frame-Options_Response_Headers\">OWASP - Defending with X-Frame-Options response headers</a></p>\n</li>\n</ul>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_installation\">Installation</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>These instructions are targeted towards Grails 3 installations. For Grails 2.x refer to branch 1.x of the plugin.</p>\n</div>\n<div class=\"paragraph\">\n<p>Add a dependency to <code>build.gradle</code>:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre>...\ndependencies {\n ...\n runtime ('org.grails.plugins:x-frame-options:1.1.2')\n ...\n}\n...</pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>The default configuration installs a servlet filter for the URL pattern <code>/*</code> that adds a response\nheader <code>X-Frame-Options</code> with the value <code>DENY</code>.</p>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_configuration\">Configuration</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>The plugin is configured through <code>grails-app/conf/application.yml</code>.</p>\n</div>\n<div class=\"paragraph\">\n<p>We can limit the URL pattern the filter is applied to:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre>grails:\n plugin:\n xframeoptions:\n urlPattern: /path/*</pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>We can also set multiple patterns:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre>grails:\n plugin:\n xframeoptions:\n urlPattern:\n - /path/*\n - /other/*</pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>We can set different header values based on the configuration.\nTo set the header value <code>DENY</code> we must use the following configuration:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre>grails:\n plugin:\n xframeoptions:\n deny: true</pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>This is also the default value if no configuration is provided or no configuration options\nare set.</p>\n</div>\n<div class=\"paragraph\">\n<p>To set the header value <code>SAMEORIGIN</code> we must use the following configuration:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre>grails:\n plugin:\n xframeoptions:\n sameOrigin: true</pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>To set the header value <code>ALLOW-FROM</code> with a URL we must use the following configuration:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre>grails:\n plugin:\n xframeoptions:\n allowFrom: http://www.mrhaki.com</pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>To disable the filter we must use the following configuration option:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre>grails:\n plugin:\n xframeoptions:\n enabled: false</pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>The filter is enabled by default and will use the <code>DENY</code> header value.</p>\n</div>\n</div>\n</div>" |
| }, |
| { |
| "deprecated": "Since version 3.2.1, Grails has built-in CORS support.", |
| "bintrayPackage": { |
| "name": "cors-interceptor", |
| "repo": "maven", |
| "owner": "appcela", |
| "desc": "Add Cross-Origin Resource Sharing (CORS) headers for Grails 3 applications.", |
| "labels": [ |
| "cors" |
| ], |
| "licenses": [ |
| "MIT" |
| ], |
| "issueTrackerUrl": "https://github.com/appcela/grails3-cors-interceptor/issues", |
| "latestVersion": "1.2.1", |
| "updated": "2017-11-07T07:26:53.951Z", |
| "systemIds": [ |
| "org.grails.plugins:grails3-cors-interceptor" |
| ], |
| "vcsUrl": "https://github.com/appcela/grails3-cors-interceptor" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>grails3-cors-interceptor</h1>\n<p>Add Cross-Origin Resource Sharing (CORS) headers for Grails 3 applications.</p>\n<h1>Grails 3.2.2+</h1>\n<p>For Grails 3.2.2+, please use the Grails built-in <a href=\"http://docs.grails.org/latest/guide/theWebLayer.html#cors\">CORS support</a>, you no longer need this plugin.</p>\n<h1>Grails 3.0.x - 3.2.1 Only</h1>\n<p>This plugin will add a new Interceptor (see <a href=\"https://grails.github.io/grails-doc/latest/guide/single.html#interceptors\">Grails 3 Interceptor API</a>) to your Grails app that adds CORS headers to all your controllers and actions.</p>\n<p>This plugin has only been tested with Grails 3.0., 3.0.15, 3.1.4 and 3.2.0, 3.2.1</p>\n<ul>\n<li>for Grails 3.1.4+, please use version <code>1.2.1</code></li>\n<li>for Grails 3.0.15+, please use version <code>0.1.5</code></li>\n<li>for Grails 3.0.4 - 3.0.14, please use version <code>0.1.2</code></li>\n</ul>\n<h1>Grails 2.x</h1>\n<p>For Grails 2.x app, please use the execellent <a href=\"https://github.com/davidtinker/grails-cors\">CORS Plugin</a>. In fact, this plugin is based on the Grails 3 servlet filter code provided in the README by that plugin author. The filter code is rewritten as interceptor for this plugin.</p>\n<h1>Usage</h1>\n<h2>1. Add Plugin Dependency</h2>\n<p>Add the following dependency to your Grails app,</p>\n<p><em>build.gradle</em></p>\n<pre><code>compile "org.grails.plugins:grails3-cors-interceptor:1.2.1"\n</code></pre>\n<h2>2. (Optional) Add HTTP OPTIONS Method URL Mapping</h2>\n<p><strong>For Grails 3.1.4+, this step is no longer needed. Please skip it.</strong></p>\n<p>To support the preflight CORS request with HTTP OPTIONS method, url mappings for OPTIONS method must be added explicitly.</p>\n<p><em>UrlMappings.groovy</em></p>\n<pre><code>"/books"(resources:'book') // mapping to REST resource "book"\n"/books/$id?"(controller:'book', method: 'OPTIONS') // explicitly map OPTIONS method to "book" REST controller\n</code></pre>\n<h2>3. (Optional) Configuration Settings</h2>\n<p><em>application.yml</em></p>\n<pre><code>corsInterceptor:\n includeEnvironments: ['development', 'test']\n excludeEnvironments: ['production']\n allowedOrigins: ['yourhost.com']\n allowedHeaders: ['my-authorization-header', 'origin', 'content-type', 'accept']\n</code></pre>\n<ul>\n<li>includeEnvironments - include this plugin only in the environments listed (default to all environments)</li>\n<li>excludeEnvironments - exclude this plugin from the environments listed (default to null)</li>\n<li>allowedOrigins - white list for allowed origins (default to all origins without restrictions)</li>\n<li>allowedHeaders - custom headers to be used in "Access-Control-Allow-Headers" (default to <code>["origin", "authorization", "accept", "content-type", "x-requested-with"]</code>)</li>\n</ul>\n<h1>Working with Spring Security Core or Spring Security REST Plugins</h1>\n<p>See the sample app <a href=\"https://github.com/appcela/grails3-cors-interceptor-spring-security-rest-sample-app\">grails3-cors-interceptor-spring-security-rest-sample-app</a> for detailed\ninstructions on how to get <code>grails3-cors-interceptor</code> working with <a href=\"https://grails-plugins.github.io/grails-spring-security-core/v3/index.html\">Spring Security Core</a> or <a href=\"http://alvarosanchez.github.io/grails-spring-security-rest/2.0.0.M2/docs/index.html\">Spring Security REST plugin</a>.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "uploadr", |
| "repo": "plugins", |
| "owner": "pankajtandon", |
| "desc": "Plugin to upload multiple files from a web page. Uses HTML5 and CSS3", |
| "labels": [ |
| "upload" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/pankajtandon/grails3-uploadr/issues", |
| "latestVersion": "3.1.0", |
| "updated": "2016-06-11T13:54:37.345Z", |
| "systemIds": [ |
| "com.nayidisha.grails.uploadr:grails3-uploadr" |
| ], |
| "vcsUrl": "https://github.com/pankajtandon/grails3-uploadr" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>HTML5 and CSS3 based File Uploader</h1>\n<h2>About</h2>\n<p>Grails 3 is based on Spring-Boot and plugins written pre-Grails 3 have to be "re-structured" or re-configured for Grails 3.</p>\n<p>This is an upgrade to grails 3.x of the excellent plugin written by Dustin Clark <a href=\"https://github.com/dustindclark/grails-uploadr/blob/master/README.md\">here</a></p>\n<h2>Usage</h2>\n<p>In the project that you would like to use the uploadr plugin, include the following in its build.gradle.</p>\n<pre>\nbuildscript {\n...\n dependencies {\n classpath 'com.bertramlabs.plugins:asset-pipeline-gradle:2.5.0'\n ...\n }\n}\n</pre>\n<p>and</p>\n<pre>\ndependencies {\n ...\n compile \"com.nayidisha.grails.uploadr:grails3-uploadr:3.0\"\n...\n}\n</pre>\n<p>Then in a gsp where the uploadr needs to be installed:</p>\n<pre><code><!DOCTYPE HTML>\n<html>\n<head>\n ...\n <asset:javascript src="uploadr.manifest.js"/>\n <asset:javascript src="uploadr.demo.manifest.js"/>\n <asset:stylesheet href="uploadr.manifest.css"/>\n <asset:stylesheet href="uploadr.demo.manifest.css"/>\n ...\n</head>\n<body>\n ...\n <uploadr:demo/>\n ...\n</body>\n</html>\n</code></pre>\n<h2>Images</h2>\n<p>When your gsp is configured with a tag like so:</p>\n<pre><code><uploadr:add name="aFileToUpload.png" path="/somewhereOnYourFS" maxSize="52428800" />\n</code></pre>\n<p>Here is how a single file upload looks:</p>\n<p><img src=\"uploadbefore.png\" alt=\"uploadImage\" /></p>\n<p>and after upload...</p>\n<p><img src=\"upload.png\" alt=\"uploadImage\" /></p>\n<h2>ToDo</h2>\n<ul>\n<li>i18n is still not working correctly, so all messages have been hardcoded in English.</li>\n</ul>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "gravatar", |
| "repo": "plugins", |
| "owner": "rpalcolea", |
| "desc": "Grails plugin for displaying avatars from Gravatar", |
| "labels": [ |
| "gravatar", |
| "image" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/rpalcolea/grails-gravatar/issues", |
| "latestVersion": "1.0.2", |
| "updated": "2016-09-04T02:11:13.186Z", |
| "systemIds": [ |
| "rpalcolea.gravatar:gravatar" |
| ], |
| "vcsUrl": "https://github.com/rpalcolea/grails-gravatar" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails Gravatar Plugin</h1>\n<p><a href=\"https://travis-ci.org/rpalcolea/grails-gravatar\"><img src=\"https://travis-ci.org/rpalcolea/grails-gravatar.svg?branch=master\" alt=\"Build Status\" /></a>\n<a href=\"https://bintray.com/rpalcolea/plugins/gravatar/_latestVersion\"><img src=\"https://api.bintray.com/packages/rpalcolea/plugins/gravatar/images/download.svg\" alt=\"Download\" /></a>\n<a href=\"http://slack-signup.grails.org\"><img src=\"http://slack-signup.grails.org/badge.svg\" alt=\"Slack Signup\" /></a></p>\n<p>This plugin provides a taglib for displaying gravatars.</p>\n<p>Gravatars allow users to configure an avatar to go with their email address at a central location: gravatar.com. Gravatar-aware websites can then look up and display each user\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffds preferred avatar, without having to handle avatar management. The user gets the benefit of not having to set up an avatar for each site that they post on.</p>\n<h2>Installation</h2>\n<p>Add the following dependencies in <code>build.gradle</code></p>\n<pre><code class=\"language-groovy\">dependencies {\n...\n compile 'rpalcolea.gravatar:gravatar:1.0.2'\n...\n}\n</code></pre>\n<h2>Configuration</h2>\n<p>You can modify the default rating and defaultImage in your application.yml as follows</p>\n<pre><code class=\"language-yml\">gravatar:\n defaultRating: g #Optional (default is g)\n defaultGravatarUrl: http://docs.grails.org/latest/img/grails.png #optional\n</code></pre>\n<h2>Usage</h2>\n<p>###TagLib\nUsing the taglib is simple:</p>\n<pre><code class=\"language-gsp\"><gravatar:image email="roberto@perezalcolea.info"/>\n</code></pre>\n<p>This will output</p>\n<pre><code class=\"language-html\"><img id="" name="" alt="Gravatar" class="gravatar" height="80" width="80" src="https://www.gravatar.com/avatar/ae03f5244dfbbd216864590baacfd130?s=80&r=g" title="gravatar"/>\n</code></pre>\n<p>You can provide the following arguments to the TagLib:</p>\n<pre><code class=\"language-groovy\"> /**\n * @attr email REQUIRED\tthe startDate for styling\n * @attr size the disired dimensions in pixels for the gravatar image (from 1 up to 512)\n * @attr alt alt-attribute for the resulting img-element\n * @attr cssClass class-attribute for the resulting img-element\n * @attr title title-attribute for the resulting img-element\n * @attr id id-attribute for the resulting img-element\n * @attr name name-attribute for the resulting img-element\n * @attr defaultGravatarUrl the default image to display if no gravatar is found; may be a URL or one of the following (defaults to the official Gravatar logo):\n * \t\t\t\t\t\t\t\t<li>404: do not load any image if none is associated with the email hash, instead return an HTTP 404 (File Not Found) response\n * \t\t\t\t\t\t\t\t<li>mm: (mystery-man) a simple, cartoon-style silhouetted outline of a person (does not vary by email hash)\n * \t\t\t\t\t\t\t\t<li>identicon: a geometric pattern based on an email hash\n * \t\t\t\t\t\t\t\t<li>monsterid: a generated 'monster' with different colors, faces, etc\n * \t\t\t\t\t\t\t\t<li>wavatar: generated faces with differing features and backgrounds\n * \t\t\t\t\t\t\t\t<li>retro: awesome generated, 8-bit arcade-style pixelated faces\n * @attr gravatarRating desired image rating censor-level; may be one of the following:\n * \t\t\t\t\t\t\t\t<li>g (default): suitable for display on all websites with any audience type.\n * \t\t\t\t\t\t\t\t<li>pg: may contain rude gestures, provocatively dressed individuals, the lesser swear words, or mild violence.\n * \t\t\t\t\t\t\t\t<li>r: may contain such things as harsh profanity, intense violence, nudity, or hard drug use.\n * \t\t\t\t\t\t\t\t<li>x: may contain hardcore sexual imagery or extremely disturbing violence.\n */\n</code></pre>\n<p>###GravatarUrlGenerator\nIf you want to generate links without the use of the taglib, you can accomplish it by using <code>GravatarUrlGenerator</code> as follows:</p>\n<pre><code class=\"language-groovy\">GravatarUrlGenerator.generateUrl('roberto@perezalcolea.info')\n</code></pre>\n<p>This will output</p>\n<pre><code>https://www.gravatar.com/avatar/ae03f5244dfbbd216864590baacfd130?s=80&r=g\n</code></pre>\n<p>You can provide the following arguments:</p>\n<pre><code class=\"language-groovy\"> GravatarRating rating\n Integer size\n String defaultImage\n</code></pre>\n<h2>Acknowledgements</h2>\n<p>This plugin contains original code and the ideas from the <a href=\"https://github.com/domix/avatarplugin\">Avatar Plugin</a> for Grails <code>1.x</code> by Domingo Suarez Torres (@domix)</p>\n<h2>License</h2>\n<p>Apache 2</p>\n<h2>Sponsors</h2>\n<p><a href=\"https://www.yourkit.com/.net/profiler/index.jsp\"><img src=\"https://www.yourkit.com/images/yklogo.png\" alt=\"Alt text\" title=\"YourKit\" /></a></p>\n<p>YourKit supports open source projects with its full-featured Java Profiler.\nYourKit, LLC is the creator of <a href=\"https://www.yourkit.com/java/profiler/index.jsp\">YourKit Java Profiler</a>\nand <a href=\"https://www.yourkit.com/.net/profiler/index.jsp\">YourKit .NET Profiler</a>,\ninnovative and intelligent tools for profiling Java and .NET applications.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "greenmail", |
| "repo": "plugins", |
| "owner": "gpc", |
| "desc": "Grails GreenMail Plugin", |
| "labels": [ |
| "testing", |
| "mail" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/gpc/greenmail/issues", |
| "latestVersion": "2.0.0.RC3", |
| "updated": "2021-02-24T01:09:42.561Z", |
| "systemIds": [ |
| "org.grails.plugins:greenmail" |
| ], |
| "vcsUrl": "https://github.com/gpc/greenmail" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Greenmail Plugin for Grails 3</h1>\n<p>This is a fork of grails greenmail plugin for grails 3.</p>\n<h2>INSTALL</h2>\n<p>Add a dependency for the plugin in <code>build.gradle</code>:</p>\n<pre><code>\ndependencies { \n compile 'org.grails.plugins:greenmail:2.0.0.RC2' \n}\n\n</code></pre>\n<h2>USAGE</h2>\n<p>Provides a wrapper around <a href=\"http://www.icegreen.com/greenmail/\">GreenMail</a> and provides a view that displays <code>sent</code> messages - useful for testing application in the <code>development</code> or <code>test</code> environments.</p>\n<h3>Installation</h3>\n<pre><code>grails install-plugin greenmail\n</code></pre>\n<p>The plugin assumes that you have some sort of Java mail provider installed (for instance the Grails mail plugin). You need to define a SMTP port for the mock Greenmail SMTP server to start with. Using the Grails Mail plugin, this is as simple as defining the <code>grails.mail.port</code> property in <code>Config.groovy</code>, like this (see the first line in the <code>development</code> and <code>test</code> blocks):</p>\n<pre><code>environments {\n production {\n grails.serverURL = "http://www.changeme.com"\n }\n development {\n\tgrails.mail.port = com.icegreen.greenmail.util.ServerSetupTest.SMTP.port\n grails.serverURL = "http://localhost:8080/${appName}"\n }\n test {\n\tgrails.mail.port = com.icegreen.greenmail.util.ServerSetupTest.SMTP.port\n grails.serverURL = "http://localhost:8080/${appName}"\n }\n}\n</code></pre>\n<p>You can also completely disable the plugin by using the config setting <code>grails.plugin.greenmail.disabled = true</code>. For example, to disable greenmail in production:</p>\n<pre><code>environments {\n production {\n grails.plugin.greenmail.disabled=true\n }\n}\n</code></pre>\n<p>If you need to change the default listening port (1025) you can use the <code>grails.plugin.greenmail.ports.smtp</code> configuration variable. For example:</p>\n<pre><code>environments {\n test {\n grails.plugin.greenmail.ports.smtp = 2025\n }\n}\n</code></pre>\n<h3>Usage in Integration Tests</h3>\n<p>The plugin can be used to capture email messages during integration tests. For example:</p>\n<pre><code>import com.icegreen.greenmail.util.*\n\nclass GreenmailTests extends GroovyTestCase {\n def mailService\n def greenMail\n\n void testSendMail() {\n Map mail = [message:'hello world', from:'from@piragua.com', to:'to@piragua.com', subject:'subject']\n\n mailService.sendMail {\n to mail.to\n from mail.from\n subject mail.subject\n body mail.message\n }\n \n assertEquals(1, greenMail.getReceivedMessages().length)\n\t\n def message = greenMail.getReceivedMessages()[0]\n\t\t\n assertEquals(mail.message, GreenMailUtil.getBody(message))\n assertEquals(mail.from, GreenMailUtil.getAddressList(message.from))\n assertEquals(mail.subject, message.subject)\n }\n\n void tearDown() {\n greenMail.deleteAllMessages()\n }\n}\n</code></pre>\n<p>The plugin adds a <code>deleteAllMessages()</code> convenience method to the <code>greenMail</code> bean that deletes all received messages.</p>\n<h3>Usage in running application</h3>\n<p>The plugin provides a controller and view to show messages that are <code>sent</code> from the application. Simply browse to http://localhost:8080/greenmail and it will show a list of messages sent. You can click on the <code>show</code> link to view the raw message.</p>\n<h3>Roadmap</h3>\n<p>This is a fully functional plugin, though there are some features that I think would be worth adding. Contributions and patches are welcome!</p>\n<ul>\n<li>Messages sent by the Grails Mail plugin have duplicate "TO:" fields in the raw message and in the address list, for instance if the recipient is spam@piragua.com, then that email address is listed twice when you retrieve the address list for RecipientType.TO (e.g. GreenMailUtil.getAddressList(message.getRecipients(javax.mail.Message.RecipientType.TO))</li>\n<li>Ability to view HTML email messages as they appear in a mail client rather than as RAW message.</li>\n</ul>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "gsp", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Grails Server Pages (GSP) - GSP (Grails Server Pages) - A server-side view rendering technology based on Groovy", |
| "labels": [ |
| "views" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/grails-gsp/issues", |
| "latestVersion": "6.2.4", |
| "updated": "2024-11-19T22:48:43.000Z", |
| "systemIds": [ |
| "org.grails.plugins:gsp" |
| ], |
| "vcsUrl": "https://github.com/grails/grails-gsp" |
| }, |
| "documentationUrl": "https://gsp.grails.org/latest/guide/index.html", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/grails/plugins/gsp/maven-metadata.xml", |
| "readme": "<div id=\"preamble\">\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>This project contains the sources for GSP, the server-side view rendering technology used in <a href=\"http://grails.org\">Grails</a>.</p>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_documentation\">Documentation</h2>\n<div class=\"sectionbody\">\n<div class=\"ulist\">\n<ul>\n<li>\n<p>Latest - <a href=\"http://gsp.grails.org\" class=\"bare\">http://gsp.grails.org</a></p>\n</li>\n<li>\n<p>Latest - <a href=\"http://gsp.grails.org/latest/api\" class=\"bare\">http://gsp.grails.org/latest/api</a></p>\n</li>\n<li>\n<p>Snapshot Guide - <a href=\"http://gsp.grails.org/snapshot\" class=\"bare\">http://gsp.grails.org/snapshot</a></p>\n</li>\n<li>\n<p>Snapshot API - <a href=\"http://gsp.grails.org/snapshot\" class=\"bare\">http://gsp.grails.org/snapshot</a></p>\n</li>\n</ul>\n</div>\n</div>\n</div>" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "handlebars-asset-pipeline", |
| "repo": "asset-pipeline", |
| "owner": "bertramlabs", |
| "desc": "Provides native Handlebars file support in the asset-pipeline. Easily convert .hbs or .handlebars files into javascript template caches for use with the handlebars runtime.", |
| "labels": [ |
| "asset-pipeline", |
| "handlebars" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/bertramdev/asset-pipeline/issues", |
| "latestVersion": "5.0.9", |
| "updated": "2025-04-13T23:20:10.000Z", |
| "systemIds": [ |
| "com.bertramlabs.plugins:handlebars-asset-pipeline" |
| ], |
| "vcsUrl": "https://github.com/bertramdev/asset-pipeline" |
| }, |
| "documentationUrl": "https://bertramdev.github.io/asset-pipeline/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/com/bertramlabs/plugins/handlebars-asset-pipeline/maven-metadata.xml", |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "handlebars-renderer", |
| "repo": "plugins", |
| "owner": "salex772", |
| "desc": "Grails handlebars templates renderer plugin", |
| "labels": [ |
| "handlebars" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/salex772/handlebars-renderer/issues", |
| "latestVersion": "0.1.2", |
| "updated": "2016-05-30T14:11:29.543Z", |
| "systemIds": [ |
| "org.grails.plugins:handlebars-renderer" |
| ], |
| "vcsUrl": "https://github.com/salex772/handlebars-renderer" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails handlebars templates renderer plugin</h1>\n<p>This plugin is for Grails 3 and this is a fork of https://github.com/davidtinker/grails-handlebars</p>\n<h3>Install</h3>\n<p>Add to build.gradle</p>\n<pre><code>dependencies {\n compile "org.grails.plugins:handlebars-renderer:0.1.2"\n}\n</code></pre>\n<h3>Config</h3>\n<pre><code>grails.handlebars.templatesRoot = 'templates'\ngrails.handlebars.templateExtension = '.hbs'\ngrails.handlebars.templatesPathSeparator = '/'\n</code></pre>\n<h3>Usage</h3>\n<p>In controller:</p>\n<pre><code>def data = [\n\tname : 'alex',\n]\n\n//income.hbs must under path /src/main/webapps/templates/mailbox\nrender handlebarsService.apply("mailbox/income", data)\n</code></pre>\n<p>In GSP template:</p>\n<pre><code><handlebars:render template="mailbox/income" model="${data}"/>\n</code></pre>\n<p>or</p>\n<pre><code><handlebars:render>\n Hello {{name}} from the controller\n</handlebars:render>\n</code></pre>\n<p>Please read complete documentation at https://github.com/davidtinker/grails-handlebars</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "hazelcast", |
| "repo": "grails-plugins", |
| "owner": "budjb", |
| "desc": "Grails hazelcast plugin", |
| "labels": [ |
| "hazelcast" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/budjb/grails-hazelcast/issues", |
| "latestVersion": "1.1.1", |
| "updated": "2018-07-19T20:30:23.897Z", |
| "systemIds": [ |
| "org.grails.plugins:hazelcast" |
| ], |
| "vcsUrl": "https://github.com/budjb/grails-hazelcast" |
| }, |
| "documentationUrl": "https://budjb.github.io/grails-hazelcast/latest/", |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/budjb/grails-hazelcast\"><img src=\"http://img.shields.io/travis/budjb/grails-hazelcast.svg?branch=master\" alt=\"Build Status\" /></a>\n<a href=\"http://www.apache.org/licenses/LICENSE-2.0.html\"><img src=\"http://img.shields.io/:license-apache-blue.svg\" alt=\"License\" /></a></p>\n<h1>Grails Hazelcast Plugin</h1>\n<p>See the documentation at <a href=\"https://budjb.github.io/grails-hazelcast/latest\">https://budjb.github.io/grails-hazelcast/latest</a>.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "hazelgrails", |
| "repo": "plugins", |
| "owner": "enesakar", |
| "desc": "Hazelcast Grails Integration", |
| "labels": [ |
| "hazelcast" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/enesakar/hazelgrails/issues", |
| "latestVersion": "1.0.2", |
| "updated": "2016-04-18T13:39:17.430Z", |
| "systemIds": [ |
| "org.grails.plugins:hazelgrails" |
| ], |
| "vcsUrl": "https://github.com/enesakar/hazelgrails" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Hazelcast plugin for grails</h1>\n<p>Update (4/2016): Hazelcast version is upgraded to 3.6.2.</p>\n<h3>How to Install Plugin</h3>\n<p>Just add the following dependency under the dependencies block in your project's build.gradle:</p>\n<blockquote>\n<p>compile "org.grails.plugins:hazelgrails:1.0.2"</p>\n</blockquote>\n<h3>Configuration</h3>\n<p>You can configure hazelcast in details:</p>\n<p>For available options have a look at:\n<a href=\"http://docs.hazelcast.org/docs/3.6/manual/html-single/index.html#hazelcast-configuration\">http://docs.hazelcast.org/docs/3.6/manual/html-single/index.html#hazelcast-configuration</a></p>\n<p>To use Hazelcast as Hibernate 2nd Level Cache, add the following line to application.groovy:</p>\n<p>cache.region.factory_class = 'com.hazelcast.hibernate.HazelcastCacheRegionFactory'</p>\n<h3>For more documentation:</h3>\n<p>See:\n<a href=\"http://blog.hazelcast.com/distribute-grails-with-hazelcast/\">http://blog.hazelcast.com/distribute-grails-with-hazelcast/</a></p>\n<h3>For Grails3 Test application:</h3>\n<p>See:\n[https://github.com/rohitbishnoi/hazelcast-test] (https://github.com/rohitbishnoi/hazelcast-test)</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "hibernate", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "GORM - Grails Data Access Framework", |
| "labels": [ |
| "database", |
| "gorm", |
| "hibernate", |
| "rdms" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/grails-data-mapping/issues", |
| "latestVersion": "4.3.10.7", |
| "updated": "2016-10-03T14:41:45.128Z", |
| "systemIds": [ |
| "org.grails.plugins:hibernate" |
| ], |
| "vcsUrl": "https://github.com/grails/grails-data-mapping" |
| }, |
| "documentationUrl": "https://grails.github.io/grails-data-mapping/", |
| "mavenMetadataUrl": null, |
| "readme": "<p><img src=\"https://github.com/grails/grails-data-mapping/workflows/Java%20CI/badge.svg?branch=master\" alt=\"Java CI\" />\n<img src=\"https://github.com/grails/grails-data-mapping/workflows/Release/badge.svg?branch=master\" alt=\"Release\" />\n<img src=\"https://github.com/grails/grails-data-mapping/workflows/Maven%20Central%20Sync/badge.svg?branch=master\" alt=\"Maven Central Sync\" /></p>\n<h1>GORM (Grails Object Mapping)</h1>\n<p>[Grails][Grails] is a framework used to build web applications with the [Groovy][Groovy] programming language. This project provides the plumbings for the GORM API both for Hibernate and for new implementations of GORM ontop of NoSQL datastores.\n[Grails]: http://grails.org/\n[Groovy]: http://groovy-lang.org/</p>\n<h2>Getting Started</h2>\n<p>For further information see the dedicated websites:</p>\n<ul>\n<li><a href=\"http://gorm.grails.org/\">Stable Version</a>.</li>\n<li><a href=\"http://gorm.grails.org/snapshot/\">Development Version</a>.</li>\n</ul>\n<h2>License</h2>\n<p>Grails and Groovy are licensed under the terms of the [Apache License, Version 2.0][Apache License, Version 2.0].\n[Apache License, Version 2.0]: http://www.apache.org/licenses/LICENSE-2.0.html</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "hibernate-search", |
| "repo": "plugins", |
| "owner": "lgrignon", |
| "desc": "This plugin aims to integrate Hibernate Search features to Grails in very few steps.", |
| "labels": [ |
| "search", |
| "hibernate" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/mathpere/grails-hibernate-search-plugin/issues", |
| "latestVersion": "2.4.0", |
| "updated": "2020-04-10T16:57:56.220Z", |
| "systemIds": [ |
| "org.grails.plugins:hibernate-search" |
| ], |
| "vcsUrl": "https://github.com/mathpere/grails-hibernate-search-plugin" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails Hibernate Search Plugin</h1>\n<p>This plugin aims to integrate Hibernate Search features to Grails in very few steps.</p>\n<ul>\n<li><a href=\"#grails-hibernate-search-plugin\">Grails Hibernate Search Plugin</a>\n<ul>\n<li><a href=\"#getting-started\">Getting started</a></li>\n<li><a href=\"#configuration\">Configuration</a></li>\n<li><a href=\"#indexing\">Indexing</a>\n<ul>\n<li><a href=\"#mark-your-domain-classes-as-indexable\">Indexing Domain Class</a></li>\n<li><a href=\"#indexing-the-data\">Indexing the Data</a></li>\n</ul>\n</li>\n<li><a href=\"#search\">Search</a>\n<ul>\n<li><a href=\"#retrieving-the-results\">Retrieving search results</a></li>\n<li><a href=\"#mixing-with-criteria-query\">Mixing with criteria query</a></li>\n<li><a href=\"#performing-simplequerystring-searches\">Performing SimpleQueryString Searches</a></li>\n<li><a href=\"#sorting-the-results\">Sorting results</a></li>\n<li><a href=\"#counting-the-results\">Counting results</a></li>\n<li><a href=\"#additional-features\">Additional features</a></li>\n</ul>\n</li>\n<li><a href=\"#analysis\">Analysis</a>\n<ul>\n<li><a href=\"#define-named-analyzers\">Defining Analyzers</a></li>\n<li><a href=\"#use-named-analyzers\">Using Defined Analyzers</a></li>\n</ul>\n</li>\n<li><a href=\"#normalizer\">Normalizer</a>\n<ul>\n<li><a href=\"#define-named-normalizers\">Defining Normalizers</a></li>\n<li><a href=\"#use-named-normalizer\">Using Defined Normalizers</a></li>\n</ul>\n</li>\n<li><a href=\"#filters\">Filters</a>\n<ul>\n<li><a href=\"#define-named-filters\">Defining Filters</a></li>\n<li><a href=\"#filter-query-results\">Using Defined Filters</a></li>\n</ul>\n</li>\n<li><a href=\"#options\">Options</a></li>\n<li><a href=\"#notes\">Notes</a>\n<ul>\n<li><a href=\"#updating-from-2.2-to-2.3\">Updating from 2.2 to 2.3</a></li>\n<li><a href=\"#runtime.groovy-vs-application.groovy\">runtime.groovy vs application.groovy</a></li>\n<li><a href=\"#ide-integration\">IDE Integration</a></li>\n<li><a href=\"#sessionfactory-failures-during-startup\">SessionFactory failures during startup</a></li>\n</ul>\n</li>\n<li><a href=\"#examples\">Examples</a></li>\n<li><a href=\"#change-log\">Change log</a></li>\n<li><a href=\"#authors\">Authors</a></li>\n<li><a href=\"#development-contribution\">Development / Contribution</a></li>\n<li><a href=\"#license\">License</a></li>\n</ul>\n</li>\n</ul>\n<h2>Getting started</h2>\n<p>If you don't want to start from the <a href=\"#examples\">template project</a>, you could start a fresh project:</p>\n<p>And add the following to your dependencies</p>\n<pre><code> compile("org.grails.plugins:hibernate-search:2.3.0")\n compile("org.grails.plugins:hibernate5:6.1.8")\n compile("org.grails.plugins:cache")\n compile("org.hibernate:hibernate-core:5.2.10.Final")\n compile("org.hibernate:hibernate-ehcache:5.2.10.Final")\n</code></pre>\n<h2>Configuration</h2>\n<p>By default, the plugin stores your indexes in this directory:</p>\n<pre><code> ~/.grails/${grailsVersion}/projects/${yourProjectName}/lucene-index/development/\n</code></pre>\n<p>You can override this configuration in your application.yml</p>\n<pre><code class=\"language-yml\">hibernate:\n cache:\n use_second_level_cache: true\n use_query_cache: true\n provider_class: net.sf.ehcache.hibernate.EhCacheProvider\n region:\n factory_class: org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory\n search:\n default:\n \tindexBase: '/path/to/your/indexes'\n indexmanager: near-real-time\n directory_provider: filesystem\n</code></pre>\n<p>You can also define the path to your indexes with JNDI configuration as following:</p>\n<pre><code class=\"language-yml\">hibernate:\n cache:\n use_second_level_cache: true\n use_query_cache: true\n provider_class: net.sf.ehcache.hibernate.EhCacheProvider\n region:\n factory_class: org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory\n search:\n default:\n indexBaseJndiName: 'java:comp/env/luceneIndexBase'\n directory_provider: filesystem\n</code></pre>\n<h2>Indexing</h2>\n<h3>Mark your domain classes as indexable</h3>\n<p>Add a static <code>lucenceIndexing</code> closure as following:</p>\n<p><strong>Note</strong>: You can use properties from super class and traits with no additional configuration (since 2.0.2)</p>\n<pre><code class=\"language-groovy\">class MyDomainClass {\n\n String author\n String body\n Date publishedDate\n String summary\n String title\n Status status\n Double price\n Integer someInteger\n\n enum Status {\n DISABLED, PENDING, ENABLED\n }\n\n static hasMany = [categories: Category, items: Item]\n\n static luceneIndexing = {\n // fields\n author index: 'yes'\n body termVector: 'with_positions'\n publishedDate date: 'day'\n summary boost: 5.9\n title index: 'yes', sortable: [name: title_sort, normalizer: LowerCaseFilterFactory]\n status index: 'yes', sortable: true\n categories indexEmbedded: true\n items indexEmbedded: [depth: 2] // configure the depth indexing\n price numeric: 2, analyze: false\n someInteger index: 'yes', bridge: ['class': PaddedIntegerBridge, params: ['padding': 10]]\n\n // support for classBridge\n classBridge = ['class': MyClassBridge, params: [myParam: "4"]]\n }\n\n}\n</code></pre>\n<p>This static property indicates which fields should be indexed and describes how the field has to be indexed.</p>\n<p>Also, the plugin lets you to mark your domain classes as indexable with the Hibernate Search annotations.</p>\n<pre><code class=\"language-groovy\">@Indexed\n@ClassBridge(\n impl = MyClassBridge,\n params = @Parameter( name="myParam", value="4" ) )\nclass MyDomainClass {\n\n // when using annotations, id is required to define DocumentId\n @DocumentId\n Long id\n\n @Field(index=Index.YES)\n String author\n\n @Field(index=Index.YES)\n String body\n\n @Field\n @DateBridge(resolution=Resolution.DAY)\n Date publishedDate\n\n @Field(index=Index.YES)\n String summary\n\n @Field(index=Index.YES)\n @Field(name="title_sort", normalizer=@Normalizer(impl=LowerCaseFilterFactory))\n @SortableField(forField="title_sort")\n String title\n\n @Field(index=Index.YES)\n @SortableField\n Status status\n\n @Field\n @NumericField( precisionStep = 2)\n Double price\n\n @Field(index=Index.YES)\n @FieldBridge(impl = PaddedIntegerBridge.class, params = @Parameter(name="padding", value="10"))\n Integer someInteger\n\n enum Status {\n DISABLED, PENDING, ENABLED\n }\n\n @IndexedEmbedded\n Set categories\n\n @IndexedEmbedded(depth = 2)\n Set items\n\n static hasMany = [categories: Category, items: Item]\n\n}\n</code></pre>\n<h3>Indexing the data</h3>\n<h4>Create index for existing data</h4>\n<p>The plugin lets you to create index of any indexed entity as following:</p>\n<pre><code class=\"language-groovy\">MyDomainClass.search().createIndexAndWait()\n</code></pre>\n<p>This method relies on MassIndexer and can be configured like this:</p>\n<pre><code class=\"language-groovy\">\nMyDomainClass.search().createIndexAndWait {\n ...\n batchSizeToLoadObjects 25\n cacheMode org.hibernate.CacheMode.NORMAL\n threadsToLoadObjects 5\n ...\n}\n\n#### Manual index changes\n\n##### Adding instances to index\n\n```groovy\n\n// index only updated at commit time\nMyDomainClass.search().withTransaction { transaction ->\n MyDomainClass.findAll().each {\n it.search().index()\n }\n}\n</code></pre>\n<h4>Deleting instances from index</h4>\n<pre><code class=\"language-groovy\">\n// index only updated at commit time\nMyDomainClass.search().withTransaction { transaction ->\n\n MyDomainClass.get(3).search().purge()\n\n}\n</code></pre>\n<p>To remove all entities of a given type, you could use the following purgeAll method:</p>\n<pre><code class=\"language-groovy\">\n// index only updated at commit time\nMyDomainClass.search().withTransaction {\n MyDomainClass.search().purgeAll()\n}\n</code></pre>\n<h4>Rebuild index on start</h4>\n<p>Hibernate Search offers an option to rebuild the whole index using the MassIndexer API. This plugin provides a configuration which lets you to rebuild automatically your indexes on startup.</p>\n<p>To use the default options of the MassIndexer API, simply provide this option into your runtime.groovy:</p>\n<pre><code class=\"language-groovy\">\n\ngrails.plugins.hibernatesearch = {\n rebuildIndexOnStart true\n}\n\n</code></pre>\n<p>If you need to tune the MassIndexer API, you could specify options with a closure as following:</p>\n<pre><code class=\"language-groovy\">\ngrails.plugins.hibernatesearch = {\n\n rebuildIndexOnStart {\n\t\tbatchSizeToLoadObjects 30\n\t\tthreadsForSubsequentFetching 8 \t\n\t\tthreadsToLoadObjects 4\n\t\tthreadsForIndexWriter 3\n\t\tcacheMode CacheMode.NORMAL\n }\n\n}\n\n</code></pre>\n<h2>Search</h2>\n<p>The plugin provides you dynamic method to search for indexed entities.</p>\n<h3>Retrieving the results</h3>\n<p>All indexed domain classes provides .search() method which lets you to list the results.\nThe plugin provides a search DSL for simplifying the way you can search. Here is what it looks like with the search DSL:\n(See the HibernateSearchQueryBuilder class to check the available methods)</p>\n<pre><code class=\"language-groovy\">class SomeController {\n\n def myAction = { MyCommand command ->\n\n def page = [max: Math.min(params.max ? params.int('max') : 10, 50), offset: params.offset ? params.int('offset') : 0]\n\n def myDomainClasses = MyDomainClass.search().list {\n\n if ( command.dateTo ) {\n below "publishedDate", command.dateTo\n }\n\n if ( command.dateFrom ) {\n above "publishedDate", command.dateFrom\n }\n\n mustNot {\n keyword "status", Status.DISABLED\n }\n\n if ( command.keyword ) {\n should {\n command.keyword.tokenize().each { keyword ->\n\n def wild = keyword.toLowerCase() + '*'\n\n wildcard "author", wild\n wildcard "body", wild\n wildcard "summary", wild\n wildcard "title", wild\n wildcard "categories.name", wild\n }\n }\n }\n\n sort "publishedDate", "asc"\n\n maxResults page.max\n\n offset page.offset\n }\n\n [myDomainClasses: myDomainClasses]\n }\n}\n</code></pre>\n<h3>Mixing with criteria query</h3>\n<p>Criteria criteria = fullTextSession.createCriteria( clazz ).createAlias("session", "session").add(Restrictions.eq("session.id", 115L));</p>\n<pre><code class=\"language-groovy\"> def myDomainClasses = MyDomainClass.search().list {\n\n criteria {\n setFetchMode("authors", FetchMode.JOIN)\n }\n\n fuzzy "description", "mi search"\n }\n</code></pre>\n<h3>Performing SimpleQueryString searches</h3>\n<p>See <a href=\"https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#_simple_query_string_queries\">Hibernate Search Simple Query Strings</a> for more details on the actual query string.\nYou can implement any other queries alongside a simple query string search.</p>\n<h4>Simple search on 1 field</h4>\n<pre><code class=\"language-groovy\">// Search for "war and peace or harmony" in the title field\ndef myDomainClasses = MyDomainClass.search().list {\n\tsimpleQueryString 'war + (peace | harmony)', 'title'\n}\n</code></pre>\n<h4>Simple search on multiple fields</h4>\n<pre><code class=\"language-groovy\">// Search for "war and peace or harmony" in the title and description field\ndef myDomainClasses = MyDomainClass.search().list {\n\tsimpleQueryString 'war + (peace | harmony)', 'title', 'description\n}\n</code></pre>\n<h4>Simple search on field setting AND as the default operator</h4>\n<pre><code class=\"language-groovy\">// Search for "war and peace" in the title field\ndef myDomainClasses = MyDomainClass.search().list {\n\tsimpleQueryString 'war peace', [withAndAsDefaultOperator: true], 'title'\n}\n</code></pre>\n<h4>Simple search on multiple fields setting the boost for each field</h4>\n<pre><code class=\"language-groovy\">// Search for "war and peace" in the title field and description field with boosts applied\ndef myDomainClasses = MyDomainClass.search().list {\n\tsimpleQueryString 'war + (peace | harmony)', ['title':2.0, 'description':0.5]\n}\n</code></pre>\n<h3>Sorting the results</h3>\n<p>sort() method accepts an optional second parameter to specify the sort order: "asc"/"desc". Default is "asc".</p>\n<p>Fields used for sorting can be analyzed, but must not be tokenized, so you should rather use normalizers on those fields.</p>\n<p>If you try to sort on an indexed field which has not been marked as "sortable" you will either get warnings or full errors.\nTherefore it is important to mark any indexed fields as sortable, and as sortable fields cannot be indexed with tokenizer analyzers you should also define a normalizer to be used (see the section on <a href=\"#normalizer\">Normalizer</a>s on how to define them).</p>\n<pre><code class=\"language-groovy\">MyDomainClass.search().list {\n ...\n sort "publishedDate", "asc"\n ... \n}\n</code></pre>\n<p>If for some reasons, you want to sort results with a property which doesn't exist in your domain class, you should specify the sort type with a third parameter (default is String). You have three ways to achieve this:</p>\n<h4>By Specifying the type (could be Integer, String, Date, Double, Float, Long, Bigdecimal):</h4>\n<pre><code class=\"language-groovy\">MyDomainClass.search().list {\n ...\n sort "my_special_field", "asc", Integer\n ...\n}\n</code></pre>\n<h4>By Specifying directly its sort field (Lucene):</h4>\n<pre><code class=\"language-groovy\">def items = Item.search().list {\n ...\n sort "my_special_field", "asc", org.apache.lucene.search.SortField.Type.STRING_VAL\n ...\n}\n</code></pre>\n<h4>By specifying its sort field with string:</h4>\n<pre><code class=\"language-groovy\">def items = Item.search().list {\n ...\n sort "my_special_field", "asc", "string_val"\n ...\n}\n</code></pre>\n<h3>Counting the results</h3>\n<p>You can also retrieve the number of results by using 'count' method:</p>\n<pre><code class=\"language-groovy\">def myDomainClasses = MyDomainClass.search().count {\n ...\n}\n</code></pre>\n<h3>Additional features</h3>\n<h4>Support for ignoreAnalyzer(), ignoreFieldBridge() and boostedTo() functions</h4>\n<p>When searching for data, you may want to not use the field bridge or the analyzer. All methods (below, above, between, keyword, fuzzy) accept an optional map parameter to support this:</p>\n<pre><code class=\"language-groovy\">\nMyDomainClass.search().list {\n\n keyword "status", Status.DISABLED, [ignoreAnalyzer: true]\n\n wildcard "description", "hellow*", [ignoreFieldBridge: true, boostedTo: 1.5f]\n\n}\n</code></pre>\n<h4>Fuzzy search</h4>\n<p>On fuzzy search, you can add an optional parameter to specify the max distance</p>\n<p>See <a href=\"https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#_fuzzy_queries\">Hibernate Fuzzy Search</a></p>\n<pre><code class=\"language-groovy\">\nMyDomainClass.search().list {\n\n keyword "status", Status.DISABLED, [ignoreAnalyzer: true]\n\n fuzzy "description", "hellow", [ignoreFieldBridge: true, maxDistance: 2]\n\n}\n</code></pre>\n<h3>Support for projections</h3>\n<p>Hibernate Search lets you to return only a subset of properties rather than the whole domain object. It makes it possible to avoid to query the database. This plugin supports this feature:</p>\n<pre><code class=\"language-groovy\">def myDomainClasses = MyDomainClass.search().list {\n\n projection "author", "body"\n\n}\n\nmyDomainClasses.each { result ->\n\n def author = result[0]\n def body = result[1]\n\n ...\n}\n\n</code></pre>\n<p>Don't forget to store the properties into the index as following:</p>\n<pre><code class=\"language-groovy\">class MyDomainClass {\n\n [...]\n\n static luceneIndexing = {\n author index: 'yes', store: 'yes'\n body index: 'yes', store: 'yes'\n }\n}\n</code></pre>\n<h2>Analysis</h2>\n<h3>Define named analyzers</h3>\n<p>Named analyzers are global and can be defined within runtime.groovy as following:</p>\n<pre><code class=\"language-groovy\">\nimport org.apache.solr.analysis.StandardTokenizerFactory\nimport org.apache.solr.analysis.LowerCaseFilterFactory\nimport org.apache.solr.analysis.NGramFilterFactory\n\n...\n\ngrails.plugins.hibernatesearch = {\n\n analyzer( name: 'ngram', tokenizer: StandardTokenizerFactory ) {\n filter LowerCaseFilterFactory\n filter factory: NGramFilterFactory, params: [minGramSize: 3, maxGramSize: 3]\n }\n\n}\n\n</code></pre>\n<p>This configuration is strictly equivalent to this annotation configuration:</p>\n<pre><code class=\"language-java\">@AnalyzerDef(name = "ngram", tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class),\n filters = {\n @TokenFilterDef(factory = LowerCaseFilterFactory.class),\n @TokenFilterDef(factory = NGramFilterFactory.class,\n params = {\n @Parameter(name = "minGramSize",value = "3"),\n @Parameter(name = "maxGramSize",value = "3")\n })\n})\npublic class Address {\n...\n}\n</code></pre>\n<h3>Use named analyzers</h3>\n<p>Set the analyzer at the entity level: all fields will be indexed with the analyzer</p>\n<pre><code class=\"language-groovy\">class MyDomainClass {\n\n String author\n String body\n ...\n\n static luceneIndexing = {\n analyzer = 'ngram'\n author index: 'yes'\n body index: 'yes'\n }\n\n}\n</code></pre>\n<p>Or set the analyzer at the field level:</p>\n<pre><code class=\"language-groovy\">class MyDomainClass {\n\n String author\n String body\n ...\n\n static luceneIndexing = {\n author index: 'yes'\n body index: 'yes', analyzer: 'ngram'\n other index: 'yes', analyzer: new MyFilter()\n }\n\n}\n</code></pre>\n<h3>Get scoped analyzer for given entity</h3>\n<p>The plugin lets you ro retrieve the scoped analyzer for a given analyzer with the search() method:</p>\n<pre><code class=\"language-groovy\">def parser = new org.apache.lucene.queryParser.QueryParser (\n "title", Song.search().getAnalyzer() )\n</code></pre>\n<h2>Normalizer</h2>\n<p>Normalizers are analyzers without tokenization and are important for indexed fields which you want to sort,\nsee <a href=\"https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#section-normalizers\">Hibernate Search Normalizer</a> for more information.</p>\n<h3>Define named normalizers</h3>\n<p>Named normalizers are global and can be defined within runtime.groovy as following:</p>\n<pre><code class=\"language-groovy\">\nimport org.apache.lucene.analysis.core.LowerCaseFilterFactory\nimport org.apache.lucene.analysis.miscellaneous.ASCIIFoldingFilterFactory\n\n...\n\ngrails.plugins.hibernatesearch = {\n\n normalizer(name: 'lowercase') {\n filter ASCIIFoldingFilterFactory\n filter LowerCaseFilterFactory\n }\n\n}\n\n</code></pre>\n<p>This configuration is strictly equivalent to this annotation configuration:</p>\n<pre><code class=\"language-java\">@NormalizerDef(name = "lowercase",\n filters = {\n @TokenFilterDef(factory = ASCIIFoldingFilterFactory.class),\n @TokenFilterDef(factory = LowerCaseFilterFactory.class)\n})\npublic class Address {\n...\n}\n</code></pre>\n<h3>Use named normalizer</h3>\n<p>Set the normalizer at the field level</p>\n<pre><code class=\"language-groovy\">class MyDomainClass {\n\n String author\n String body\n ...\n\n static luceneIndexing = {\n author index: 'yes', sortable: [name: author_sort, normalizer: 'lowercase']\n body index: 'yes', sortable: [name: author_sort, normalizer: LowerCaseFilterFactory]\n }\n\n}\n</code></pre>\n<h2>Filters</h2>\n<p>In Hibernate Search 5.9.x the <code>Filter</code> class is completely removed and filters must now be applied as\n<a href=\"https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#query-filter-fulltext\">Full-Text Filters</a>\nwhich are passed Querys rather than Filters.</p>\n<h3>Define named filters</h3>\n<p>Named filters are global and MUST be defined within runtime.groovy as following:</p>\n<pre><code class=\"language-groovy\">\n...\n\ngrails.plugins.hibernatesearch = {\n\n // cf official doc https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#query-filter-fulltext\n // Example 116. Defining and implementing a Filter\n fullTextFilter name: "bestDriver", impl: BestDriversFilter\n\n // cf official doc https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#query-filter-fulltext\n // Example 118. Using parameters in the actual filter implementation \n fullTextFilter name: "security", impl: SecurityFilterFactory, cache: "instance_only"\n\n}\n\n</code></pre>\n<p>If they are not defined in runtime.groovy they will not be available for querying.</p>\n<h3>Filter query results</h3>\n<p>Filter query results looks like this:</p>\n<p>MyDomainClass.search().list {</p>\n<pre><code class=\"language-groovy\">\n// without params:\nMyDomainClass.search().list {\n ...\n filter "bestDriver"\n ...\n}\n\n// with params:\nMyDomainClass.search().list {\n ...\n filter name: "security", params: [ level: 4 ]\n ...\n}\n\n</code></pre>\n<h2>Options</h2>\n<pre><code class=\"language-groovy\">grails.plugins.hibernatesearch = {\n\trebuildIndexOnStart false // see related section above\n\tthrowOnEmptyQuery false // throw or not exception when Hibernate Search raises an EmptyQueryException\n\tfullTextFilter /* ... */ // see related section above\n}\n</code></pre>\n<h2>Notes</h2>\n<h3>Updating from 2.2 to 2.3</h3>\n<p>There is a signification change between 2.2 and 2.3.</p>\n<h4>Updating filters</h4>\n<p>Filters must now be defined in the runtime.groovy in advance and then added to a query as filter definitions which will define fullTextFilters.\nThis is due to the deprecation of the filter class from Hibernate Search.</p>\n<h3>runtime.groovy vs application.groovy</h3>\n<p>In Grails 3 the <code>application.groovy</code> file is loaded when the Grails CLI is started,\ntherefore certain logic and requirements on dependencies will fall over when defined in the <code>application.groovy</code> file.</p>\n<p>The solution is to define a <code>runtime.groovy</code> file and move the logic into this file,\nthis also helps to provide a nice divide on what logic is required when running the application\nand as config is now provided in the <code>application.yml</code> file it should result in only needing to define a <code>runtime.groovy</code> file and not the\n<code>application.groovy</code> file.</p>\n<p>We therefore advise all hibernatesearch closure config to be defined in the <code>runtime.groovy</code> file.</p>\n<p><code>runtime.groovy</code> is run along with application.groovy when the application starts up, it is also packaged and run by a WAR.</p>\n<h3>IDE Integration</h3>\n<p>Unfortunately IDEs will not recognise the <code>search()</code> method as it is added dynamically.\nOne messy but possible way to get around this and gain access to the DSL inside the IDE is to\nadd an extra static method to your class.\nThis is not ideal but it may make your programming easier.</p>\n<pre><code class=\"language-groovy\">class DomainClass {\n\n ...\n\n static List<DomainClass> hibernateSearchList(@DelegatesTo(HibernateSearchApi) Closure closure){\n DomainClass.search().list(closure)\n }\n \n static int hibernateSearchCount(@DelegatesTo(HibernateSearchApi) Closure closure){\n DomainClass.search().count(closure)\n }\n}\n</code></pre>\n<h3>SessionFactory failures during startup</h3>\n<p>During the SessionFactory build process any exceptions which occur during the HibernateSearch boot sequence\nare silently wrapped and hidden inside the futures.\nThis means there will be a particularly helpful exception thrown :</p>\n<pre><code>Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'methodValidationPostProcessor' defined in class path resource [org/springframework/boot/autoconfigure/validation/ValidationAutoConfiguration.class]: Unsatisfied dependency expressed through method 'methodValidationPostProcessor' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hibernateDatastoreServiceRegistry': Cannot resolve reference to bean 'hibernateDatastore' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hibernateDatastore': Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.grails.orm.hibernate.HibernateDatastore]: Constructor threw exception; nested exception is java.lang.NullPointerException\n</code></pre>\n<p>which will stacktrace down to :</p>\n<pre><code>Caused by: java.lang.NullPointerException: null\n\tat org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration$2.sessionFactoryClosed(HibernateMappingContextConfiguration.java:266)\n\tat org.hibernate.internal.SessionFactoryObserverChain.sessionFactoryClosed(SessionFactoryObserverChain.java:61)\n\tat org.hibernate.internal.SessionFactoryImpl.close(SessionFactoryImpl.java:756)\n\tat org.hibernate.search.hcore.impl.HibernateSearchSessionFactoryObserver.boot(HibernateSearchSessionFactoryObserver.java:134)\n\tat org.hibernate.search.hcore.impl.HibernateSearchSessionFactoryObserver.sessionFactoryCreated(HibernateSearchSessionFactoryObserver.java:79)\n\tat org.hibernate.internal.SessionFactoryObserverChain.sessionFactoryCreated(SessionFactoryObserverChain.java:35)\n\tat org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:366)\n\tat org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:452)\n\tat org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:710)\n\tat org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration.buildSessionFactory(HibernateMappingContextConfiguration.java:274)\n\tat grails.plugins.hibernate.search.context.HibernateSearchMappingContextConfiguration.buildSessionFactory(HibernateSearchMappingContextConfiguration.java:357)\n\tat org.grails.orm.hibernate.connections.HibernateConnectionSourceFactory.create(HibernateConnectionSourceFactory.java:86)\n\tat org.grails.orm.hibernate.connections.AbstractHibernateConnectionSourceFactory.create(AbstractHibernateConnectionSourceFactory.java:39)\n\tat org.grails.orm.hibernate.connections.AbstractHibernateConnectionSourceFactory.create(AbstractHibernateConnectionSourceFactory.java:23)\n\tat org.grails.datastore.mapping.core.connections.AbstractConnectionSourceFactory.create(AbstractConnectionSourceFactory.java:64)\n\tat org.grails.datastore.mapping.core.connections.AbstractConnectionSourceFactory.create(AbstractConnectionSourceFactory.java:52)\n\tat org.grails.datastore.mapping.core.connections.ConnectionSourcesInitializer.create(ConnectionSourcesInitializer.groovy:24)\n\tat org.grails.orm.hibernate.HibernateDatastore.<init>(HibernateDatastore.java:196)\n\tat sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)\n\tat sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)\n\tat sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)\n\tat java.lang.reflect.Constructor.newInstance(Constructor.java:423)\n\tat org.springsource.loaded.ri.ReflectiveInterceptor.jlrConstructorNewInstance(ReflectiveInterceptor.java:1076)\n\tat org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:142)\n\t... 51 common frames omitted\n</code></pre>\n<p>The actual exception stack is not at all helpful as whilst the actual failure point is in:</p>\n<pre><code>org.hibernate.search.hcore.impl.HibernateSearchSessionFactoryObserver.boot(HibernateSearchSessionFactoryObserver.java:134)\n</code></pre>\n<p>It is masked inside the catch statement at line 127 inside the class,\nas the finally clause is what results in the above exception stacktrace.</p>\n<pre><code class=\"language-java\">public class HibernateSearchSessionFactoryObserver implements SessionFactoryObserver {\n // ...\n \n private synchronized void boot(SessionFactory factory) {\n try{ \n // ...\n }\n catch (Throwable t) {\n extendedSearchIntegratorFuture.completeExceptionally( t );\n // This will make the SessionFactory abort and close itself\n throw t;\n }finally {\n if ( failedBoot ) {\n factory.close();\n }\n }\n }\n \n // ...\n}\n</code></pre>\n<p>Therefore if you get the above exceptions then drop a debug point at line 130 and then start with a debugger running.\nThe debug point will give you the helpful exception as to why the boot has failed.</p>\n<h2>Examples</h2>\n<p>A sample project is available at this repository URL\nhttps://github.com/lgrignon/grails3-quick-start</p>\n<p>It contains several branches for each version of this plugin</p>\n<h2>Change log</h2>\n<h3>v2.3</h3>\n<ul>\n<li>Grails 3.3.x</li>\n<li>GORM 6.1</li>\n<li>Hibernate 5.2.10</li>\n<li>Hibernate Search 5.9.1</li>\n<li>Add sortable field</li>\n<li>Add SimpleQueryString</li>\n</ul>\n<h3>v2.2</h3>\n<ul>\n<li>Grails 3.3.x</li>\n<li>GORM 6.1</li>\n<li>Hibernate 5.2.9</li>\n<li>Hibernate Search 5.7</li>\n</ul>\n<h3>v2.1.2</h3>\n<ul>\n<li>Supports hibernate.configClass if any</li>\n<li>Removed dependencies to info.app.grailsVersion, info.app.name</li>\n</ul>\n<h3>v2.1</h3>\n<ul>\n<li>Grails 3.2.x</li>\n<li>GORM 6</li>\n<li>Hibernate 5.2.9</li>\n<li>Hibernate Search 5.7</li>\n</ul>\n<h3>v2.0.2</h3>\n<p>Support for indexing trait properties</p>\n<h3>v2.0.1</h3>\n<p>Support for indexing inherited properties</p>\n<h3>v2.0</h3>\n<ul>\n<li>Grails 3.1.x</li>\n<li>GORM 5</li>\n<li>Hibernate 5.1.1</li>\n<li>Hibernate Search 5.5.4</li>\n</ul>\n<h3>v1.x</h3>\n<ul>\n<li>Grails 2.x</li>\n<li>Hibernate 4</li>\n</ul>\n<h2>Authors</h2>\n<p><strong>Mathieu Perez</strong></p>\n<ul>\n<li>http://twitter.com/mathieuperez</li>\n</ul>\n<p><strong>Julie Ingignoli</strong></p>\n<ul>\n<li>http://twitter.com/ZeJulie</li>\n</ul>\n<p><strong>Louis Grignon</strong></p>\n<ul>\n<li>https://github.com/lgrignon</li>\n</ul>\n<h2>Development / Contribution</h2>\n<p>Install with:</p>\n<pre><code>gradlew clean publishToMavenLocal\n</code></pre>\n<p>Publish with:</p>\n<pre><code>gradlew clean bintrayUpload --stacktrace -PbintrayUser=... -PbintrayKey=...\n</code></pre>\n<h2>License</h2>\n<p>Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "hibernate3", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "GORM - Grails Data Access Framework", |
| "labels": [ |
| "database", |
| "gorm", |
| "hibernate", |
| "rdms" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/grails-data-mapping/issues", |
| "latestVersion": "5.0.13", |
| "updated": "2017-03-21T12:02:19.359Z", |
| "systemIds": [ |
| "org.grails.plugins:hibernate3" |
| ], |
| "vcsUrl": "https://github.com/grails/grails-data-mapping" |
| }, |
| "documentationUrl": "https://grails.github.io/grails-data-mapping/", |
| "mavenMetadataUrl": null, |
| "readme": "<p><img src=\"https://github.com/grails/grails-data-mapping/workflows/Java%20CI/badge.svg?branch=master\" alt=\"Java CI\" />\n<img src=\"https://github.com/grails/grails-data-mapping/workflows/Release/badge.svg?branch=master\" alt=\"Release\" />\n<img src=\"https://github.com/grails/grails-data-mapping/workflows/Maven%20Central%20Sync/badge.svg?branch=master\" alt=\"Maven Central Sync\" /></p>\n<h1>GORM (Grails Object Mapping)</h1>\n<p>[Grails][Grails] is a framework used to build web applications with the [Groovy][Groovy] programming language. This project provides the plumbings for the GORM API both for Hibernate and for new implementations of GORM ontop of NoSQL datastores.\n[Grails]: http://grails.org/\n[Groovy]: http://groovy-lang.org/</p>\n<h2>Getting Started</h2>\n<p>For further information see the dedicated websites:</p>\n<ul>\n<li><a href=\"http://gorm.grails.org/\">Stable Version</a>.</li>\n<li><a href=\"http://gorm.grails.org/snapshot/\">Development Version</a>.</li>\n</ul>\n<h2>License</h2>\n<p>Grails and Groovy are licensed under the terms of the [Apache License, Version 2.0][Apache License, Version 2.0].\n[Apache License, Version 2.0]: http://www.apache.org/licenses/LICENSE-2.0.html</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "hibernate4", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "GORM - Grails Data Access Framework", |
| "labels": [ |
| "database", |
| "gorm", |
| "hibernate", |
| "rdms" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/gorm-hibernate4", |
| "latestVersion": "6.1.8", |
| "updated": "2017-10-27T06:58:00.000Z", |
| "systemIds": [ |
| "org.grails.plugins:hibernate4" |
| ], |
| "vcsUrl": "https://github.com/grails/gorm-hibernate4" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>GORM for Hibernate 4</h1>\n<p>This project implements <a href=\"http://gorm.grails.org/latest/\">GORM</a> for the Hibernate 4.</p>\n<p>For more information see the following links:</p>\n<ul>\n<li><a href=\"http://gorm.grails.org/latest/hibernate/manual\">Documentation</a></li>\n<li><a href=\"http://gorm.grails.org/latest/hibernate/api\">API</a></li>\n<li><a href=\"https://grails.org/plugins.html#plugin/hibernate4\">Grails Plugin</a></li>\n<li><a href=\"https://travis-ci.org/grails/gorm-hibernate5\"><img src=\"https://travis-ci.org/grails/gorm-hibernate4.svg?branch=master\" alt=\"Build Status\" /></a></li>\n</ul>\n<p>For the current development version see the following links:</p>\n<ul>\n<li><a href=\"http://gorm.grails.org/snapshot/hibernate/manual\">Beta Documentation</a></li>\n<li><a href=\"http://gorm.grails.org/snapshot/hibernate/api\">Beta API</a></li>\n</ul>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "hibernate5", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "GORM - Grails Data Access Framework", |
| "labels": [ |
| "database", |
| "gorm", |
| "hibernate", |
| "rdms" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/grails-data-mapping/issues", |
| "latestVersion": "8.1.1", |
| "updated": "2024-11-19T01:27:50.000Z", |
| "systemIds": [ |
| "org.grails.plugins:hibernate5" |
| ], |
| "vcsUrl": "https://github.com/grails/grails-data-mapping" |
| }, |
| "documentationUrl": "https://grails.github.io/grails-data-mapping/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/grails/plugins/hibernate5/maven-metadata.xml", |
| "readme": "<p><img src=\"https://github.com/grails/grails-data-mapping/workflows/Java%20CI/badge.svg?branch=master\" alt=\"Java CI\" />\n<img src=\"https://github.com/grails/grails-data-mapping/workflows/Release/badge.svg?branch=master\" alt=\"Release\" />\n<img src=\"https://github.com/grails/grails-data-mapping/workflows/Maven%20Central%20Sync/badge.svg?branch=master\" alt=\"Maven Central Sync\" /></p>\n<h1>GORM (Grails Object Mapping)</h1>\n<p>[Grails][Grails] is a framework used to build web applications with the [Groovy][Groovy] programming language. This project provides the plumbings for the GORM API both for Hibernate and for new implementations of GORM ontop of NoSQL datastores.\n[Grails]: http://grails.org/\n[Groovy]: http://groovy-lang.org/</p>\n<h2>Getting Started</h2>\n<p>For further information see the dedicated websites:</p>\n<ul>\n<li><a href=\"http://gorm.grails.org/\">Stable Version</a>.</li>\n<li><a href=\"http://gorm.grails.org/snapshot/\">Development Version</a>.</li>\n</ul>\n<h2>License</h2>\n<p>Grails and Groovy are licensed under the terms of the [Apache License, Version 2.0][Apache License, Version 2.0].\n[Apache License, Version 2.0]: http://www.apache.org/licenses/LICENSE-2.0.html</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "html-cleaner", |
| "repo": "grails-plugins", |
| "owner": "snimavat", |
| "desc": "Html Cleaner Grails Plugin", |
| "labels": [ |
| "html" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/snimavat/html-cleaner/issues", |
| "latestVersion": "3.0.0.1", |
| "updated": "2017-01-16T10:18:16.040Z", |
| "systemIds": [ |
| "org.grails.plugins:html-cleaner" |
| ], |
| "vcsUrl": "https://github.com/snimavat/html-cleaner" |
| }, |
| "documentationUrl": "https://snimavat.github.io/html-cleaner/", |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/snimavat/html-cleaner\"><img src=\"https://travis-ci.org/snimavat/html-cleaner.svg?branch=master\" alt=\"Build Status\" /></a></p>\n<p>See <a href=\"http://snimavat.github.com/html-cleaner/guide/index.html\">documentation</a></p>\n" |
| }, |
| { |
| "deprecated": "Source repository is archived and this is a duplicate of a plugin with the same name by snimavat. This entry in the registry should probably be removed to avoid confusion.", |
| "bintrayPackage": { |
| "name": "html-cleaner", |
| "repo": "plugins", |
| "owner": "agorapulse", |
| "desc": "Grails HTML Cleaner plugin", |
| "labels": [ |
| "html" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/agorapulse/grails-html-cleaner/issues", |
| "latestVersion": "1.1", |
| "updated": "2016-05-03T11:57:38.051Z", |
| "systemIds": [ |
| "org.grails.plugins:html-cleaner" |
| ], |
| "vcsUrl": "https://github.com/agorapulse/grails-html-cleaner" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Html Cleaner Grails Plugin</h1>\n<p><a href=\"https://travis-ci.org/agorapulse/grails-html-cleaner\"><img src=\"https://travis-ci.org/agorapulse/grails-html-cleaner.png\" alt=\"Build Status\" /></a>\n<a href=\"https://bintray.com/agorapulse/plugins/html-cleaner/_latestVersion\"><img src=\"https://api.bintray.com/packages/agorapulse/plugins/html-cleaner/images/download.svg\" alt=\"Download\" /></a></p>\n<h1>Introduction</h1>\n<p>The <strong>Html Cleaner Plugin</strong> is a whitelist based html sanitizer, based on <a href=\"http://jsoup.org\">Jsoup</a>.\nThis is a port to Grails3 of the Grails1 plugin, originally written by Sudhir Nimavat.</p>\n<p>It provides:</p>\n<ul>\n<li>a DSL to define whitelists,</li>\n<li><strong>HtmlCleaner</strong> - A Spring bean which provides a method <em>cleanHtml()</em> to sanitize html,</li>\n<li><strong>htmlCleanerTagLib</strong> - A taglib to sanitize html.</li>\n</ul>\n<p>Note: Html cleaner is not just a sanitizer, it cleans ill-formed user supplied html and produces a well formed xml.</p>\n<h1>Installation</h1>\n<p>Declare the plugin dependency in the <em>build.gradle</em> file, as shown here:</p>\n<pre><code class=\"language-groovy\">repositories {\n ...\n maven { url "http://dl.bintray.com/agorapulse/plugins" }\n}\ndependencies {\n ...\n compile "org.grails.plugins:html-cleaner:1.1"\n}\n</code></pre>\n<h1>Config</h1>\n<p>Following whitelists are available by default and does not need any configuration:</p>\n<ul>\n<li>none</li>\n<li>simpleText</li>\n<li>basic</li>\n<li>basicWithImages</li>\n<li>relaxed</li>\n</ul>\n<p>You can define default white list in your <em>grails-app/conf/application.yml</em>:</p>\n<pre><code class=\"language-yml\">grails:\n plugin:\n htmlcleaner:\n defaultWhiteList: basic\n</code></pre>\n<p>See below to define custom whitelists.</p>\n<h1>Usage</h1>\n<p>Let's say you have a form with a text area, but you don't want to allow any html. You can clean the user supplied text with whitelist none and it will stripe out all the html.</p>\n<pre><code class=\"language-groovy\">import grails.plugin.htmlcleaner.HtmlCleaner\n\nclass FooController {\n\n HtmlCleaner htmlCleaner\n\n def save = {\n String cleaned = htmlCleaner.cleanHtml(params.textArea, 'none') \n }\n}\n</code></pre>\n<p>Or in a service:</p>\n<pre><code class=\"language-groovy\">import grails.plugin.htmlcleaner.HtmlCleaner\n\nclass FooService {\n\n HtmlCleaner htmlCleaner\n\n def foo(unsafe) {\n String cleaned = htmlCleaner.cleanHtml(unsafe, 'none')\n }\n}\n</code></pre>\n<p>You can also allow basic html as per basic whitelist.</p>\n<pre><code class=\"language-groovy\">def cleaned = htmlCleaner.cleanHtml(unsafe, 'basic')\n</code></pre>\n<p>The plugin also provides a taglib.</p>\n<pre><code class=\"language-html\"><hc:cleanHtml html="${domainInstance.description}" whitelist="basic"/>\n</code></pre>\n<h1>Defining custom whitelists</h1>\n<p>Plugin provides a DSL to define custom whitelists in configuration.\nDefine a custom whitelist sample that will allow just <em>b</em>, <em>i</em>, <em>p</em> and <em>span</em> tags.</p>\n<p>application.groovy</p>\n<pre><code>grails {\n plugin {\n htmlcleaner {\n whitelists = {\n whitelist("sample") {\n startwith "none"\n allow "b", "p", "i", "span"\n }\n }\n }\n }\n}\n</code></pre>\n<p>The above configuration would define a whitelist with name sample that builds on top of whitelist none and allows additional tags <em>b</em>, <em>i</em>, <em>p</em> and <em>span</em>.</p>\n<p>A whitelist can start with any of the default whitelists or A whitelist can start with any custom whitelists that are defined earlier in configuration as well, but it must start with another whitelist.</p>\n<p>Define a whitelist sample2 that starts with whitelist sample we defined above and allows tag <em>a</em> with just one attribute href and puts rel="nofollow"</p>\n<pre><code>grails {\n plugin {\n htmlcleaner {\n whitelists = {\n whitelist("sample2") {\n startwith "sample"\n allow("a") {\n attributes "href"\n enforce attribute:"rel", value:"nofollow"\n }\n }\n }\n }\n }\n}\n</code></pre>\n<p>Define a whitelist basic-with-tables that starts with whitelist basic and allows tables.</p>\n<pre><code>grails {\n plugin {\n htmlcleaner {\n whitelists = {\n whitelist("basic-with-tables") {\n startwith "basic"\n allow "table", "tr", "td"\n }\n }\n }\n }\n}\n</code></pre>\n<p>Restricting attributes</p>\n<pre><code>grails {\n plugin {\n htmlcleaner {\n whitelists = {\n whitelist("sample") {\n allow("div") {\n attributes "id", "class"\n }\n }\n }\n }\n }\n}\n</code></pre>\n<p>Enforcing attributes - An enforced attribute will always be added to the element. If the element already has the attribute set, it will be overridden.</p>\n<pre><code>grails {\n plugin {\n htmlcleaner {\n whitelists = {\n whitelist("sample") {\n allow("div") {\n enforce attribute:"class", value:"block"\n }\n }\n }\n }\n }\n}\n</code></pre>\n<p>Defining multiple whitelists</p>\n<pre><code>grails {\n plugin {\n htmlcleaner {\n whitelists = {\n whitelist("sample") {\n startwith "none"\n allow "b", "p", "span"\n }\n whitelist("sample-with-anchor") {\n startwith "sample"\n allow("a") {\n attributes "href"\n enforce attribute:"rel", value:"nofollow"\n }\n }\n \n whitelist("basic-with-tables") {\n startwith "basic"\n allow "table", "tr", "td"\n }\n \n }\n }\n }\n}\n</code></pre>\n<h1>Bugs</h1>\n<p>To report any bug, please use the project <a href=\"http://github.com/agorapulse/grails-html-cleaner/issues\">Issues</a> section on GitHub.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "http-builder-helper", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Grails HTTP Builder Helper Plugin", |
| "labels": [ |
| "http-client" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/bobbywarner/grails-http-builder-helper/issues", |
| "latestVersion": "1.1.0", |
| "updated": "2017-09-01T14:14:12.890Z", |
| "systemIds": [ |
| "org.grails.plugins:http-builder-helper" |
| ], |
| "vcsUrl": "https://github.com/bobbywarner/grails-http-builder-helper" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails HTTP Builder Helper</h1>\n<p>This plugin used to be called the REST plugin in Grails 1.x & 2.x, but for Grails 3.x it has been renamed to <code>httpbuilder-helper</code>. The plugin enables the usage of HTTPBuilder in a Grails application.</p>\n<h1>Description</h1>\n<p>The REST plugin enables the usage of HTTPBuilder on a Grails application.</p>\n<h2>Usage</h2>\n<p>The plugins will inject the following dynamic methods:</p>\n<ul>\n<li><code>withHttp(Map params, Closure stmts)</code> - executes stmts using a <code>HTTPBuilder</code></li>\n<li><code>withAsyncHttp(Map params, Closure stmts)</code> - executes stmts using an <code>AsyncHTTPBuilder</code></li>\n<li><code>withRest(Map params, Closure stmts)</code> - executes stmts using a <code>RESTClient</code></li>\n</ul>\n<h2>Examples</h2>\n<p>Taken from HttpBuilder's Simplified GET Request</p>\n<pre><code class=\"language-groovy\">withHttp(uri: "http://www.google.com") {\n def html = get(path : '/search', query : [q:'Groovy'])\n assert html.HEAD.size() == 1\n assert html.BODY.size() == 1\n}\n</code></pre>\n<p>Notice that you can call <code>HTTPBuilder</code>'s methods inside <code>stmts</code>, the current <code>HTTPBuilder</code> is set as the closure's delegate. The same holds true for the other dynamic methods.\n<code>AsyncHTTPBuilder</code></p>\n<pre><code class=\"language-groovy\">import static groovyx.net.http.ContentType.HTML\nwithAsyncHttp(poolSize : 4, uri : "http://hc.apache.org", contentType : HTML) {\n def result = get(path:'/') { resp, html ->\n println ' got async response!'\n return html\n }\n assert result instanceof java.util.concurrent.Future\n\n while (! result.done) {\n println 'waiting...'\n Thread.sleep(2000)\n }\n\n /* The Future instance contains whatever is returned from the response\n closure above; in this case the parsed HTML data: */\n def html = result.get()\n assert html instanceof groovy.util.slurpersupport.GPathResult\n}\n</code></pre>\n<p>All dynamic methods will create a new http client when invoked unless you define an id: attribute. When this attribute is supplied the client will be stored as a property on the instance's metaClass. You will be able to access it via regular property access or using the id: again.</p>\n<pre><code class=\"language-groovy\">class FooController {\n def loginAction = {\n withRest(id: "twitter", uri: "http://twitter.com/statuses/") {\n auth.basic model.username, model.password\n }\n }\n def queryAction = {\n withRest(id: "twitter") {\n def response = get(path: "followers.json")\n // \ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\n }\n /* alternatively\n def response twitter.get(path: "followers.json")\n */\n }\n}\n</code></pre>\n<h1>Configuration</h1>\n<h2>Dynamic method injection</h2>\n<p>Dynamic methods will be added to controllers and services by default. You can change this setting by adding a configuration flag <code>application.yml</code> or <code>application.groovy</code>:</p>\n<pre><code class=\"language-groovy\">grails.rest.injectInto = ["Controller", "Service", "Routes"]\n</code></pre>\n<h2>Proxy settings</h2>\n<p>You can apply proxy settings by calling <code>setProxy(String host, int port, String scheme)</code> on the client/builders at any time. You can also take advantage of the <code>proxy:</code> shortcut</p>\n<pre><code class=\"language-groovy\">withHttp(uri: "http://google.com", proxy: [host: "myproxy.acme.com", port: 8080, scheme: "http"])\n</code></pre>\n<p>This shortcut has the following defaults</p>\n<pre><code>port: = 80\nscheme: = http\n</code></pre>\n<p>Meaning most of the times you'd only need to define a value for <code>host:</code></p>\n<h2>SSL Key-Store and Trust-Store support</h2>\n<p>If you are connecting to a server through HTTPS you might need to add a Key and or a Trust Store to the underlying SSL Socket Factory. Some examples are\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd</p>\n<p>The service you are connecting to requires some sort of SSL Cert authentication,\nYou want to make sure that the server you are connecting to provides a specific certificate.\nYou do not mind that the certificate that the server provides doesn't match the Domain Name that the server has.\nNote, this last option will normally apply to development and test environments.</p>\n<h3>So how can I add the Key and/or Trust Stores to the underlying SSL Socket Factory?</h3>\n<p>The client will try to add a Key and a Trust Store if the URL of the host starts with <code>https</code>. By default it will attempt to locate a Key Store through the File System's path <code>$HOME/.keystore</code> e.g <code>/home/berngp/.keystore</code> and a Trust Store through the JVM Classpath <code>./truststore.jks</code>, you can override this by specifying a <code>rest.https.keystore.path</code> and/or <code>rest.https.truststore.path</code> configuration entries in the <code>application.yml</code> or <code>application.groovy</code> file.</p>\n<p>Also by default it will try to open the stores using the following passwords '', 'changeit', 'changeme' but you can set a specific password through the <code>rest.https.keystore.pass</code> and <code>rest.https.truststore.pass</code> configuration entries. If for some reason it is unable to setup the underlying SSL Socket Factory it will fail silently unless the <code>rest.https.sslSocketFactory.enforce</code> configuration entry is set to <code>true</code>.</p>\n<h3>Specifying a Hostname Verification strategy for the Trust Store.</h3>\n<p>You can set three different Hostname Verification strategies through the <code>rest.https.cert.hostnameVerifier</code> configuration entry.</p>\n<p><code>ALLOW_ALL</code>: The URL requested doesn't need to match the URL in the Certificate.\n<code>STRICT</code>: The URL requested needs to match the URL in the Certificate.\n<code>BROWSER_COMPATIBLE</code>: The URL requested must be in the same domain as the one in the Certificate. It accepts wildcards.\nExample of a specific setup</p>\n<pre><code class=\"language-groovy\">/** SSL truststore configuration key */\nrest.https.truststore.path = 'resources/certs/truststore.jks'\n/** SSL keystore configuration key */\nrest.https.keystore.path='resources/certs/keystore.jks'\n/** SSL keystore password configuration key */\nrest.https.keystore.pass='changeme'\n/** Certificate Hostname Verifier configuration key */\nrest.https.cert.hostnameVerifier = 'BROWSER_COMPATIBLE'\n/** Enforce SSL Socket Factory */\nrest.https.sslSocketFactory.enforce = true\n</code></pre>\n<h3>Generating a Key Store</h3>\n<p>Generating a Java Key Store is outside the scope of this guide but you can find some useful information through the following links.</p>\n<ul>\n<li>\n<p>Official JDK Guide - http://download.oracle.com/javase/6/docs/technotes/tools/solaris/keytool.html</p>\n</li>\n<li>\n<p>Importing a Private Key into a KeyStore (JDK 1.6 and above) - http://cunning.sharp.fm/2008/06/importing_private_keys_into_a.html</p>\n</li>\n<li>\n<p>KeyMan - An non JDK Key Tool by IBM - http://www.alphaworks.ibm.com/tech/keyman</p>\n</li>\n</ul>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "http-requests-grails", |
| "repo": "maven", |
| "owner": "budjb", |
| "desc": "The HTTP Requests Plugin provides the http-requests library and artefacts for filters and converters.", |
| "labels": [ |
| "http-client" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/budjb/http-requests/issues", |
| "latestVersion": "1.0.2", |
| "updated": "2018-07-25T04:16:25.412Z", |
| "systemIds": [ |
| "com.budjb:http-requests-grails" |
| ], |
| "vcsUrl": "https://github.com/budjb/http-requests" |
| }, |
| "documentationUrl": "https://budjb.github.io/http-requests/", |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/budjb/http-requests\"><img src=\"http://img.shields.io/travis/budjb/http-requests.svg?branch=master\" alt=\"Build Status\" /></a>\n<a href=\"http://www.apache.org/licenses/LICENSE-2.0.html\"><img src=\"http://img.shields.io/:license-apache-blue.svg\" alt=\"License\" /></a></p>\n<h1>HTTP Requests Library</h1>\n<p>See the documentation at https://budjb.github.io/http-requests/latest.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "i18n-asset-pipeline", |
| "repo": "plugins", |
| "owner": "amc-world", |
| "desc": "asset-pipeline plugin to use localized messages in JavaScript.", |
| "labels": [ |
| "i18n", |
| "javascript" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/dellermann/i18n-asset-pipeline/issues", |
| "latestVersion": "2.0.0", |
| "updated": "2016-03-31T13:31:54.872Z", |
| "systemIds": [ |
| "org.grails.plugins:i18n-asset-pipeline" |
| ], |
| "vcsUrl": "https://github.com/dellermann/i18n-asset-pipeline" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>I18n asset-pipeline plugin</h1>\n<p>The Grails plugin <code>i18n-asset-pipeline</code> is an asset-pipeline plugin that\ngenerates a JavaScript file with localized texts which can be used for\nclient-side i18n.</p>\n<p>For more information on how to use asset-pipeline, visit\n<a href=\"http://www.github.com/bertramdev/asset-pipeline\">asset-pipeline project page</a>.</p>\n<h2>Version information</h2>\n<p>Because <code>asset-pipeline</code> 2.x and 3.x introduced new APIs and aren't backward\ncompatible, you must use the following versions of this plugin:</p>\n<p>i18n-asset-pipeline version | required for\n----------------------------|--------------\n0.x | <code>asset-pipeline</code> up to version 1.9.9\n1.x | <code>asset-pipeline</code> version 2.0.0 or higher\n2.x | Grails 3.x</p>\n<h2>Installation</h2>\n<p>To use this plugin you have to add the following code to your <code>build.gradle</code>:</p>\n<pre><code class=\"language-groovy\">buildscript {\n dependencies {\n classpath 'org.amcworld.plugins:i18n-asset-pipeline:2.0.0'\n }\n}\n\ndependencies {\n runtime 'org.grails.plugins:i18n-asset-pipeline:2.0.0'\n}\n</code></pre>\n<p>The first dependency declaration is needed to precompile your assets (e. g.\nwhen building a WAR file). The second one provides the necessary\n<code><asset:i18n></code> tag and compiles the assets on the fly (e. g. in development)\nmode.</p>\n<h2>Usage</h2>\n<p><code>i18n-asset-pipeline</code> uses special files in your asset folders (we recommend\n<code>grails-app/assets/i18n</code>) with extension '.i18n'. The names of\nthese files must contain a language specification separated by underscore, e.\ng. <code>messages_de.i18n</code> or <code>messages_en_UK.i18n</code>. Files without a language\nspecification (e. g. <code>messages.i18n</code>) are files for the default locale. These\nfiles mainly contain message codes that are resolved to localized texts.</p>\n<p>The plugin generates a JavaScript file, that contains a function named <code>$L</code>\nwhich can be called to obtain the localized message by a given code, e. g.:</p>\n<pre><code class=\"language-javascript\">$(".btn").text($L("default.btn.ok"));\n</code></pre>\n<h2>I18n file syntax</h2>\n<p>Each i18n file must be defined according to the following rules:</p>\n<ul>\n<li>Files are line based.</li>\n<li>Lines are trimmed (i. e. leading and terminating whitespaces are removed).</li>\n<li>Empty lines and lines starting with a hash <code>#</code> (comment lines) are ignored.</li>\n<li>Lines starting with <code>@import</code> <em><code>url</code></em> are resolved by importing file\n<em><code>url</code></em>, processing it according to these rules, and replacing the\n<code>@import</code> statement by its content. The import file may contain further\nimport statements, even circular ones. You may omit file extension <code>.i18n</code>\nin <em><code>url</code></em>.</li>\n<li>All other lines are treated as messsage codes which are translated to the\nrequired language.</li>\n<li>Comments after import statements and message codes are not allowed.</li>\n</ul>\n<p>Each i18n file may contain asset-pipeline <code>require</code> statements to load other\nassets such as JavaScript files. <strong>ATTENTION!</strong> Don't use <code>require</code> to load\nother i18n files because they will not be processed correctly. Use the\n<code>@import</code> declaration instead.</p>\n<h2>Typical file structure</h2>\n<p>Typically, you have one i18n file for each language in the application. Given,\nyou have the following message resources in <code>grails-app/i18n</code>:</p>\n<ul>\n<li><code>messages.properties</code></li>\n<li><code>messages_de.properties</code></li>\n<li><code>messages_en_UK.properties</code></li>\n<li><code>messages_es.properties</code></li>\n<li><code>messages_fr.properties</code></li>\n</ul>\n<p>Then, you should have the same set of files in e. g. <code>grails-app/assets/i18n</code>:</p>\n<ul>\n<li><code>messages.i18n</code></li>\n<li><code>messages_de.i18n</code></li>\n<li><code>messages_en_UK.i18n</code></li>\n<li><code>messages_es.i18n</code></li>\n<li><code>messages_fr.i18n</code></li>\n</ul>\n<p>Normally, you would have to declare the same set of message codes in each file.\nTo DRY, add a file <code>_messages.i18n</code> to <code>grails-app/assets/i18n</code> (the\nleading underscore prevents the i18n file to be compiled itself):</p>\n<pre><code>#\n# _messages.i18n\n# List of message codes that should be available on client-side.\n#\n\n# Add your messages codes here:\ndefault.btn.cancel\ndefault.btn.ok\ncontact.foo.bar\n\n</code></pre>\n<p>Then, you can import this file in all other files, e. g.:</p>\n<pre><code>#\n# messages.i18n\n# Client-side i18n, English messages.\n#\n\n@import _messages\n\n</code></pre>\n<pre><code>#\n# messages_de.i18n\n# Client-side i18n, German messages.\n#\n\n@import _messages\n\n</code></pre>\n<pre><code>#\n# messages_es.i18n\n# Client-side i18n, Spanish messages.\n#\n\n@import _messages\n\n</code></pre>\n<h2>Including localized assets</h2>\n<p>In order to include a localized asset you can either use an asset-pipeline\n<code>require</code> directive or the tag <code><asset:i18n></code>. The tag supports the following\nattributes:</p>\n<ul>\n<li><code>locale</code>. Either a string or a <code>java.util.Locale</code> object representing the\nlocale that should be loaded. This attribute is mandatory.</li>\n<li><code>name</code>. A string indicating the base name of the i18n files to load\n(defaults to <code>messages</code>).</li>\n</ul>\n<p>Examples:</p>\n<pre><code class=\"language-html\"><asset:i18n locale="en_UK" />\n</code></pre>\n<pre><code class=\"language-html\"><asset:i18n name="texts" locale="${locale}" />\n</code></pre>\n<h2>Author</h2>\n<p>This plugin was written by <a href=\"mailto:d.ellermann@amc-world.de\">Daniel Ellermann</a>\n(<a href=\"http://www.amc-world.de\">AMC World Technologies GmbH</a>).</p>\n<h2>License</h2>\n<p>This plugin was published under the\n<a href=\"http://www.apache.org/licenses/LICENSE-2.0\">Apache License, Version 2.0</a>.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "i18n-enums", |
| "repo": "plugins", |
| "owner": "sbglasius", |
| "desc": "This plugin adds an annotation usable on Enums to easy add and implement the MessageSourceResolvable interface in an standard way throughout a project.", |
| "labels": [ |
| "enums", |
| "i18n" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/sbglasius/i18n-enums/issues", |
| "latestVersion": "5.0.0", |
| "updated": "2023-12-29T12:00:00.000Z", |
| "systemIds": [ |
| "org.grails.plugins:i18n-enums" |
| ], |
| "vcsUrl": "https://github.com/sbglasius/i18n-enums" |
| }, |
| "documentationUrl": "https://sbglasius.github.io/i18n-enums/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/dk/glasius/i18n-enums/maven-metadata.xml", |
| "readme": "<h1>i18n-enums</h1>\n<p>Documentation can be found here: http://sbglasius.github.io/i18n-enums/</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "i18n-javascript", |
| "repo": "plugins", |
| "owner": "salex772", |
| "desc": "Render all Grails i18n messages to Javascript", |
| "labels": [ |
| "i18n", |
| "javascript" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/salex772/i18n-javascript/issues", |
| "latestVersion": "0.4.2", |
| "updated": "2016-05-26T08:34:01.691Z", |
| "systemIds": [ |
| "org.grails.plugins:i18n-javascript" |
| ], |
| "vcsUrl": "https://github.com/salex772/i18n-javascript" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Render all Grails i18n messages to Javascript</h1>\n<h2>This plugin includes</h2>\n<ul>\n<li>i18nService to get all messages from messageSource bean</li>\n<li>i18nJs taglib to render in GSP</li>\n<li>I18nJsController to get JSON object in Javascript app</li>\n</ul>\n<h3>Install</h3>\n<p>Add to build.gradle</p>\n<pre><code>dependencies {\n compile "org.grails.plugins:i18n-javascript:0.4.2"\n}\n</code></pre>\n<h3>Config</h3>\n<p>In application.groovy add config with desired including and excluding prefixes</p>\n<pre><code>i18nJs {\n prefixInclude = [\n 'i18nJs'\n ]\n\n prefixExclude = [\n 'default', 'other'\n ]\n}\n</code></pre>\n<p>So 'i18nJs.page1.header' will be rendered whereas 'default.home.label' will not.\nWithout this all items from message.properties wiil be in JS</p>\n<h3>Get messages</h3>\n<p>In GSP use</p>\n<pre><code><g:i18nJs/>\n</code></pre>\n<p>to render all messages in output HTML</p>\n<p>Or make request to /I18nJs/getMessages within AJAX call.</p>\n<h3>Usage</h3>\n<pre><code>alert(I18N.getMessage('my.message.code'));\n</code></pre>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "jasper", |
| "repo": "plugins", |
| "owner": "puneetbehl", |
| "desc": "Grails jasper plugin", |
| "labels": [ |
| "reporting", |
| "jasper" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/puneetbehl/grails-jasper/issues", |
| "latestVersion": "2.1.0", |
| "updated": "2019-03-08T14:19:00.237Z", |
| "systemIds": [ |
| "org.grails.plugins:jasper" |
| ], |
| "vcsUrl": "https://github.com/puneetbehl/grails-jasper" |
| }, |
| "documentationUrl": "https://puneetbehl.github.io/grails-jasper/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails Jasper Plugin</h1>\n<p><a href=\"http://travis-ci.org/candrews/grails-jasper\"><img src=\"https://api.travis-ci.org/candrews/grails-jasper.png\" alt=\"Build Status\" /></a></p>\n<h1>Usage</h1>\n<p>For usage information, please see https://puneetbehl.github.io/grails-jasper/</p>\n<h1>How to build this plugin</h1>\n<p>run 'grailsw package-plugin'</p>\n<p>It will create a plugin archive.</p>\n<h1>Releasing a new version of this plugin</h1>\n<ol>\n<li>In JasperGrailsPlugin.groovy, set the plugin version to a non-snapshot version number (ex 1.6.1)</li>\n<li>run 'grailsw publish-plugin --stacktrace'</li>\n<li>Update the plugin version in JasperGrailsPlugin.groovy to be a snapshot (ex "1.6.2-SNAPSHOT")</li>\n</ol>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "jasper-reports", |
| "repo": "grails-plugins", |
| "owner": "9ci", |
| "desc": "Jasper reports Grails Plugin - Jasper reports Grails Plugin", |
| "labels": [ |
| "reporting", |
| "jasper" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/yakworks/spring-grails-kit", |
| "latestVersion": "5.0.10", |
| "updated": "2023-03-09T02:20:53.000Z", |
| "systemIds": [ |
| "org.yakworks:grails-jasper", |
| "org.grails.plugins:jasper-reports" |
| ], |
| "vcsUrl": "https://github.com/yakworks/spring-grails-kit" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/yakworks/grails-jasper/maven-metadata.xml", |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "jaxrs-core", |
| "repo": "grails-plugins", |
| "owner": "budjb", |
| "desc": "The jaxrs project is a set of Grails plugins that supports the development of RESTful web services based\r\non the Java API for RESTful Web Services.\r\n\r\nThe jaxrs-core plugin provides the main functionality of the plugin. This plugin does not include an implementing JAX-RS servlet provider, however, so one of the implementation plugins should be included in projects instead.", |
| "labels": [ |
| "jax-rs" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/budjb/grails-jaxrs/issues", |
| "latestVersion": "3.1.0", |
| "updated": "2018-10-01T20:15:04.093Z", |
| "systemIds": [ |
| "org.grails.plugins:jaxrs-core" |
| ], |
| "vcsUrl": "https://github.com/budjb/grails-jaxrs" |
| }, |
| "documentationUrl": "https://budjb.github.io/grails-jaxrs/3.x/latest/", |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/budjb/grails-jaxrs\"><img src=\"https://travis-ci.org/budjb/grails-jaxrs.svg?branch=grails-3.x\" alt=\"Build Status\" /></a></p>\n<h1>JAX-RS Plugin for Grails 3.x</h1>\n<p>See the documentation at http://budjb.github.io/grails-jaxrs/3.x/latest/.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "jaxrs-integration-test", |
| "repo": "grails-plugins", |
| "owner": "budjb", |
| "desc": "The jaxrs project is a set of Grails plugins that supports the development of RESTful web services based\r\non the Java API for RESTful Web Services.\r\n\r\nThe jaxrs-integration-test plugin provides classes to help with integration testing.", |
| "labels": [ |
| "testing", |
| "jax-rs" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/budjb/grails-jaxrs/issues", |
| "latestVersion": "3.1.0", |
| "updated": "2018-10-01T20:14:31.676Z", |
| "systemIds": [ |
| "org.grails.plugins:jaxrs-integration-test" |
| ], |
| "vcsUrl": "https://github.com/budjb/grails-jaxrs" |
| }, |
| "documentationUrl": "https://budjb.github.io/grails-jaxrs/3.x/latest/", |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/budjb/grails-jaxrs\"><img src=\"https://travis-ci.org/budjb/grails-jaxrs.svg?branch=grails-3.x\" alt=\"Build Status\" /></a></p>\n<h1>JAX-RS Plugin for Grails 3.x</h1>\n<p>See the documentation at http://budjb.github.io/grails-jaxrs/3.x/latest/.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "jaxrs-jersey1", |
| "repo": "grails-plugins", |
| "owner": "budjb", |
| "desc": "The jaxrs project is a set of Grails plugins that supports the development of RESTful web services based\r\non the Java API for RESTful Web Services.\r\n\r\nThe jaxrs-jersey1 plugin implements the Jersey 1.x JAX-RS implementation.", |
| "labels": [ |
| "jax-rs" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/budjb/grails-jaxrs/issues", |
| "latestVersion": "3.1.0", |
| "updated": "2018-10-01T20:14:58.513Z", |
| "systemIds": [ |
| "org.grails.plugins:jaxrs-jersey1" |
| ], |
| "vcsUrl": "https://github.com/budjb/grails-jaxrs" |
| }, |
| "documentationUrl": "https://budjb.github.io/grails-jaxrs/3.x/latest/", |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/budjb/grails-jaxrs\"><img src=\"https://travis-ci.org/budjb/grails-jaxrs.svg?branch=grails-3.x\" alt=\"Build Status\" /></a></p>\n<h1>JAX-RS Plugin for Grails 3.x</h1>\n<p>See the documentation at http://budjb.github.io/grails-jaxrs/3.x/latest/.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "jaxrs-restlet", |
| "repo": "grails-plugins", |
| "owner": "budjb", |
| "desc": "The jaxrs project is a set of Grails plugins that supports the development of RESTful web services based\r\non the Java API for RESTful Web Services.\r\n\r\nThe jaxrs-restlet plugin implements the Restlet JAX-RS implementation.", |
| "labels": [ |
| "jax-rs" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/budjb/grails-jaxrs/issues", |
| "latestVersion": "3.1.0", |
| "updated": "2018-10-01T20:15:00.863Z", |
| "systemIds": [ |
| "org.grails.plugins:jaxrs-restlet" |
| ], |
| "vcsUrl": "https://github.com/budjb/grails-jaxrs" |
| }, |
| "documentationUrl": "https://budjb.github.io/grails-jaxrs/3.x/latest/", |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/budjb/grails-jaxrs\"><img src=\"https://travis-ci.org/budjb/grails-jaxrs.svg?branch=grails-3.x\" alt=\"Build Status\" /></a></p>\n<h1>JAX-RS Plugin for Grails 3.x</h1>\n<p>See the documentation at http://budjb.github.io/grails-jaxrs/3.x/latest/.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "jaxrs-swagger-ui", |
| "repo": "grails-plugins", |
| "owner": "budjb", |
| "desc": "Integrates the Swagger UI with applications using JAX-RS resources.", |
| "labels": [ |
| "jax-rs" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/budjb/grails-jaxrs/issues", |
| "latestVersion": "3.1.0", |
| "updated": "2018-10-01T20:17:06.113Z", |
| "systemIds": [ |
| "org.grails.plugins:jaxrs-swagger-ui" |
| ], |
| "vcsUrl": "https://github.com/budjb/grails-jaxrs" |
| }, |
| "documentationUrl": "https://budjb.github.io/grails-jaxrs/3.x/latest/", |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/budjb/grails-jaxrs\"><img src=\"https://travis-ci.org/budjb/grails-jaxrs.svg?branch=grails-3.x\" alt=\"Build Status\" /></a></p>\n<h1>JAX-RS Plugin for Grails 3.x</h1>\n<p>See the documentation at http://budjb.github.io/grails-jaxrs/3.x/latest/.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "jenjir", |
| "repo": "maven", |
| "owner": "vahid", |
| "desc": "Grails Jenjir plugin", |
| "labels": [ |
| "jira", |
| "jenkins" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/vahidhedayati/grails-jenkins-plugin/issues", |
| "latestVersion": "3.0.2", |
| "updated": "2016-04-13T21:31:04.183Z", |
| "systemIds": [ |
| "org.grails.plugins:jenjir" |
| ], |
| "vcsUrl": "https://github.com/vahidhedayati/grails-jenkins-plugin" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>jenjir (Jenkins -> Jira) Grails plugin</h1>\n<p>Grails Jenjir plugin, will interact with Jenkins front end html interface using HTTPBuilder and push summary information to Jira if configured.</p>\n<p>You can use websocket feature to watch live builds / view historical build information or trigger a background process that will do the build. So long as userID is provided and Jenkins has authentication enabled, it will attempt to log in as that user without a password (by grabbing token off of Jenkins) This in short means you now have visibility of who triggered a build via Jenkins.</p>\n<p>Hooks/Triggers can be put in place to do two additional tasks.</p>\n<p>After build trigger known as processurl or if via websocket wsprocessurl</p>\n<p>After build summary - which with correct Jira details it will push this summary to all defined tickets within the changelog.</p>\n<h6>Dependency (Grails 2.X), in your conf/BuildConfig.groovy under plugins add :</h6>\n<pre><code class=\"language-groovy\">\tcompile ":jenjir:0.11"\n</code></pre>\n<p><a href=\"https://github.com/vahidhedayati/grails-jenkins-plugin/tree/grails2\">codebase for grails 2.X</a></p>\n<h6>Dependency (Grails 3.X), in your build.gradle under plugins add :</h6>\n<pre><code class=\"language-groovy\">\tcompile "org.grails.plugins:jenjir:3.0.2"\n</code></pre>\n<h6>Plugin will work with tomcat 7.0.54 + (inc. 8) running java 1.7+</h6>\n<h3>Video</h3>\n<p><a href=\"https://www.youtube.com/watch?v=XfsrBAa8aAg&index=5&list=PLfZr1vB6p8XJEQD5Dmox_PM_Y-_0y1Hz1\">Jenjir Part 1 : Older look</a></p>\n<p><a href=\"https://www.youtube.com/watch?v=CKv3TqWq4AQ&list=PLfZr1vB6p8XJEQD5Dmox_PM_Y-_0y1Hz1&index=4\">Jenjir Part 2 : Update showing multiple builds, basic grails build in Jenkins</a></p>\n<p><a href=\"https://www.youtube.com/watch?v=LOREp25Vz2Y&list=PLfZr1vB6p8XJEQD5Dmox_PM_Y-_0y1Hz1&index=3\">Jenjir Part 3 : Update showing Jenkins authentication</a></p>\n<p><a href=\"https://www.youtube.com/watch?v=bO3s8e4Qakc&index=2&list=PLfZr1vB6p8XJEQD5Dmox_PM_Y-_0y1Hz1\">Jenjir Part 4 : Non token authentication, custom Parameters</a></p>\n<p><a href=\"https://www.youtube.com/watch?v=665QHQ-8q0U&index=1&list=PLfZr1vB6p8XJEQD5Dmox_PM_Y-_0y1Hz1\">Jenjir part 5 : Automated build/deploy via jssh websockets async non websocket build</a></p>\n<p><a href=\"https://www.youtube.com/watch?v=5LYrnobvLns&index=8&list=PLfZr1vB6p8XJEQD5Dmox_PM_Y-_0y1Hz1\">Jenjir part 6 : Automated summary to Jira - From Jenkins change log to Jira ticket(s)</a></p>\n<p><a href=\"https://github.com/vahidhedayati/testjenkins\">Jenjir Test website testjenkins Grails 2X - used in videos</a>\n<a href=\"https://github.com/vahidhedayati/testjenkins\">Jenjir Test website testjenkins Grails 3X</a></p>\n<h3>Walkthrough</h3>\n<p>once plugin dependency added to BuildConfig, refreshed dependencies upon run-appp, you will be able to access this plugin via this url:</p>\n<pre><code>http://localhost:8080/yourapp/jen\n</code></pre>\n<p>This will load in the default index page which asks a few questions in order for you to interact with the given jenkins server/job. This can either be re-used or just make a direct connection using <jen:connect within your gsp.</p>\n<p>The plugin adds the following functionality to your existing grails application:</p>\n<h5>lists current build history items on right hand side</h5>\n<p>The build history info is sent via WebSockets. If you click an item the Jenkins console logs will be displayed. It displays status of job whether it passed/failed/cancelled/building or queued. If building it will additionally show running time and estimated time according to Jenkins, this was initially achieved by parsing page over and over, now moved locally as a JavaScript that works out difference of estimated time according to jobid/api/json estimateTime value set per Jenkins job. You can click stop to send a stop to backend Jenkins which will stop the build. Scheduled future builds will appeared as queued and you can also cancel them.</p>\n<h5>Build</h5>\n<p>This triggers a build and attempts to parse the live Jenkins console output, since it is building the results on Jenkins by default are returned using Ajax. The plugin attempts to do a similar thing but using WebSockets, it grab ready chunks of log output and display back on your page.</p>\n<h4>How to use</h4>\n<p><img src=\"https://raw.githubusercontent.com/vahidhedayati/grails-jenkins-plugin/master/documentation/quick-connect.jpg\" alt=\"Quick Connect\" /></p>\n<p><img src=\"https://raw.githubusercontent.com/vahidhedayati/grails-jenkins-plugin/master/documentation/connect.jpg\" alt=\"Connection details\" /></p>\n<h5>Example : Using taglib to make multiple calls to jenkins:</h5>\n<p>Controller:\nExampleController.groovy:</p>\n<pre><code class=\"language-groovy\">\tdef build() {\n\t\tdef goahead=params.goahead\n\t\t[goahead:goahead]\n\t}\n</code></pre>\n<p>GSP Page for build.gsp</p>\n<pre><code class=\"language-gsp\">\n\n<g:form>\n\t<input type="hidden" name="goahead" value="yes">\n\t<input type="submit" value="Build Jenkins job">\n</g:form>\n\n<g:if test="${goahead.equals('yes') }">\n\t<jen:connect divId="firstId" jenserver="localhost" jensport="9090" jensuser="" jenspass=""\n\tjensjob="my_build" jensprefix="" jensfolder="job" jenschoice="build" hideButtons="no" hideBuildTimer="no" />\n\n\t<jen:connect divId="secondId" jenserver="localhost" jensport="9090" jensuser="" jenspass=""\n\tjensjob="my_build2" jensprefix="" jensfolder="job" jenschoice="build" hideButtons="no" hideBuildTimer="no"/>\n</g:if>\n</code></pre>\n<p>So we have a button that asks to trigger build - if when clicked - its a self posting form that sets goahead=yes</p>\n<p>Then on the same page if this valus equals yes to call taglibs: results below:</p>\n<p><img src=\"https://raw.githubusercontent.com/vahidhedayati/grails-jenkins-plugin/master/documentation/double-build.jpg\" alt=\"Output from dual builds\" /></p>\n<p><img src=\"https://raw.githubusercontent.com/vahidhedayati/grails-jenkins-plugin/master/documentation/jenjir-buttons.jpg\" alt=\"Output from jenjir 0.2 all buttons\" /></p>\n<h1>Config.groovy variables required:</h1>\n<p>Please refer to <a href=\"https://github.com/vahidhedayati/grails-jenkins-plugin/wiki/configuration-items\">configuration</a>, this is all of below without comments</p>\n<p>Configure properties by adding following to grails-app/conf/Config.groovy under the "jenkins" key:</p>\n<pre><code class=\"language-groovy\">/*\n* This is the most important configuration\n* in my current version the hostname is being defined by tomcat start up setenv.sh\n* In my tomcat setenv.sh I have\n* HOSTNAME = $(hostname)\n* JAVA_OPTS="$JAVA_OPTS -DSERVERURL=$HOSTNAME"\n*\n* Now as per below the hostname is getting set to this value\n* if not defined wschat will default it localhost:8080\n*\n*/\njenkins.wshostname = System.getProperty('SERVERURL')+":8080"\n// can be overridden via tag lib : wshostname="something"\n\n\n/* timeout\n* This is the default timeout value for websocket connection\n* If you wish to get user to be timed out if inactive set this to a millisecond value\n*/\njenkins.timeout = 0\n\n\n/*\n* HTTP Builder socket/connection timeouts by default values are as below\n*/\njenkins.http.connection.timeout=10\njenkins.http.socket.timeout=30\n\n\n\n/*\n* Optional : not required - unless different to defaults\n* Jenkins hide Login Pag: default 'no'\n* choices : no/yes\n* Choose if default index page from plugin can be loaded\n*/\njenkins.hideLoginPage = 'no'\n\n\n\n/*\n* Optional : not required - unless different to defaults\n* Jenkins internal consoleLog : default '/consoleFull'\n*/\njenkins.consoleLog = '/consoleFull'\n// can be overridden via tag lib by definining: jensLog="something"\n\n\n\n/*\n* Optional : not required - unless different to defaults\n* Jenkins internal buildend : default '/build?delay=0sec'\n*/\njenkins.buildend = '/build?delay=0sec'\n// can be overridden via tag lib : jensbuildend="something"\n\n\n/*\n* Optional : not required - unless different to defaults\n* Jenkins internal progressiveuri : default '/logText/progressiveHtml'\n*/\njenkins.progressiveuri = '/logText/progressiveHtml'\n// can be overridden via tag lib : jensprogressive="something"\n\n\n/*\n* Optional : not required - unless different to defaults\n* Jenkins hide build/dashboard buttons : default 'no'\n* choices : no/yes\n*/\n\njenkins.hideButtons = 'no'\n\n/*\n* Optional : not required - unless different to defaults\n* Jenkins hide build button : default 'no'\n* choices : no/yes\n*/\njenkins.hideTriggerButton = 'no'\n\n/*\n* Optional : not required - unless different to defaults\n* Jenkins hide dashboard/buildhistory button : default 'no'\n* choices : no/yes\n*/\njenkins.hideDashBoardButton = 'no'\n\n/*\n* Optional : your own custom processing url for when builds are triggered\n* provide a full url back to a controll action so that when it completes a build\n* notification is sent to controller and you can then call further services on output\n*/\njenkins.processurl = "http://localhost:8080/testjenkins/test/parseJenPlugin"\n\n\n/*\n* Optional : your own custom processing url for when builds are triggered\n* provide a full url back to a controll action so that when it completes an extra \n* action button is provided\n* the process url could in theory call another end point to lets say jssh and do a live deployment\n*/\njenkins.wsprocessname = "Deploy"\njenkins.wsprocessurl = "http://localhost:8080/testjenkins/test/parseJenPluginDeploy"\n\n\n\n// Auto submit wsprocess url ?\njenkins.autosubmit = "yes"\n\n// Enhanced option for secondary action \n// If this is set as true it will only attempt to call \n// processurl/wsprocess url triggers if result was successfull\njenkins.process.on.success = true\n\n/* 0.3 feature \n* if app has wsprocessurl additional button to buildOnly appears \n* which can be disabled if this is set to no\n*/\njenkins.show.build.only.button = "yes"\n\n\n// If once built you wish to send summary enable this as true\njenkins.sendSummary = true\n\n// This must also be set to yes to show summary and send it once built. \njenkins.showsummary = "yes"\n\n\n\n/*\n* Jira configuration - refer to summary section below:\n* Don't enable any of this if you are not looking to push anything to Jira.\n*/\njenkins.sendtoJira = 'yes'\n\njenkins.jiraServer = 'http://jira-test.yourdomain.com'\njenkins.jiraUser = 'automation_account'\njenkins.jiraPass = 'automation_account_password'\n\n/*\n* This is the url usually to access the ticket for viewing - used to test if ticket is valid\n* if not defined will default to /browse/\n*/\njenkins.jira.AccessUri = "/browse/"\n\n\n/* \n * There are various send types :\n * comment -- adds the summary output as a comment to valid jira ticket \n * customfield -- adds the summary output to provided customfield ID - please note customfield must have correct screen perms for it to work\n * updatecustomfield -- gets current input if different to new input adds them together to customfield\n * description -- updates ticket description with the summary\n * comdesc -- updates ticket description and adds a comment both containing the summary\n */\njenkins.jiraSendType = 'customfield' \n// If you have defined working option customfield then define the customfield id for this configuration item:\njenkins.customField = '12330' // the id of your customfield\n\n\n/*\n* API Api Info - send this as part of summary?\n*/\njenkins.sendApi = true // true/false - by default false\n// SendApi - sub fields:\n/* API ChangeSet - send this as part of summary?*/\njenkins.sendChangeSet = true // true/false - by default false\n/*API culprits - send this as part of summary?*/\njenkins.sendCulprits = true // true/false - by default false\n/*API full display name - send this as part of summary?*/\njenkins.sendFdn = true // true/false - by default false\n/*API Build Id - send this as part of summary?*/\njenkins.sendBuildId = true // true/false - by default false\n/*API Build UserID/Name - send this as part of summary?*/\njenkins.sendBuildUser = true // true/false - by default false\n\n/*\n* Jenkins BuildID Change Logs - send this as part of summary?\n*/\njenkins.sendChanges = true // true/false - by default false\n\n/*\n* Jenkins BuildID Specific parse Info - send this as part of summary?\n*/\njenkins.sendParseConsole = true // true/false - by default false\n/*LogParser Look for Building Work space ? send this as part of summary?*/\njenkins.parseBuildingWorkSpace = true // true/false - by default false\n/*LogParser Look for Building ? send this as part of summary?*/\njenkins.parseBuilding = true // true/false - by default false\n/*LogParser Look for Done Creating? send this as part of summary?*/\njenkins.parseDoneCreating = true // true/false - by default false\n/*LogParser Look for Last valid trans ? send this as part of summary?*/\njenkins.parseLastTrans = true // true/false - by default false\n\n\n/* Buttons on websocket page :\n* set these as you see here change to no if you wish \n* not for them to appear on the webpage.\n* you can override these values from within either taglib call too\n*/\njenkins.summaryViewButtons = "yes"\njenkins.summaryFileButton = "yes"\njenkins.summaryChangesButton = "yes"\n\njenkins.jiraButtons = "yes"\njenkins.jiraOverwriteButton = "yes"\njenkins.jiraAppendButton = "yes"\njenkins.jiraCommentButton = "yes"\n\n\n/*\n* formType can be defined as taglib (overrides Config.groovy )\n* defines the wsprocessurl form type (either normal which takes over page or remote which updates divId)\n* if remote it will create new element ID called return_${divId} what ever you defined divId to be \n* so if multi call - on each call a return_ element is created\n*/\njenkins.formType = "normal" // either normal or remote\n\n// If you define formType = "remote" you will also need two more config or tag lib calls:\n// Both of these should actually be part of above wsprocess url \njenkins.remoteController= 'Your controller that is being called'\njenkins.remoteAction = 'Your action' \n\n</code></pre>\n<p>When submitted, the controller has been set to recieve parameters and call a tag lib which can also be used by you guys to call a jenkins build on the fly from within your gsp.</p>\n<pre><code class=\"language-gsp\"><jen:connect\ndivId="someId"\njenserver="${jenserver }"\njensport="${jensport}"\njensuser="${jensuser}"\njenspass="${jenspass}"\njensjob="${jensjob}"\njensprefix="${jensprefix}"\njensfolder="${jensfolder}"\njensport="${jensport}"\njenschoice="${jenschoice}"\n\n/>\n</code></pre>\n<p>Optional override taglibs: (Refer to above Config.groovy to understand what these are:)</p>\n<pre><code class=\"language-gsp\"><jen:connect\n....\nhideButtons="${hideButtons }"\nhideTriggerButton="${hideTriggerButton }"\nhideDashBoardButton="${hideDashBoardButton }"\njensLog="something"\nwshostname="something"\njensprogressive="something"\njensLog="something"\ndynamicParams = "['deployType':['background', 'live']]"\ncustomParams="[appId: '123', appName: 'crazyApp', appEnv: 'test' ]"\nprocessurl="http://your_process_url/controller/action"\nwsprocessurl="http://your_process_url/controller/action"\nwsprocessname="Deploy code"\n\n// Buttons\nsummaryViewButtons = "yes"\nsummaryFileButton = "yes"\nsummaryChangesButton = "yes"\n\njiraButtons = "yes"\njiraOverwriteButton = "yes"\njiraAppendButton = "yes"\njiraCommentButton = "yes"\n// if you have wsprocess url - 2 buttons would appear \nbuildOnlyButton = "yes"\n\nformType = "normal" // normal or remote\n// if remote define these:\nremoteController = 'Your controller that is being called'\nremoteAction = 'Your action' \n/>\n</code></pre>\n<p>customParams - if you have configured a processurl in your config you can pass values back</p>\n<p>Results are typically returned to process url like this:</p>\n<pre><code>[files:{"type":"WAR","name":"target/testmodaldynamix-0.1.war"},result:SUCCESS, token:9cf496bb07021a1d788f8838159291cf, buildUrl:http://localhost:9090/job/my_build/175, customParams:{appId=123, appName=crazyApp, appEnv=test}, buildId:175, job:/job/my_build, server:http://localhost:9090, user:cc, action:parseJenPlugin, format:null, controller:test]\n</code></pre>\n<h5>Refer further down on information on how to retrieve customParams</h5>\n<p>So long as you provide the above values from within a gsp page it should load in the results back on the page.</p>\n<p>You should be able to call it multiple times and provide different divId's for each call - to get multiple builds on one gsp page.</p>\n<p>Tested on recent/older variants of Jenkins. May still fail on others, please post an issue with specific Jenkins version for me to look into.</p>\n<p>Alternative more direct connect tag lib call:</p>\n<pre><code class=\"language-gsp\"><jen:dirconnect\n\t\tdivId="someId"\n\t\tjensurl="http://jenkins-server:port/job/jobname"\n\t\tjensuser="current_user"\n\t\tjenschoice="dashboard"\n\t\tjensjob="jobname"\n\t/>\n</code></pre>\n<p>Optional - if you have configured a processurl in your config you can pass values back\nAll optional above should work</p>\n<pre><code class=\"language-gsp\">processurl="http://your_process_url/controller/action"\nwsprocessurl="http://your_process_url/controller/action"\nwsprocessname="Deploy code"\ncustomParams="[appId: '123', appName: 'crazyApp', appEnv: 'test' ]"\n</code></pre>\n<h4>Summary information:</h4>\n<p>There is a new option called summary that appears next to the build ID's this Summary tries to grab information from 3 segments of Jenkins and if configured will push this information to a customfield on Jira.</p>\n<p>It queries:</p>\n<p>The build Logs and tries to grab working folder, produced file and a line called last trans if it exists.\nChange screen - grabs all related build changes to be pushed through\nApi summary - a variety of information from the api output.</p>\n<p>The most important aspect of this is that within the changes logs, it looks for a ticket ID either seperated by : or -</p>\n<p>so</p>\n<pre><code>AB-1102 : Description \n</code></pre>\n<p>or :</p>\n<pre><code>AB-1102 - Description\n</code></pre>\n<p>Where AB-1102 will be the ticket number, this will then update this jira ticket with the summary provided</p>\n<p><img src=\"https://raw.githubusercontent.com/vahidhedayati/grails-jenkins-plugin/master/documentation/jen-changes.jpg\" alt=\"Jira ticket number\" /></p>\n<p>Refer to above configuration items for the required jenkins configuration in your config.groovy.</p>\n<p>It will parse through the changes logs, and for each ticket found - it will attempt to push the response to all tickets.</p>\n<p>For the summary information to work properly I found I had to add two blank configuration items to my config.groovy:</p>\n<pre><code>jenkins.processurl=""\n\njenkins.wsprocessurl=""\n</code></pre>\n<p>These could actually be filled with a value, its just if not defined it returns some groovy object</p>\n<p>####Async Build (Non Websocket)\nThis will trigger a service that does a background build, whilst building it will check for completion, once completed it will trigger process url\nand send back results to it.</p>\n<pre><code class=\"language-gsp\"><jen:asyncBuild\n\n\turl="http://host:post/job/JOB_NAME"\n\t\n\tcustomParams="[appId:'MyCurrentJob', appDetails: 'Something']"\n\t\n\t\n\tjensuser="MyUserId"\n\t\n\t\n\tprocessurl="http://localhost:8080/testjenkins/test/myresults"\n\t\n\t\n\t/>\n</code></pre>\n<p>The processurl - is a background process that has no interaction with your front end view, runs in the background. When a job completes it returns its status plus a variety of other parameters to the given url.</p>\n<p>The wsprocessurl - is a url which wsprocessname is the display name for the link within your websocket connected page. Once the job is completed a button is provided on the same websocket page to trigger the next controller/action which could in short be another taglib call that calls yet another websocket to process something else.\nYou can enable both processurl and wsprocessurl - they could be doing different things if needs be. It would not be a good idea to call the same controller/action since it will then lead to duplicated actions.</p>\n<h3>Authenticated Jenkins howto:</h3>\n<p>Once you have configured global security of some form on your Jenkins server. Authentication should work via Jenkins so long as you either provide just the username to the initial form, or via the taglib call.</p>\n<h5>The plugin will attempt to grab the user authToken from the given server, if it can successfully retrieve this without authentication then the userToken is automatically set.</h5>\n<p>So by simply providing a valid username, the plugin will try do the rest and authenticate as the given user. With this you can easily gain a better overview of who is trigerring the build on Jenkins backend.</p>\n<p>Whilst building if the current user has got authenticated then the user will appear above build logs otherwise current user will show anonymous.</p>\n<h5>To manually define authToken per user(known as jenspass)</h5>\n<p>First thing first, you need to enable authentication on Jenkins, our systems uses AD plugin and connects a user through to AD.\nOnce a user has logged in then goto:</p>\n<ol>\n<li>Your Jenkins server:</li>\n</ol>\n<p>http://your_jenkins:port/user/USERID/configure</p>\n<p>Click on show API Token (This is an example token)\n9a997cc1a954ac3a5ac59ea97c17a851</p>\n<p>With this information now login using the front end using the username and the token as the password - this now triggers builds as the user.</p>\n<h6>customParams Retrieval</h6>\n<p>This is our example parseJenplugin call, the results are actually in JSON format, so as per what fed in in above example. I am now extracting each value on processurl:</p>\n<pre><code class=\"language-groovy\">def parseJenPlugin() { \n\t\tprintln ":::> ${params} <:::"\n\t\t\n\t\t// This is an example itterating through files:\n\t\t// files:{"type":"WAR","name":"target/testmodaldynamix-0.1.war"}\n\t\t// where key will be type or name\n\t\t// value will by type of file and file name as per jenkins output in the build logs.\n\t\t// you may wish to set :\n\t\t//jenkins.parseBuilding = false\n\t\t// in config.groovy so that Building files also do not appear in :\n\t\t//jenkins.parseDoneCreating = true\n\n\t\tif (params.files) {\n\t\t\tJSONObject files1=JSON.parse(params.files)\n\t\t\tfiles1.each { k,v->\n\t\t\t\tprintln "-- FILE_TYPE: $k ||| FILE_NAME: $v"\n\t\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\tdef pp=params.customParams\n\t\tdef apps\n\t\tif (pp) {\n\t\t\tdef data = JSON.parse(params.customParams)\n\t\t\tdef appId=data?.appId\n\t\t\tdef appName=data?.appName\n\t\t\tdef appEnv=data?.appEnv\n\t\t\tprintln "--- Our Custom values passed from initial taglib call are:"\n\t\t\tprintln " AppID: $appId | AppName: $appName | AppEnv: $appEnv"\n\t\t\t/*\n\t\t\t * <jen:connect divId="firstId" \n\t\t\t\t\t.....\n\t\t\t\t\tcustomParams="[appId: '123', appName: 'crazyApp', appEnv: 'test' ]"\n\t\t\t\t\t/>\n\t\t\t\t\t\n\t\t\t\t\twhich has produced:\n\t\t\t\t\t\n\t\t\t\t\t:::>[files:{"type":"WAR","name":"target/testmodaldynamix-0.1.war"},result:SUCCESS, token:9cf496bb07021a1d788f8838159291cf, buildUrl:http://localhost:9090/job/my_build/182, customParams:{appId=123, appName=crazyApp, appEnv=test}, buildId:182, job:/job/my_build, server:http://localhost:9090, user:cc, action:parseJenPlugin, format:null, controller:test] <:::\n--- Our Custom values passed from initial taglib call are:\n AppID: 123 | AppName: crazyApp | AppEnv: test\n\n\t\t\t\t\t\n\t\t\t * \n\t\t\t */\n\t\t\t\n\t\t\t\n\t\t}\n\t\trender ""\n\t}\n</code></pre>\n<h1>Jenjir Change information:</h1>\n<pre><code>0.10-SNAPSHOT - Environment Issue if attempting to run as a plugin within development project\n\n0.10 - \tIssues with gsp javascript - variables not bound to dynamic call - issue with previous size - \n\t\tnow defaulted to first array value for any amount of input. Since initial value may not be default action\n\t\t\n0.9\t-\tMinor issues - config options in endpoint set to default to '' if not set - was returning object before.\n\t\tCheck to see if dynamicValues size = 1 if so then set this to be the default value via websockets on _process.gsp\n\t\t\n0.8 - \tMinor bugs : if jira front end buttons disabled -small tag was left open making list smaller and smaller - fixed.\n\t\tNewly introduced successProcess in jenService required bid as String from the local call - causing issues doing next phase action\n\t\tNewly added Additional function button appeared on all passed jobs - only first requires this value. - fixed\n\t\t\n0.7\t-\tBug in appendCustomField + customField functions fixed. New button added labelled as wsprocessname Value. This gives addtional functionality \n\t\tto first in list - or last Build ID - if it built successfully a trigger to trigger secondary action is now available.\n\t\tIf a build is triggered this icon disappears since the workspace is likely to no longer include last built file.\n\t\t\n\t\t\n0.6\t-\tDynamicParams added as an additional input to <jen:connect <jen:dirconnect\n\t\tThis is defined by a key followed by values \n\t\tdynamicParams = "['deployType':['background', 'live']]"\n\t\tWith this set a select box is created on frontend which when user selects defined option the value is passed back to \n\t\tprocessurl or wsprocessurl after build is completed \n\t\tThis is now allowing dynamic value selection alongside the build/deploy task\n\t\t\n\t\t\n0.5 - \tHoping this be the last update for a while the remoteForm functionality would have only worked on autoSubmit=yes\n\t\tThis has now been corrected so remoteForms will work on autosubmit true or not.\n\t\t\n0.4 - \tremote form submission feature enabled meaning on multi build tasks with multi element all results should be \n\t\treturned/triggered on the same page that did the call. Refer to configuration items for remoteform options (formType)\n\t\t \n0.3 - \tCleanup of config calls within services. Addition just Build button added if end app has processurl name/action defined.\n\t\tBetter logics around displaying wsprocessname with Build button.\n\t\t\n0.2 - \tTidy up - moved getlastBuild as lastBuild into jenService - removed duplicate calls. \n\t\tFixed wsprocess/process urls to both include files produced json as output params\n\t\tAdded socket/http connection timeouts to HTTPBuilder calls.\n\t\t\n0.1 - release\n</code></pre>\n<h3>Jenjir Issues/Bugs:</h3>\n<h5>1. Prefix jenkins servers.</h5>\n<p>If you have a server with a prefix then you will find the quick connect method will not work for you, you need to use the manaully full detail connection method since the prefix is required for the url and uri.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "jesque", |
| "repo": "grails-plugins", |
| "owner": "ctoestreich", |
| "desc": "Grails Jesque Plugin", |
| "labels": [ |
| "jedis", |
| "jesque", |
| "queue", |
| "redis" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/Grails-Plugin-Consortium/grails-jesque/issues", |
| "latestVersion": "1.2.1", |
| "updated": "2017-04-19T17:22:29.457Z", |
| "systemIds": [ |
| "org.grails.plugins:jesque", |
| "org.grails.plugins:grails-jesque" |
| ], |
| "vcsUrl": "https://github.com/Grails-Plugin-Consortium/grails-jesque" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "jesque-admin", |
| "repo": "plugins", |
| "owner": "uberall", |
| "desc": "Admin UI for the Grails Jesque Plugin", |
| "labels": [ |
| "jesque" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/uberall/jesque-admin/issues", |
| "latestVersion": "0.6.9", |
| "updated": "2020-08-21T18:35:05.302Z", |
| "systemIds": [ |
| "org.grails.plugins:jesque-admin", |
| "org.grails.plugins:grails-jesque-admin" |
| ], |
| "vcsUrl": "https://github.com/uberall/jesque-admin" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>jesque-admin</h1>\n<p>A User interface for <a href=\"https://grails.org/plugins.html#plugin/jesque\">Jesque</a> powered by grails and react.</p>\n<h1>Installation</h1>\n<p>Just add jesque-admin to your dependencies</p>\n<pre><code>dependencies {\n ...\n compile 'org.grails.plugins:jesque-admin:0.6.6'\n}\n</code></pre>\n<h1>Usage</h1>\n<p>Make sure that jesque is enabled. If you do not have the "default mapping for controllers" in your UrlMappings.groovy you will have to add mappings for jesque-admin to your UrlMappings.groovy\nThis plugin does not expose any UrlMappings by itself for security reasons. Job payloads can hold sensitive data and having an "open" jesque-admin interface can lead to breaches.</p>\n<pre><code>"/jesque/"(controller: 'jesqueAdmin', action: 'index')\n"/jesque/api/overview"(controller: 'jesqueAdmin', action: 'overview')\n"/jesque/api/queues"(controller: 'jesqueAdminQueue', action: 'list')\n"/jesque/api/queues/$name"(controller: 'jesqueAdminQueue', action: 'details', method: "GET")\n"/jesque/api/queues/$name"(controller: 'jesqueAdminQueue', action: 'remove', method: "DELETE")\n"/jesque/api/jobs"(controller: 'jesqueAdminStatistics', action: 'jobs', method: "GET")\n"/jesque/api/jobs"(controller: 'jesqueAdminJob', action: 'enqueue', method: "POST")\n"/jesque/api/jobs/removeDelayed"(controller: 'jesqueAdminJob', action: 'removeDelayed', method: "POST")\n"/jesque/api/jobs/failed"(controller: 'jesqueAdminJob', action: 'failed', method: "GET")\n"/jesque/api/jobs/failed/$id"(controller: 'jesqueAdminJob', action: 'retry', method: "POST")\n"/jesque/api/jobs/failed/$id"(controller: 'jesqueAdminJob', action: 'remove', method: "DELETE")\n"/jesque/api/jobs/failed"(controller: 'jesqueAdminJob', action: 'clear', method: "DELETE")\n"/jesque/api/jobs/triggers"(controller: 'jesqueAdminJob', action: 'triggers', method: "GET")\n"/jesque/api/jobs/triggers/$name"(controller: 'jesqueAdminJob', action: 'deleteTrigger', method: "DELETE")\n"/jesque/api/jobs/$job"(controller: 'jesqueAdminStatistics', action: 'list', method: "GET")\n"/jesque/api/workers"(controller: 'jesqueAdminWorker', action: 'list', method: 'GET')\n"/jesque/api/workers"(controller: 'jesqueAdminWorker', action: 'manual', method: 'POST')\n"/jesque/api/workers/$name"(controller: 'jesqueAdminWorker', action: 'remove', method: 'DELETE')\n"/jesque/api/workers/pause"(controller: 'jesqueAdminWorker', action: 'pause', method: 'GET')\n"/jesque/api/workers/resume"(controller: 'jesqueAdminWorker', action: 'resume', method: 'GET')\n</code></pre>\n<p>You can freely change "/jesque/api/" to whatever you want but i highly recommend not to change anything that comes after that.</p>\n<h1>Job Statistics</h1>\n<p>jesque-admin comes with mechanics to gather statistics like start, end and runtimes of Jobs. All this is done by using a specific Worker Listener.\nAll you have to do is enable the statistics collecting feature in you application.yml (or .groovy):</p>\n<pre><code>grails:\n jesque:\n statistics:\n enabled: true\n max: 100 // the maximum number of statistics PER JOB CLASS to store\n</code></pre>\n<p>you also have to set <code>JesqueJobStatisticsWorkerListener</code> as a custom listener:</p>\n<pre><code>grails:\n jesque:\n enabled: true\n custom:\n listener:\n clazz: grails.plugins.jesque.admin.JesqueJobStatisticsWorkerListener\n</code></pre>\n<p>After restarting your App you should find a list menu item under "jobs" in jesque-admin which lets you browse past jobs being processed.</p>\n<h1>Development</h1>\n<p>If you want to extend jesque-admin or help developing it further simply start by:</p>\n<ol>\n<li>Run <code>gradle bootRun -Djesque.admin.devel=true</code> (or <code>grails run-app</code> or run the main method in Application.groovy whatever you prefer)</li>\n<li>Run <code>npm i</code> in the root folder of this plugin</li>\n<li>Run <code>npm run devel</code></li>\n</ol>\n<p>Note: you need node.js version <code>6.9.0</code></p>\n<p>In order to build the project run the following commands:</p>\n<ol>\n<li><code>npm run package</code></li>\n<li><code>./gradlew publishToMavenLocal</code></li>\n</ol>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "jms", |
| "repo": "plugins", |
| "owner": "gpc", |
| "desc": "Grails jms plugin", |
| "labels": [ |
| "jms", |
| "messaging" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/gpc/jms/issues", |
| "latestVersion": "4.0.2", |
| "updated": "2024-02-15T14:45:33.000Z", |
| "systemIds": [ |
| "io.github.gpc:jms", |
| "org.grails.plugins:jms" |
| ], |
| "vcsUrl": "https://github.com/gpc/jms" |
| }, |
| "documentationUrl": "https://gpc.github.io/jms/latest/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/io/github/gpc/jms/maven-metadata.xml", |
| "readme": "JMS integration for Grails. See <a href=\"https://gpc.github.io/jms/latest/\">documentation</a> for more information." |
| }, |
| { |
| "bintrayPackage": { |
| "name": "joda-time", |
| "repo": "plugins", |
| "owner": "gpc", |
| "desc": "Joda-Time Plugin", |
| "labels": [ |
| "date" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/gpc/joda-time/issues", |
| "latestVersion": "2.1.0", |
| "updated": "2018-06-19T11:29:37.127Z", |
| "systemIds": [ |
| "org.grails.plugins:joda-time" |
| ], |
| "vcsUrl": "https://github.com/gpc/joda-time" |
| }, |
| "documentationUrl": "https://gpc.github.io/joda-time/", |
| "mavenMetadataUrl": null, |
| "readme": null |
| }, |
| { |
| "deprecated": "Source repository for this entry is archived. This entry should probably be removed from the registry.", |
| "bintrayPackage": { |
| "name": "json-annotations-marshaller", |
| "repo": "plugins", |
| "owner": "tony75", |
| "desc": "Grails 3 plugin for managing JSON marshalling through annotations", |
| "labels": [ |
| "json" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "", |
| "latestVersion": "v1.0", |
| "updated": "2016-03-31T16:16:47.970Z", |
| "systemIds": [ |
| |
| ], |
| "vcsUrl": "https://github.com/tony75/grails3-json-annotations-marshaller" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>json-apis</h1>\n<h2>Grails plugin for managing multiple JSON apis using domain class annotations</h2>\n<p>The goal of this plugin is to help convert Grails domain classes into various\nJSON representations needed in different parts of your web application or to\nsupport various API versions.</p>\n<p>Features:</p>\n<ul>\n<li>Allows you to declare multiple named JSON configurations for different use cases</li>\n<li>Configuration is very straightforward: all that is required is to mark domain class\nproperties with a single annotation naming the configurations under which that\nproperty should be included in the serialized JSON object</li>\n<li>Works for collections as well as <code>belongsTo</code> properties</li>\n<li>Enables developers to avoid the circular object reference problem elegantly by\ndefining appopriate namespaces - this way it is possible to start the serialization\neither in a parent or child entity, depending on the use case</li>\n<li>Works for objects serialized inside a <a href=\"http://grails.org/doc/latest/guide/theWebLayer.html#moreOnJSONBuilder\">JSON builder</a></li>\n<li>Uses the Grails' <code>ObjectMarshaller</code> mechanism under the hood</li>\n<li>Detects API changes during development time live reloads</li>\n</ul>\n<h2>Example of use</h2>\n<p>Several API variants can be easily defined in domain classes by annotating properties with\n<code>JsonApi</code> and providing a list of API profile names under which that property should appear in the\nresulting JSON. Marking a property with the <code>JsonApi</code> annotation but providing no API names will\ninclude that property in all APIs. The database identity property will always be included\nautomatically. One could for instance define the following domain class:</p>\n<pre><code class=\"language-groovy\">import grails.plugins.jsonapis.JsonApi\n\nclass User {\n\t@JsonApi\n\tString screenName\n\n\t@JsonApi('userSettings')\n\tString email\n\n\t@JsonApi(['userSettings', 'detailedInformation'])\n\tString twitterUsername\n}\n</code></pre>\n<p>Then in the controller one would call the desired named JsonApi configuration to get only\nthe fields defined for that API. The following code:</p>\n<pre><code class=\"language-groovy\">JSON.use("detailedInformation")\nrender person as JSON\n</code></pre>\n<p>...would convert the <code>person</code> object into JSON containing the <code>id</code>, <code>screenName</code> and <code>twitterUsername</code>\nproperties but not the <code>email</code>. It works for collections as well, converting each collection\nmember using the same API profile that was used to convert the parent:</p>\n<pre><code class=\"language-groovy\">static hasMany = [\n\tpets: Pet\n]\n@JsonApi('detailedInformation')\nSet pets\n</code></pre>\n<p>To include a domain object's parent in a JSON API, declare a <code>belongsTo</code> property explicitly\nand annotate it with <code>JsonApi</code> (but be careful not to create circular paths by including both\nends of a <code>belongsTo</code>/<code>hasMany</code> pair):</p>\n<pre><code class=\"language-groovy\">static belongsTo = [\n\tuser:User\n]\n\n@JsonApi('petDetails') \nUser user\n</code></pre>\n<p>JSONBuilder is supported, too:</p>\n<pre><code class=\"language-groovy\">JSON.use("userSettings")\nrender(contentType: "text/json") {\n user = User.first()\n pet = Pet.first()\n}\n</code></pre>\n<h2>Future plans</h2>\n<ul>\n<li>Detect circular APIs and display a warning on startup, perhaps disable them entirely</li>\n<li>Add a script/controller that would document the registered APIs in one or more formats</li>\n<li>Read the domain class annotations and produce configurations for those 3rd party JSON\nrenderers which currently seem to perform better than the native Grails implementation</li>\n</ul>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "jssh", |
| "repo": "maven", |
| "owner": "vahid", |
| "desc": "Grails j2ssh plugin", |
| "labels": [ |
| "ssh" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/vahidhedayati/jssh/issues", |
| "latestVersion": "3.0.2", |
| "updated": "2016-04-13T21:24:25.384Z", |
| "systemIds": [ |
| "org.grails.plugins:jssh" |
| ], |
| "vcsUrl": "https://github.com/vahidhedayati/jssh" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>jssh</h1>\n<h3>Side note - similar / related projects</h3>\n<ul>\n<li>\n<p><a href=\"https://github.com/vahidhedayati/RemoteSSH\">RemoteSSH</a></p>\n</li>\n<li>\n<p><a href=\"https://github.com/vahidhedayati/jssh\">jssh (this)</a></p>\n</li>\n</ul>\n<p>Grails jssh Plugin based on j2ssh library, provides ssh connection with features/facilities to execute remote shell commands. Provides connection via websockets as well as ajax/polling.</p>\n<p>Websocket ssh interaction can be incorporated to an existing grails app running ver 2>+. Supports both resource (pre 2.4) /assets (2.4+) based grails sites. Plugin will work with tomcat 7.0.54 + (8 as well) running java 1.7 +</p>\n<h6>Dependency (Grails 2.X):</h6>\n<pre><code>compile ":jssh:1.10"\n</code></pre>\n<p><a href=\"https://github.com/vahidhedayati/jssh/tree/grails2\">codebase for grails 2.X</a></p>\n<h6>Dependency (Grails 3.X) :</h6>\n<pre><code class=\"language-groovy\">\tcompile "org.grails.plugins:jssh:3.0.2"\n</code></pre>\n<p>This plugin is a web based basic putty i.e. sshkey or username/password. It provides a variety of taglib calls that you can call from within your application to then interact with SSH connection(s) to Unix/Linux/OSx machines.</p>\n<p>Once you have successfully configured connected. Your browser will provide something similar to a shell console and with the latter Websocket calls you can literally interact live with your SSH connection(s).</p>\n<h2>Config.groovy additions required:</h2>\n<p><a href=\"https://github.com/vahidhedayati/jssh/wiki/Config.groovy-values\">Config.groovy variables</a></p>\n<p>Test site:</p>\n<p><a href=\"https://github.com/vahidhedayati/testjssh-grails3\">grails 3 demo site</a> refer to application.groovy for config values</p>\n<p><a href=\"https://github.com/vahidhedayati/test-jssh\">grails 2 demo site</a></p>\n<h2>Change Release information</h2>\n<p><a href=\"https://github.com/vahidhedayati/jssh/wiki/VersionInfo-grails3\">Change information</a></p>\n<h2>Videos</h2>\n<p><a href=\"https://www.youtube.com/watch?v=rGIWeLMeC5o\">jssh 1.6 admin interface / cloning of accounts + viewing historical logs/commands</a></p>\n<p><a href=\"https://www.youtube.com/watch?v=tkGavxbrnh8\">jssh 1.3 sshuser configuration per webuser + command restrictions(blacklist) / command rewrites</a></p>\n<p><a href=\"https://www.youtube.com/watch?v=HcJauTC6b8I\">jssh 1.0 broadcast ssh commands to multiple remote hosts 8 Mins</a></p>\n<p>Video of jssh 0.9, whilst waiting on creations of stuff there was some discussion into the back-end plugin code and how it interacts via websockets:</p>\n<p><a href=\"https://www.youtube.com/watch?v=r-dBVUmT9Uo\">jssh 0.9 full walk through 43 mins? wow a lot of BS :)</a></p>\n<h2>Interaction Methods:</h2>\n<h2>1> <a href=\"https://github.com/vahidhedayati/jssh/blob/master/grails-app/views/connectSsh/scsocketconnect.gsp\">Socket Client/Server</a></h2>\n<h5><a href=\"https://github.com/vahidhedayati/jssh/wiki/mutli-connection---broadcasting-to-multi-nodes\">mutli-connection broadcasting to multiple SSH connections</a></h5>\n<p><a href=\"https://github.com/vahidhedayati/jssh/wiki/Websocket-client-server-taglib-call\">New Client/Server Websocket SSH tag lib call</a></p>\n<p><a href=\"https://github.com/vahidhedayati/jssh/wiki/Websocket-client-server-command-utils\">1.3 Command blacklist / command rewrites</a></p>\n<p>1.11 j2ssh some updates to the inner workings, issues getting it to work on latest ubuntu, are you having issues getting j2ssh to work with your open-ssh server ? if so read this</p>\n<p><a href=\"http://stackoverflow.com/questions/26424621/algorithm-negotiation-fail-ssh-in-jenkins\">J2ssh issues with latest open-ssh-server</a></p>\n<p>J2ssh was not working on the latest ubuntu for me, refer to the above link to find changes in debian ssh roll out.</p>\n<h3><a href=\"https://github.com/vahidhedayati/jssh/wiki/j2ssh-and-openssh-server-issues\">To fix j2ssh and latest openssh-server issue read this</a></h3>\n<h3><a href=\"https://github.com/vahidhedayati/jssh/wiki/conn-sessions\">Sessions</a></h3>\n<pre><code class=\"language-gsp\">\n<jssh:conn \n hostname="${hostname}" \n username="${username}"\n\tport="${port}" \n\tpassword="${password}"\n\tuserCommand="${userCommand}"\n\trealuser="${session.username}"\n\tjsshUser="${jsshUser}" //do not set this if you want auto gen id \n\tdivId="${divId}"\n\tenablePong="true"\n\tpingRate="50000"\n />\n\n</code></pre>\n<h2>2A> <a href=\"https://github.com/vahidhedayati/jssh/blob/master/grails-app/views/connectSsh/socketprocess.gsp\">Socket Method</a></h2>\n<p><a href=\"https://github.com/vahidhedayati/jssh/wiki/jssh-websocket-taglib-call\">jssh-websocket-taglib-call</a></p>\n<p><a href=\"https://github.com/vahidhedayati/jssh/wiki/jssh-websocket-within-existing-application\">wiki on jssh existing app using websockets</a></p>\n<p><a href=\"https://github.com/vahidhedayati/jssh/wiki/socket-taglib-with-pingpong\">Socket taglib with pingpong</a></p>\n<pre><code class=\"language-gsp\"><jssh:socketconnect \nusername="${username }"\npassword="${password }"\nhostname="${hostname}" \nuserCommand="${userCommand}"\ndivId="${divId}"\nhideWhatsRunning="${hideWhatsRunning }"\nhideDiscoButton="${hideDiscoButton }"\nhidePauseControl="${hidePauseControl }"\nhideSessionCtrl="${hideSessionCtrl }"\nhideConsoleMenu="${hideConsoleMenu}"\nhideSendBlock="${hideSendBlock}"\nhideNewShellButton="${hideNewShellButton}"\nenablePong="true"\npingRate="50000"\n/>\n</code></pre>\n<h2>2B> Socket Method -- Multipe calls - remoteForm -</h2>\n<p>As above but: refer to plugin connectSsh/index page and go to remote Form..\nI have used this method and called it many times on 1 page by reusing the <jssh:socketconnect tag multiple times.</p>\n<pre><code class=\"language-gsp\"><jssh:socketconnect \n...\n divId="${divId}" />\n<div id="${divId}"></div>\n</code></pre>\n<h2>3> <a href=\"https://github.com/vahidhedayati/jssh/blob/master/grails-app/views/connectSsh/ajaxprocess.gsp\">Ajax Taglib</a></h2>\n<p><a href=\"https://github.com/vahidhedayati/jssh/wiki/using-jssh-within-existing-application\">wiki on jssh existing app using ajax polling</a></p>\n<p><a href=\"https://github.com/vahidhedayati/jssh/wiki/ajax-polling-taglib-call\">ajax/polling tag lib call</a></p>\n<pre><code class=\"language-gsp\"><jssh:ajaxconnect hostname="${hostname}" username="${username}"\n\tport="${port}" password="${password}"\n\tuserCommand="${userCommand.encodeAsJavaScript()}"\n\tjsshUser="${jsshUser}" />\n</code></pre>\n<h2>4> Admin interface (part of 1.4 release)</h2>\n<p>A new configuration item has been added to jsshUser DB table, called permissions.</p>\n<p>If you want to use this plugin and define admin outside of the scope of usual app interaction, then you could try adding default admin accounts through your :</p>\n<p><a href=\"https://github.com/vahidhedayati/jssh/wiki/BootStrap.groovy---adding-admin-accounts\">BootStrap.groovy</a></p>\n<p>Otherwise you could add the following to your Config.groovy and any accounts generated from there on via the tool would have access to admin interface.\nYou could do this to start with then change the defaultperm="user"</p>\n<pre><code class=\"language-groovy\">jssh.defaultperm="admin"\n</code></pre>\n<p>In order to access admin interface you need to call this taglib :</p>\n<pre><code class=\"language-gsp\"><jssh:loadAdmin jsshUser="your_userId" />\n</code></pre>\n<p>If you have added the admin account via Config.groovy then the account is not generated as yet so you need to make an initial connection to create the user:</p>\n<pre><code class=\"language-gsp\">\n<jssh:conn \njsshUser="your_userId"\nrealUser="your_userId"\njobName="vahidsJob"\nusername="your_userId"\npassword=""\nhostname="HOSTNAME" \nuserCommand="tail -f /var/log/tomcat/catalina.out"\ndivId="abaa"\nenablePing="true"\npingRate="60000"\n/>\n</code></pre>\n<p>Once you have hit the initial start page and created that jssh account to match the same jsshUser as the admin account and have defined admin permission for the user, the admin interface will then come alive.</p>\n<h2>5> Specific user connection select boxes.</h2>\n<p>This is the component within admin menu that allows the end user to connect to a group of servers. It has been recreated as a taglib call so now you as the end user can define when/where your website users can choose to connect to a group of servers.</p>\n<p>Most basic call with full access to all its features:</p>\n<pre><code><jssh:connectUser \njsshUser="${session.username}" \n/>\n\n</code></pre>\n<p>A more defined specific call with global broadcast and send blocks pers sever blocked, this also defines primary command to be run upon group selection:</p>\n<pre><code><jssh:connectUser \njsshUser="${session.username}" \nuserCommand="something"\nhideSendBlock="YES" \nhideBroadCastBlock="YES"\n/>\n</code></pre>\n<h5>Misc Calling methods:</h5>\n<p><a href=\"https://github.com/vahidhedayati/jssh-test/blob/master/grails-app/views/testjssh/using-resources.gsp\">Taglib example on resources based grails app</a></p>\n<p><a href=\"https://github.com/vahidhedayati/jssh-test/blob/master/grails-app/views/testjssh/using-assets.gsp\">Taglib example on assets based grails app</a></p>\n<p><a href=\"https://github.com/vahidhedayati/jssh/wiki/call-directly-via-gsp\">gsp call</a></p>\n<p><a href=\"https://github.com/vahidhedayati/jssh/wiki/extending-SSH-Connection-boxes\">Extendable css div box</a></p>\n<p><a href=\"https://github.com/vahidhedayati/jssh/wiki/tail-dummy-log-file\">Easy scrolling tailing log test</a></p>\n<p><a href=\"https://github.com/vahidhedayati/jssh/wiki/userCommand-hacks\">Usercommand hacks</a></p>\n<p><a href=\"https://github.com/vahidhedayati/jssh/wiki/Bootstrap---Jquery-Switch-method\">Bootstrap/jquery switch method</a></p>\n<p><a href=\"https://github.com/vahidhedayati/jssh/wiki/Screenshots\">Screenshots</a></p>\n<h4><a href=\"https://github.com/vahidhedayati/jssh/wiki/ssh-keys\">SSH Keys:</a></h4>\n<h4><a href=\"https://github.com/vahidhedayati/jssh/wiki/why-pingong\">Why pingpong ?</a></h4>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "karman-grails", |
| "repo": "karman", |
| "owner": "bertramlabs", |
| "desc": "Karman is a standardized / extensible interface plugin for dealing with various cloud services including Local, S3, and Openstack.", |
| "labels": [ |
| "cloud" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/bertramdev/karman-core/issues", |
| "latestVersion": "3.0.0", |
| "updated": "2024-12-30T16:52:56.000Z", |
| "systemIds": [ |
| "com.bertramlabs.plugins:karman-grails" |
| ], |
| "vcsUrl": "https://github.com/bertramdev/karman-core" |
| }, |
| "documentationUrl": "https://bertramdev.github.io/karman-core/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/com/bertramlabs/plugins/karman-grails/maven-metadata.xml", |
| "readme": "<h1>Karman Core</h1>\n<p>Welcome to Karman. Karman is a standardized / extensible interface plugin for dealing with various cloud services.\nIn the beginning, Karman will focus on providing rock solid simplified interfaces for storing / retrieving files in the cloud.</p>\n<p>Features:</p>\n<ul>\n<li>Standardized interface for storing / retrieving files in the cloud.</li>\n<li>Easily reusable in other plugins with the immediate benefit of supporting many different storage engines.</li>\n<li>LocalStorage mode allows the same provider classes to store files locally and provides retrieval endpoint.</li>\n</ul>\n<p>Modules:</p>\n<ul>\n<li>karman-core (Core Karman API and Local storage Provider)</li>\n<li>karman-aws (Amazon S3)</li>\n<li>karman-openstack (Openstack Swift Object Store)</li>\n<li>karman-rackspace (Rackspace CDN Object Store)</li>\n<li>karman-azure (Azure Object Store)</li>\n</ul>\n<h2>Documentation</h2>\n<p>Currently the majority of the documentation is in the Grails Plugin</p>\n<p>http://bertramdev.github.io/karman</p>\n<p>The Beginnings of a GroovyDoc area also available here:</p>\n<p>http://bertramdev.github.io/karman-core</p>\n<h2>Contributions</h2>\n<p>All contributions are of course welcome as this is an ACTIVE project. Any help with regards to reviewing platform compatibility, adding more tests, and general cleanup is most welcome.\nThanks to several people for suggestions throughout development.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "kml", |
| "repo": "maven", |
| "owner": "vahid", |
| "desc": "Grails Global postal code to address resolving Plugin KML Map Boundary utilities loader editor. Postcodes restricted to customised boundaries", |
| "labels": [ |
| "kml" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/vahidhedayati/grails-kml-map-plugin/issues", |
| "latestVersion": "0.7", |
| "updated": "2019-12-10T11:12:13.918Z", |
| "systemIds": [ |
| "org.grails.plugins:kml", |
| "org.grails.plugins.kml:kml", |
| "grails.kml.plugin:kml" |
| ], |
| "vcsUrl": "https://github.com/vahidhedayati/grails-kml-map-plugin" |
| }, |
| "documentationUrl": "https://vahidhedayati.github.io/grails-kml-map-plugin/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>grails-kml-plugin</h1>\n<h3>This is a very powerful plugin that does multiple things:</h3>\n<p>A plugin to read raw kml file in - load google maps and overlay kml boundaries over map geo locations, international postcode lookup & resolve address from postcode feature</p>\n<h4>1. Post/Zip code lookup globally and resolves as much of address as possible</h4>\n<h4>2. If map enabled draws out</h4>\n<h5>2.1 Boundary / area if exists</h5>\n<h5>2.2 places geo location of location on map</h5>\n<h3>3. Provides KML Utils:</h3>\n<h5>3.1 Parsing utils (Google Map overlay) - read below</h5>\n<h5>3.2 Edit KML Files via plugin and update a boundary</h5>\n<h2>Please refer to YouTube video to understand all of above a bit better</h2>\n<h4>How to install: Dependency Grails 3 (build.gradle):</h4>\n<pre><code>compile "org.grails.plugins:kml:0.4"\n</code></pre>\n<blockquote>\n<h4><a href=\"https://github.com/vahidhedayati/grailskml-test\">Demo project (grails 3.3.8)</a></h4>\n</blockquote>\n<blockquote>\n<h3>YouTube videos:</h3>\n</blockquote>\n<p><a href=\"https://www.youtube.com/watch?v=m4ecgmGn4UA&list=PLfZr1vB6p8XLgSCO-JuROPjozcotad1Pt\">Boxset - play all 3 as a playlist</a></p>\n<p><a href=\"https://youtu.be/m4ecgmGn4UA\">Part 1 Walk through urls and simple usage of plugin - very basic</a></p>\n<p><a href=\"https://youtu.be/PA_O4xLGEkc\">Part 2 Walk through of how to build on new grails project from scratch</a></p>\n<p><a href=\"https://youtu.be/DQPkME4uGRs\">Part 3 Talk through code process / steps</a></p>\n<blockquote>\n<h3><a href=\"https://vahidhedayati.github.io/grails-kml-map-plugin/\">Java docs for classes</a></h3>\n</blockquote>\n<h4>Configuration values for your application.yml application.groovy in my case:</h4>\n<pre><code>kmlplugin{\n //TO USE MAP API FEATURE NEEDS TO BE ENABLED\n GOOGLE_API_KEY='YOUR GOOGLE API KEY'\n //This is total amount of local areas to collect for editing KML \n MAX_AREAS=30\n\n //How far to look for local areas in miles\n MAX_DISTANCE=30\n\n //This defines to enable map\n ENABLE_MAP_LOOKUP=true\n\n //By default treated as false\n DISABLE_LAT_LNG_LOOKUP=false\n\n // If you don't have API feature enabled on key disable this you get a developer map instead\n MAP_HAS_API_ENABLED=false\n\n \n //2 char country code of where your _default.kml belongs to so we can look up area names\n KML_COUNTRY='UK'\n\n // Internal folder to manage KML files - create and ensure web user has access\n KML_LOC="/opt/kmlplugin/_map/KML/"\n KML_HISTORY="/opt/kmlplugin/_map/KML_HISTORY/"\n\n //Drop this file in KML_LOC root folder - refer to notes below\n KML_DEFAULT="_default.kml"\n\n //This will re-run - recreate entries from _default.kml\n //if you are running in dev on h2 db - it is worth enabling this to add areas to db upon boot\n KML_RESET_FROM_DEFAULT=false\n}\n</code></pre>\n<h4>Upon Start Available urls:</h4>\n<h2>1. Lookup service : http://localhost:8080/lookup</h2>\n<p>This provides a page that given country / postcode will attempt to:</p>\n<blockquote>\n<p>1.1: Lookup postcode and return as much of address as possible</p>\n</blockquote>\n<blockquote>\n<p>1.2. If <code>ENABLE_MAP_LOOKUP</code> is set to true and <code>GOOGLE_API_KEY</code> has valid API access\nWill load map, put postcode on map\n& if KML boundaries loaded and matches will load in the area overlay on the map.</p>\n</blockquote>\n<blockquote>\n<p>1.3 To disable features you can add any or all these to url line:</p>\n</blockquote>\n<ul>\n<li>http://localhost:8080/lookup/index?showState=false&showArea=false&showLatLong=false&streetRequired=false</li>\n</ul>\n<p>Other examples:</p>\n<ul>\n<li>\n<p>http://localhost:8080/lookup/index?showState=false&showArea=true&showLatLong=true&streetRequired=false&countrysearch=United%20Kingdom&countryCode=UK&postcode=SE1%201AP</p>\n</li>\n<li>\n<p>http://localhost:8080/lookup/index?countrysearch=United%20Kingdom&countryCode=UK&postcode=SE1%201AP</p>\n</li>\n<li>\n<p>http://localhost:8080/lookup/index?countrysearch=United%20Kingdom&countryCode=UK&postcode=SE1%201AP&longitude=-0.09326659999999999&latitude=51.5017828</p>\n</li>\n<li>\n<p>http://localhost:8080/lookup/index?countrysearch=United%20Kingdom&countryCode=UK&postcode=SE1%201AP&longitude=-0.09326659999999999&latitude=51.5017828&communitySearch=Southwark</p>\n</li>\n</ul>\n<h2>2. TagLib call</h2>\n<p>All passed variables to map and instance are not required but to show what above url params can be either posted or done as per above with instance being addition to params above\nfor tag lib if you already have data this is what it is expecting to be sent to it</p>\n<pre><code class=\"language-gsp\"><map:lookup \n showState="${false}" \n showArea="${false}" \n showLatLong="${false}" \n streetRequired="${false}"\n instance="${[\n countrysearch:'',\n countryCode:'',\n postcode:'',\n building:'',\n street:'',\n city:'',\n state:'',\n communitySearch:'',\n latitude:'',\n longitude:'',\n ]}"\n />\n<!-- similar example with some data already set all of below\n is enough to trigger maps / overlay - could be saved data -->\n<map:lookup\n showState="${false}"\n showArea="${false}"\n showLatLong="${false}"\n streetRequired="${false}"\n instance="${[\n countrysearch:'United Kingdom',\n countryCode:'UK',\n postcode:'SE1 1AP',\n building:'',\n street:'',\n city:'',\n state:'',\n communitySearch:'Southwark',\n latitude:'51.5017828',\n longitude:'-0.09326659999999999',\n ]}"\n/>\n</code></pre>\n<h2>Map overlay editor : http://localhost:8080/map</h2>\n<p>This provides an interface to edit and modify existing kml boundaries on the fly.\nIt provides raw kml extracted file, has feature to upload, hasn't been tested.</p>\n<h2>Instructions / Notes</h2>\n<h4>Customising your own lookup</h4>\n<p>You will need to take a copy of <a href=\"https://github.com/vahidhedayati/grails-kml-map-plugin/blob/master/grails-app/views/lookup/_address.gsp\">_address.gsp</a> when <code>verifyCode</code> is called the <code>data</code> object returned contains full dump of\neverything useful .</p>\n<p><code>console.log(JSON.stringify(data))</code> will show all but 2 full data sets: <code>data.latLongDetails</code> and <code>data.fullPostCodeDetails</code></p>\n<h4>KML Notes :</h4>\n<ol>\n<li><code>/opt/kmlplugin/_map/KML/</code> -></li>\n</ol>\n<p>Place a file for the given country. This will be KML file you get hold of that contains typically all the official boroughs/councils of a given country in the case of UK we found:</p>\n<p><a href=\"http://www.nemezisproject.co.uk/2012/05/20/google-maps-api-uk-local-council-overlay-boundaries-kml/\">was here</a>\nSite appears to no longer work. You can get hold of <a href=\"https://github.com/vahidhedayati/grailskml-test/tree/master/DOWNLOADS\">file from here</a></p>\n<p>This file was then stored in this folder as</p>\n<p>_default.kml</p>\n<p>/opt/kmlplugin/_map/KML/_default.kml</p>\n<h3>To parse KML Files Add this to BootStrap.groovy</h3>\n<pre><code> KmlHelper.parseKml()\n</code></pre>\n<p>When the site starts up for the very first time, it will attempt to read through this file and inside the same folder it will expand out all the found boroughs.</p>\n<pre><code class=\"language-bash\">$ ls -rtml /opt/kmlplugin/_map/KML/|more\ntotal 9876\n-rw-rw-r-- 1 mx1 mx1 7394653 Nov 29 17:08 _default.kml\n-rw-rw-r-- 1 mx1 mx1 19199 Dec 1 19:36 BEDFORDSHIRE.kml\n-rw-rw-r-- 1 mx1 mx1 31337 Dec 1 19:36 BUCKINGHAMSHIRE.kml\n-rw-rw-r-- 1 mx1 mx1 24338 Dec 1 19:36 CAMBRIDGESHIRE.kml\n-rw-rw-r-- 1 mx1 mx1 584 Dec 1 19:36 CHESHIRE.kml\n-rw-rw-r-- 1 mx1 mx1 584 Dec 1 19:36 CORNWALL.kml\n-rw-rw-r-- 1 mx1 mx1 582 Dec 1 19:36 CUMBRIA.kml\n</code></pre>\n<p>At this point it has loaded up each borough and also split each borough/community into its own specific file.</p>\n<p>This process happens only once and can be redone by clearing out and dropping in as above a _default.kml file.</p>\n<p>This triggers an internal process to do what has been demonstrated.</p>\n<p>Once it has been generated. The site will from there on refer to all created files to load up each community.</p>\n<p>This means you can now edit each of the generated files for a given community and re-save it \ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd a saved version and application restart will then ensure the site is using whatever latest content each community has.</p>\n<p>Upon start up you will need to visit the map regions and it will show what has been produced.</p>\n<h2>To enable logging:</h2>\n<p>Add below to <code>grails-app/conf/logback.groovy</code></p>\n<pre><code> logger('org.grails.plugins.kml', ERROR, ['STDOUT'], false)\n logger('org.grails.plugins.kml', DEBUG, ['STDOUT'], false)\n logger('org.grails.plugins.kml', WARN, ['STDOUT'], false)\n logger('org.grails.plugins.kml', INFO, ['STDOUT'], false)\n</code></pre>\n<p>##Credits</p>\n<h4><code>/map</code> <a href=\"http://www.birdtheme.org/useful/v3tool.html\">KML Editor taken from Kjell Scharning</a></h4>\n<p>KML Map editor or <code>/map</code> segement is thanks to above link which gave the source to build the rest as such.\nHis worked got wired into what the rest of the code does, as per what his page expected.</p>\n<h4><code>/lookup</code> my own work over different projects / requirements.</h4>\n<h6>Please note - <a href=\"https://github.com/vahidhedayati/grails-kml-map-plugin/blob/master/src/main/groovy/org/grails/plugins/kml/utils/KmlHelper.groovy\">KML Parsing utiltiy</a>. I put this class together as an expansion from <a href=\"https://stackoverflow.com/questions/15636303/extract-coordinates-from-kml-file-in-java/47576837#47576837\">this question on SO extract-coordinates-from-kml-file-in-java</a>. Since this plugin is currently functional with provided kml file, any one who has additional time and wishes to come on board and improve KML Parsing to work with other standards or any other aspect of this plugin, I be happy to accept their input. This isn't something I'm currently using and was put together for another project, decided to release into public realm since I guess it is a bit of magic.</h6>\n<p><img src=\"https://vahidhedayati.github.io/grails-kml-map-plugin/screenshots/map-region-editor.png\" alt=\"sample image\" />\n<img src=\"https://vahidhedayati.github.io/grails-kml-map-plugin/screenshots/map-region-editor-edit.png\" alt=\"sample image\" />\n<img src=\"https://vahidhedayati.github.io/grails-kml-map-plugin/screenshots/map-region-editor-edit1.png\" alt=\"sample image\" />\n<img src=\"https://vahidhedayati.github.io/grails-kml-map-plugin/screenshots/map-region-editor-edit2.png\" alt=\"sample image\" />\n<img src=\"https://vahidhedayati.github.io/grails-kml-map-plugin/screenshots/map-region-editor-edit3.png\" alt=\"sample image\" />\n<img src=\"https://vahidhedayati.github.io/grails-kml-map-plugin/screenshots/map-region-editor-edit4.png\" alt=\"sample image\" />\n<img src=\"https://vahidhedayati.github.io/grails-kml-map-plugin/screenshots/map-region-editor-edit5.png\" alt=\"sample image\" />\n<img src=\"https://vahidhedayati.github.io/grails-kml-map-plugin/screenshots/map-region-editor-edit6.png\" alt=\"sample image\" />\n<img src=\"https://vahidhedayati.github.io/grails-kml-map-plugin/screenshots/map-region-editor-edit7.png\" alt=\"sample image\" />\n<img src=\"https://vahidhedayati.github.io/grails-kml-map-plugin/screenshots/map-region-editor-edit8.png\" alt=\"sample image\" />\n<img src=\"https://vahidhedayati.github.io/grails-kml-map-plugin/screenshots/map-region-editor-edit9.png\" alt=\"sample image\" /></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "ldap-server", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Grails LDAP Server Plugin", |
| "labels": [ |
| "ldap" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/bobbywarner/grails-ldap-server/issues", |
| "latestVersion": "1.0.0", |
| "updated": "2016-04-01T15:38:25.762Z", |
| "systemIds": [ |
| "org.grails.plugins:ldap-server" |
| ], |
| "vcsUrl": "https://github.com/bobbywarner/grails-ldap-server" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "less-asset-pipeline", |
| "repo": "asset-pipeline", |
| "owner": "bertramlabs", |
| "desc": "LESS Compiler for the Asset-Pipeline", |
| "labels": [ |
| "asset-pipeline", |
| "less", |
| "css" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/bertramdev/less-asset-pipeline/issues", |
| "latestVersion": "5.0.9", |
| "updated": "2025-04-13T23:20:14.000Z", |
| "systemIds": [ |
| "com.bertramlabs.plugins:less-asset-pipeline" |
| ], |
| "vcsUrl": "https://github.com/bertramdev/less-asset-pipeline" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/com/bertramlabs/plugins/less-asset-pipeline/maven-metadata.xml", |
| "readme": "<h1>LESS Asset Pipeline</h1>\n<p><strong>MOVED</strong>: This project has moved to a sub project of the main asset-pipeline repository <a href=\"http://github.com/bertramdev/asset-pipeline\">http://github.com/bertramdev/asset-pipeline</a></p>\n<p>The <code>less-asset-pipeline</code> is a plugin that provides LESS support for the asset-pipeline static asset management plugin.</p>\n<p>For more information on how to use asset-pipeline, visit <a href=\"http://www.github.com/bertramdev/asset-pipeline\">here</a>.</p>\n<h2>Installation</h2>\n<p>Add this plugin to your classpath in gradle or dependencies list depending on how you are using it:</p>\n<pre><code class=\"language-gradle\">//Example build.gradle file\nbuildscript {\n repositories {\n mavenCentral()\n }\n dependencies {\n classpath 'com.bertramlabs.plugins:asset-pipeline-gradle:2.5.4'\n classpath 'com.bertramlabs.plugins:less-asset-pipeline:2.5.4'\n }\n}\n</code></pre>\n<h2>Usage</h2>\n<p>Create files in your standard <code>assets/stylesheets</code> folder with extension <code>.less</code> or <code>.css.less</code>. You also may require other files by using the following requires syntax at the top of each file or the standard LESS import:</p>\n<pre><code class=\"language-css\">/*\n*= require test\n*= require_self\n*= require_tree .\n*/\n\n/*Or use this*/\n@import 'test'\n\n</code></pre>\n<h2>Less4j Support</h2>\n<p>This plugin now defaults to compiling your less files with less4j instead of the standard less compiler. To Turn this off you must adjust your config:</p>\n<pre><code class=\"language-gradle\">assets {\n configOptions = [\n less: [\n compiler: 'standard'\n ]\n ]\n}\n</code></pre>\n<h2>Production</h2>\n<p>During war build your less files are compiled into css files. This is all well and good but sometimes you dont want each individual less file compiled, but rather your main base less file. It may be best to add a sub folder for those LESS files and exclude it in your precompile config...</p>\n<p>Sample Gradle Config:</p>\n<pre><code class=\"language-gradle\"> assets {\n excludes = ['mixins/*.less']\n }\n</code></pre>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "lightningj-grails", |
| "repo": "plugins", |
| "owner": "herrvendil", |
| "desc": "Grails 3.x Plugin to integrate LightningJ into a Grails application.", |
| "labels": [ |
| "lightning" |
| ], |
| "licenses": [ |
| "LGPL-3.0" |
| ], |
| "issueTrackerUrl": "https://github.com/lightningj-org/lightningj-grails/issues", |
| "latestVersion": "0.5.2-Beta", |
| "updated": "2019-02-07T18:38:29.311Z", |
| "systemIds": [ |
| "org.lightningj:lightningj-grails" |
| ], |
| "vcsUrl": "https://github.com/lightningj-org/lightningj-grails" |
| }, |
| "documentationUrl": "https://lightningj-org.github.io/lightningj-grails/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Readme for LightningJ Grails Plugin</h1>\n<p>LightningJ Grails plugin is a project to simplify the usage of the LightningJ\nlibrary in Grails 3.3.x applications and above.</p>\n<p>For documentation see docs/index.adoc of the project web-site at\nhttp://grails.lightningj.org</p>\n<p>Build status Master branch: <a href=\"https://travis-ci.org/lightningj-org/lightningj-grails\"><img src=\"https://travis-ci.org/lightningj-org/lightningj-grails.svg?branch=master\" alt=\"Build Status\" /></a></p>\n" |
| }, |
| { |
| "display-name": "mail", |
| "bintrayPackage": { |
| "name": "grails-mail", |
| "repo": "plugins", |
| "owner": "grails-plugins", |
| "desc": "The Mail Plugin provides a convenient DSL for sending email. It supports plain text, html, attachments, inline resources and i18n among other features.", |
| "labels": [ |
| "mail" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/grails-mail/issues", |
| "latestVersion": "3.0.0", |
| "updated": "2019-10-22T14:59:33.694Z", |
| "systemIds": [ |
| "org.grails.plugins:grails-mail" |
| ], |
| "vcsUrl": "https://github.com/grails-plugins/grails-mail" |
| }, |
| "documentationUrl": "https://grails-plugins.github.io/grails-mail/latest", |
| "mavenMetadataUrl": null, |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "mailinglist", |
| "repo": "maven", |
| "owner": "vahid", |
| "desc": "mailinglist is a Grails plugin which makes use of quartz to dynamically schedule either group or specific email address contact. You create html email templates with images etc, then define time and date for this to be sent. The job is then added to quartz and set to email at given time. The queue can easily be controlled via bootstrap so that nothing is ever lost.\r\n\r\nDo you want to email a person at 11:41 pm or maybe a group of people at 2.15am? then look no further.\r\n\r\nYou can schedule an email to be scheduled and to run on a set date and time.\r\n\r\nSupports HTML emails with inline images as well as attachments has been tested on outlook and result appears to load fine.", |
| "labels": [ |
| "mail" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/vahidhedayati/mailinglist/issues", |
| "latestVersion": "3.0.3", |
| "updated": "2017-02-18T12:05:20.775Z", |
| "systemIds": [ |
| "org.grails.plugins:mailinglist" |
| ], |
| "vcsUrl": "https://github.com/vahidhedayati/mailinglist" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>mailinglist 0.34</h1>\n<p>mailinglist is a Grails plugin which makes use of quartz to dynamically schedule either group or specific email address contact.\nYou create html email templates with images etc, then define time and date for this to be sent. The job is then added to quartz and set to email at given time.\nThe queue can easily be controlled via bootstrap so that nothing is ever lost.</p>\n<p>Do you want to email a person at 11:41 pm or maybe a group of people at 2.15am? then look no further.</p>\n<p>You can schedule an email to be scheduled and to run on a set date and time.</p>\n<p>Supports HTML emails with inline images as well as attachments has been tested on outlook and result appears to load fine.</p>\n<p>For a walk through guide on how to install this plugin goto : https://github.com/vahidhedayati/ml-test</p>\n<h2>Installation for grails 2.4+ assets based sites:</h2>\n<p>Add plugin Dependency in BuildConfig.groovy :</p>\n<pre><code class=\"language-groovy\">compile ":mailinglist:0.34"\n</code></pre>\n<h2>Installation for grails 3+</h2>\n<pre><code class=\"language-groovy\">compile "org.grails.plugins:mailinglist:3.0.4"\n</code></pre>\n<p>For grails 3 You will need to add bootstrap-datetimepicker.min.js to your grails-app/js/javascripts folder</p>\n<p>The file can be found here:</p>\n<p>https://github.com/vahidhedayati/mailinglist/tree/master/src/main/templates/js or https://tarruda.github.io/bootstrap-datetimepicker/</p>\n<h4>Under 2.4.0 you may need to review hibernate version and update to:</h4>\n<pre><code>runtime ":hibernate4:4.3.5.4"\n</code></pre>\n<p>Please refer to <a href=\"https://github.com/vahidhedayati/testmlist\">example site grails 2:</a></p>\n<p>Please refer to <a href=\"https://github.com/vahidhedayati/testmlist3\">example site grails 3:</a></p>\n<h2>Installation for grails < 2.4 based resources sites 2.X -> 2.3.X</h2>\n<p>Under Resources based application you can still use the latest code base, but you need to exclude hibernate. Something like this:</p>\n<pre><code>compile (":maillinglist:X.XX") { excludes 'hibernate' }\n</code></pre>\n<p>If you wish you could also use the very last build under compatible hibernate version built under resources:\nAdd plugin Dependency in BuildConfig.groovy :</p>\n<pre><code class=\"language-groovy\">compile ":mailinglist:0.19"\n</code></pre>\n<h2>Since 0.23 you also require:</h2>\n<p>In the latest app I had to also enable fixes for export plugin, unsure why it did not pull it from within plugin...</p>\n<p>Under BuildConfig.groovy:</p>\n<pre><code>\trepositories {\n\t\t......\n\t\tmavenRepo "http://repo.grails.org/grails/core"\n \t}\n\n \tdependencies {\n\t\t.....\n\t\tcompile 'commons-beanutils:commons-beanutils:1.8.3'\n \t}\n</code></pre>\n<p>The two extra lines one to repositories and one to dependencies.</p>\n<h2>Resources based sites : (Grails pre 2.4 ) grails-app/layouts/main.gsp update:</h2>\n<h5>jquery, jquery-ui libraries:</h5>\n<p>your layouts main.gsp: (add jquery-ui and jquery - or add them into ApplicationResources.groovy and ensure you refer to it in your main.gsp or relevant file</p>\n<pre><code class=\"language-gsp\">\t<g:javascript library="jquery"/>\n\t<g:javascript library="jquery-ui"/>\n\t\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\n\t\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\n\t<g:layoutHead/>\n\t<mailinglist:loadbootstrap/>\n</head>\n</code></pre>\n<p>You will also notice <a href=\"mailinglist:loadbootstrap/\">mailinglist:loadbootstrap/</a> this loads up bootstrap to make modalbox work - if you already have bootstrap then change this to</p>\n<pre><code class=\"language-gsp\"><mailinglist:loadplugincss/>\n</code></pre>\n<p>I have found using this method of calling bootstrap within one of my projects to have caused a problem when looking at source it was loading before jquery,\nso by moving this block further below end head tag resolved the issue.</p>\n<h2>Assets based sites : (Grails 2.4+ ) grails-app/layouts/main.gsp update:</h2>\n<p>A default site just add the mailingList line below application.js to grails-app/layouts/main.gsp</p>\n<pre><code>\t<asset:stylesheet src="application.css"/>\n <asset:javascript src="application.js"/>\n <mailinglist:loadbootstrap/>\n</code></pre>\n<p>Or if you already have bootstrap initialised :</p>\n<pre><code>\t<mailinglist:loadplugincss/>\n</code></pre>\n<p>replace the loadboostrap to loadplugincss</p>\n<p>Now with that all in place open grails console or from the command line run</p>\n<pre><code>grails mlsetup org.example.com 5\n</code></pre>\n<p>Where org.example.com is your package and 5 is the amount of dynamic schedule jobs to generate,</p>\n<p>Assuming package was labelled as above org.example.com and schedule jobs as 5, install script will create</p>\n<pre><code>\nViews \t\tunder views/mailingList/_addedby.gsp\n\nJobs under \torg.example.com/ScheduleEmail0Job.groovy\n\t\t \torg.example.com/ScheduleEmail1Job.groovy\n\t\t \torg.example.com/ScheduleEmail2Job.groovy\n\t\t \torg.example.com/ScheduleEmail3Job.groovy\n\t\t \torg.example.com/ScheduleEmail4Job.groovy\n\nServices \tunder org.example.com\n\t\t\tIt will update QuartzEmailCheckerService to only schedule physical jobs ScheduleEmail[0-4]Job\n</code></pre>\n<p>The domains generated in your application extend base domains within plugin, besides this the rest of the controllers etc are pushed to your own application for you to do what you like with it.</p>\n<h4>i18n support</h4>\n<p>From 1.17 you can configure your i18n/messages_{locale}.properties to include translations for terms used within this plugin, to get the latest running terms for translation please refer to the <a href=\"https://github.com/vahidhedayati/mailinglist/wiki/i18n-terms---support\">wiki</a></p>\n<h2>Version changes</h2>\n<pre><code>0.34 @idiengaid identified issue with bulk emails and templates, earlier work from 0.32 needed additional if check around template\n0.33 @idiengaid spotted instance with missing i\n0.32 Pull request https://github.com/vahidhedayati/mailinglist/pull/5 \n\nmartofeld added some commits 5 hours ago\n @martofeld\tAdd support for using templates in the mail\t\t\t5495ef2\n @martofeld\tAvoid parsing if values are already a List + fix typo\t\t\ted30889\n @martofeld\tMissed some implementations of the new template\t\t\ta3a5601\n \n \n0.31 #3 Improvement of the mlsetup script and produced services \n\tIf you have refreshed mlsetup script as part of 0.30, its worth doing it again. This will produce tidier services.\n0.30 #3 further tidyup of cron expression rule checking\n0.29 #3 Cron expressions introduced so either send via cron schedule or specify date time\n0.28 minor change update modaldynamix to 0.28 and pluginbuddy 0.3 \n0.27 minor change update to modaldynamix ver 0.27\n0.26 Updated to 2.4.2, cleaned up end user app verification by using pluginbuddy. \n0.25 latest modaldynamix called - pop up boxes loading correctly according to screen size\n0.24 Fixed datetime issue under assets based sites.\n0.23 Latest modaldynamix plugin version used - modalboxes resized according to requirement - colour added to modalbox button callers.\n0.22 Excess css entries removed from MailingList.css - causing larger buttons and unnessary spacing issues.\n0.21 Missing jquery-ui js file manually inserted in for assets based sites.\n0.20 Release of assets version - identical to 0.19 but hibernate bumped to match assets based sites.\n0.19 last release for resources based sites. to keep upto date update your underlying site to assets\n0.18 i18n support added to services - further tidy up of contact a person page.\n0.17 Tidy up of mailSent view on main menu, added i18n support to most of the calls.\n0.16 latest ckeditor added\n0.15 mailinglist.warn.duplicate and mailinglist.warn.period added, issue with search mailingList fixed. Duplicate email warnings to same contactGroup set to show on preview screen\n0.14 fixed pagination / export features on mailinglist page.\n0.13 issue with list - export feature was not working - format was not being passed - format now set to extension params\n0.12 Changed ckeditor to 4.4.0.0-SNAPSHOT http://jira.grails.org/browse/GPCKEDITOR-40\n0.11 Removal of non thread safe calls within QuartsStatusService ret_triggerName ret_triggerGroup ret_jobName, now returned as map and parsed as params back in modSchedule\n0.10 more tidying up fixes to minor broken calls\n0.9 tidyup to taglib/service and gsps \n0.8 minor changes to _list1-top.gsp - called correct controller to display more information on scheduled jobs\n0.7 updates to default db table names, readme updates, correct ckeditor call for in index.gsp, giving upload feature for images \n0.6 minor fix MailingList controller save wrong parameter for categories\n0.5 minor fix gsp listing wrong domainClass in mailingList/_form.gsp\n0.4 moved out all of the manual modalbox calls and called modaldynamix plugin \n0.3 Missing images, alerts left in java scripts tut tut, contactclients gsp page had lots of bugs now fixed, scheduling looks a lot healthier.\n0.2 moved most back into actual plugin - bug with existing used schedule issues whilst attempting to schedule something for now whilst others queued.\n0.1 release - nearly everything written to clients project\n</code></pre>\n<h4>Config.groovy changes</h4>\n<p>Required <code>Config.groovy</code> configurations:</p>\n<pre><code class=\"language-groovy\">/*\n * Optional values to override DB table names for this plugin:\n * mailinglist.table.attachments='mailing_list_attachments'\n * mailinglist.table.categories='categories'\n * mailinglist.table.mailinglist='mailing_list'\n * mailinglist.table.schedule='mailing_list_schedule'\n * mailinglist.table.senders='mailing_list_senders'\n * mailinglist.table.templates='mailing_list_templates'\n * These options define if there should be a warning to confirm an email was sent to same group within defined period\n * mailinglist.warn.duplicate='Y'\n * --- Periods are: | H for Hours | D for days | M for minutes | m for months | y for years | \n * mailinglist.warn.period='2H'\n * These are all the local tables created that in turn extend domainClasses from this plugin.\n * Check out your domainClass folder under the package you provided after you run the mlsetup command.\n */\n \n\t\n// Your date format that matches input of jquery datepicker config \n//mailinglist.dtFormat='dd/MM/yyyy HH.mm'\n\n\nckeditor {\n\t//config = "/js/myckconfig.js"\n\tskipAllowedItemsCheck = false\n\tdefaultFileBrowser = "ofm"\n\tupload {\n\t\n\t\t// basedir = "/uploads/"\n\t\t\n\t\tbaseurl="${grails.baseURL}"+'/uploads/'\n\t\tbasedir = "${externalUploadPath}"\n\t\t\n\t\t\toverwrite = false\n\t\t\tlink {\n\t\t\t\tbrowser = true\n\t\t\t\tupload = false\n\t\t\t\tallowed = []\n\t\t\t\tdenied = ['html', 'htm', 'php', 'php2', 'php3', 'php4', 'php5',\n\t\t\t\t\t\t\t 'phtml', 'pwml', 'inc', 'asp', 'aspx', 'ascx', 'jsp',\n\t\t\t\t\t\t 'cfm', 'cfc', 'pl', 'bat', 'exe', 'com', 'dll', 'vbs', 'js', 'reg',\n\t\t\t\t\t\t 'cgi', 'htaccess', 'asis', 'sh', 'shtml', 'shtm', 'phtm']\n\t\t\t}\n\t\t\timage {\n\t\t\t\tbrowser = true\n\t\t\t\tupload = true\n\t\t\t\tallowed = ['jpg', 'gif', 'jpeg', 'png']\n\t\t\t\tdenied = []\n\t\t\t}\n\t\t\tflash {\n\t\t\t\tbrowser = false\n\t\t\t\tupload = false\n\t\t\t\tallowed = ['swf']\n\t\t\t\tdenied = []\n\t\t\t}\n\t}\n}\n\njqueryDateTimePicker {\n\tformat {\n\t\tjava {\n\t\t\tdatetime = "dd/MM/yyyy HH.mm"\n\t\t\tdate = "dd/MM/yyyy"\n\t\t}\n\t\tpicker {\n\t\t\tdate = "'dd/mm/yy'"\n\t\t\ttime = "'H.mm'"\n\t\t}\n\t}\n}\n\ngrails.mime.types = [ html: ['text/html','application/xhtml+xml'],\n\txml: ['text/xml', 'application/xml'],\n\ttext: 'text-plain',\n\tjs: 'text/javascript',\n\trss: 'application/rss+xml',\n\tatom: 'application/atom+xml',\n\tcss: 'text/css',\n\tcsv: 'text/csv',\n\tpdf: 'application/pdf',\n\trtf: 'application/rtf',\n\texcel: 'application/vnd.ms-excel',\n\tods: 'application/vnd.oasis.opendocument.spreadsheet',\n\tall: '*/*',\n\tjson: ['application/json','text/json'],\n\tform: 'application/x-www-form-urlencoded',\n\tmultipartForm: 'multipart/form-data'\n ]\n</code></pre>\n<p>You will notice <code>grails.baseURL</code> externalUploadPath within ckeditor, this was done to externalise image uploads so upon a redployment the images were still available, the approach I took to this was to run values from setenv.sh within tomcat and pass this values in as variables into <code>Config.groovy</code> as per below:</p>\n<p>// configuration for plugin testing - will not be included in the plugin zip</p>\n<p>// In my tomcat setenv.sh</p>\n<pre><code class=\"language-sh\">//UPLOADLOC="$CATALINA_HOME/uploads"\n//JAVA_OPTS="$JAVA_OPTS -DUPLOADLOC=$UPLOADLOC"\n//HOSTNAME=$(hostname)\n//JAVA_OPTS="$JAVA_OPTS -DSERVERURL=$HOSTNAME"\n</code></pre>\n<p>Produces running tomcat with the following values:</p>\n<pre><code>// -DUPLOADLOC=/opt/tomcat7/tc1/uploads\n// -DSERVERURL=my.server.com\n</code></pre>\n<p>In my <code>Config.groovy</code> at the top I have this</p>\n<pre><code class=\"language-groovy\">if (System.getProperty('UPLOADLOC')) {\n\texternalUploadPath=System.getProperty('UPLOADLOC')+File.separator\n}\nif (System.getProperty('SERVERURL')) {\n\tgrails.baseURL='http://'+System.getProperty('SERVERURL')\n} else{\n\tgrails.baseURL='http://localhost'\n}\n</code></pre>\n<p>Now those values are valid within the ckeditor configuration</p>\n<h4>Boostrap changes</h4>\n<p>An example BootStrap call to requeue outstanding or interuppted schedules is to add something like this :</p>\n<pre><code class=\"language-groovy\">import grails.plugin.mailinglist.core.ScheduleBase\n\nclass BootStrap {\n\tdef mailingListEmailService\n def init = { servletContext ->\n\t\tdef getEmails = ScheduleBase.findAllByScheduleCompleteAndScheduleCancelled(false,false)\n\t\tgetEmails.each { params ->\n\t\t\tif (params.dateTime && params.emailMessage) {\n\t\t\t\tprintln "RESCHEDULING MAIL QUEUE ${params?.id} -- ${params?.mailFrom}---${params?.recipientToGroup}--${params?.recipientToList}"\n\t\t\t\tmailingListEmailService.rescheduleit(params)\n\t\t\t}\n\t\t}\n\t}\n}\n\n</code></pre>\n<h4>addedby within forms</h4>\n<p>There is a field passed around through the application and by default it is blank, this is due to a file called <code>views/mailingList/_addedby.gsp</code></p>\n<p>Take a look at this, if your existing application has some form of user and current user is being returned via session or another method i.e. params or something then update this page to refer to this value.\nThis should fix the issue all around the site, no guarantee haha.</p>\n<h4>conf/UrlMappings.groovy & plugin default holding page</h4>\n<p>If this plugin is the only purpose of your site, then simply update your url mappings to point to the holding page of this plugin:</p>\n<pre><code class=\"language-groovy\">"/" {\n\tcontroller = "MailingList"\n\taction = "index"\n}\n// Commented out default and put in above\n//"/"(view:"/index")\n</code></pre>\n<p>The plugin has a menu which can be found under: <code>http://yoursite:8080/mailinglist/MailingList</code></p>\n<p>This is the main menu, the two core options on the top left hand side, Email a person and contact clients.</p>\n<p><img src=\"https://raw.github.com/vahidhedayati/ml-test/master/documentation/mailinglist-menu.png\" alt=\"mailinglist menu\" /></p>\n<p>The rest of the menu are the manual methods of reviewing email list, or removing attachments etc.</p>\n<p><img src=\"https://raw.github.com/vahidhedayati/ml-test/master/documentation/mailinglist-sendperson.png\" alt=\"Email a person\" />\nThis is what to expect when emailing a person</p>\n<p><img src=\"https://raw.github.com/vahidhedayati/ml-test/master/documentation/mailinglist-sendperson1.png\" alt=\"Configure schedule date time\" />\nThe now button defaults to now, other than that choose actual date time you wish to email this person.</p>\n<p><img src=\"https://raw.github.com/vahidhedayati/ml-test/master/documentation/mailinglist-sent-person.png\" alt=\"When submitted\" />\nIt will just sit in that queue you can stop the job or force it play now from that same scheduling menu.</p>\n<p><img src=\"https://raw.github.com/vahidhedayati/ml-test/master/documentation/mailinglist-contact-group.png\" alt=\"Contacting group\" />\nThis is the look and feel of contact group, subject is the only thing defined, everything else is clickable or uploadable. At the top are some green buttons, each one will update this form dynamically.</p>\n<p><img src=\"https://raw.github.com/vahidhedayati/ml-test/master/documentation/mailinglist-contact-group1.png\" alt=\"New Template\" />\nAdding a new template, if you do not have a preset template to use for sending emails then create a new one from the first green button at the top of the page.</p>\n<p><img src=\"https://raw.github.com/vahidhedayati/ml-test/master/documentation/mailinglist-contact-group2.png\" alt=\"Attach a file\" />\nThis is if you wish to attach files like documents to be sent with email.</p>\n<p><img src=\"https://raw.github.com/vahidhedayati/ml-test/master/documentation/mailinglist-contact-group3.png\" alt=\"After attaching\" />\nAttachments run in iframes, so for changes to take effect on main form you need to use the close button on the top of the page.</p>\n<p><img src=\"https://raw.github.com/vahidhedayati/ml-test/master/documentation/mailinglist-contact-group4.png\" alt=\"Upload Contact Group CSV\" />\nCSV Uploader which will be your group of users to contact, please note it will always miss out on the first line since on exports usually the first line is the field name</p>\n<p><img src=\"https://raw.github.com/vahidhedayati/ml-test/master/documentation/mailinglist-contact-group5.png\" alt=\"Add Sender\" />\nThe senders from group emails come from the Senders DB table, so you need to register it once set it should remain for reuse on next use.</p>\n<p><img src=\"https://raw.github.com/vahidhedayati/ml-test/master/documentation/mailinglist-contact-group6.png\" alt=\"Schedule DateTime of email\" />\nSet the time you wish to email to this group, you have now selected and ticked everything else including once template was uploaded you clicked the select box to choose it which then popped open your presaved template.</p>\n<p><img src=\"https://raw.github.com/vahidhedayati/ml-test/master/documentation/mailinglist-contact-group7.png\" alt=\"Preview Group Email\" />\nSince emailing a group of people usually requires more care, there has been a preview screen added to ensure you are happy with what is being done. if so click confirm sending email otherwise click edit to go back,</p>\n<p><img src=\"https://raw.github.com/vahidhedayati/ml-test/master/documentation/mailinglist-contact-group8.png\" alt=\"Schedule menu\" />\nThis now contains our previous job which is set in a few hours plus our new job for now, we will now choose Completed schedules from the drop down to see:</p>\n<p><img src=\"https://raw.github.com/vahidhedayati/ml-test/master/documentation/mailinglist-contact-group9.png\" alt=\"Completed jobs\" />\nThis group email as completed</p>\n<p><img src=\"https://raw.github.com/vahidhedayati/ml-test/master/documentation/mailinglist-contact-group10.png\" alt=\"Mail Log on machine\" />\nThis is my email log confirming it sent an email from set email to the uploaded csv which had 3 gmail emails, it bounced cos my sendmail is not configured and just as well considering the amount of junk I been sending haha</p>\n<p>#Common Issues:\nAfter attempting to run</p>\n<pre><code>mlsetup org.example.com 5\n</code></pre>\n<p>you must referesh the project and run</p>\n<pre><code>grails refresh-dependencies\n</code></pre>\n<p>If your in ggts you may still see red asterix you can run:</p>\n<pre><code>grails clean \n</code></pre>\n<p>These are the manual command lines goto project right click grails tools, grails command wizard will help you with those or actual command prompt below just drop the grails in front of all of the above.</p>\n<p>Date Format: Trying to schedule and can not ?</p>\n<pre><code>dd/MM/yyyy HH.mm\n</code></pre>\n<p>You may see this :</p>\n<pre><code>Could not queue job please check quartz queue to ensure schedule slots are free\n</code></pre>\n<p>If you look at the console logs you will see it could not parse and it shows a date and time, look closely at the time you will find it has a : seperating the hour and mins.\nI know I should have set this as the default right :) This is the defaults sadly so please review main config and ensure your jquery date time config is set properly to match what is needed:</p>\n<pre><code class=\"language-groovy\">mailinglist.dtFormat='dd/MM/yyyy HH.mm'\njqueryDateTimePicker {\n\tformat {\n\t\tjava {\n\t\t\tdatetime = "dd/MM/yyyy HH.mm"\n\t\t\tdate = "dd/MM/yyyy"\n\t\t}\n\t\tpicker {\n\t\t\tdate = "'dd/mm/yy'"\n\t\t\ttime = "'H.mm'"\n\t\t}\n\t}\n}\n</code></pre>\n<p>This is in the main config above, but worth a remention, so if you want to set a different input type for date time,\nthen define this value in your config to match aboves config to get around the standard config which is a dot seperating hours and minutes.</p>\n<pre><code class=\"language-groovy\">mailinglist.dtFormat='dd/MM/yyyy HH.mm'\t\n</code></pre>\n<p>Ensure all of above tallies up for it all work properly</p>\n<h4>Pop up Modal boxes within contact clients</h4>\n<p>Take a look at https://github.com/vahidhedayati/modaldynamix follow the guide then refer to pages within this plugin to get a better idea on how to use it all together.</p>\n<h2>Finally</h2>\n<p>A big thank you as always to Burt Beckwith for cleaning up the code:\nUnfortunately due to issues with merging repo was cleaned up, original code cna be found here:\nThose changes are here: https://github.com/burtbeckwith/mailinglist/</p>\n<p><a href=\"https://github.com/martofeld\">@martofeld martin</a> For adding template support to the plugin</p>\n<p><a href=\"https://github.com/stokito\">Sergey Ponomarev</a> For cleaning up and adding formating to the README.md</p>\n<p>Thank you all for you contributions. If you wish to contribute or add stuff I be happy to add you as a project member. I am no longer using this project so will not be getting much updates from me.</p>\n" |
| }, |
| { |
| "comment": "Micronaut is part of Grails since 4.0.0. Is this entry still relevant?", |
| "bintrayPackage": { |
| "name": "micronaut-beans", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Grails Plugin For Adding Micronaut Beans To The Spring Application Context", |
| "labels": [ |
| "micronaut" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/micronaut-beans/issues", |
| "latestVersion": "1.0.0.M2", |
| "updated": "2018-08-10T16:58:48.114Z", |
| "systemIds": [ |
| "org.grails.plugins:micronaut-beans" |
| ], |
| "vcsUrl": "https://github.com/grails-plugins/micronaut-beans" |
| }, |
| "documentationUrl": "https://grails-plugins.github.io/micronaut-beans/", |
| "mavenMetadataUrl": null, |
| "readme": "https://grails-plugins.github.io/micronaut-beans/" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "middleware", |
| "repo": "plugins", |
| "owner": "lduarte", |
| "desc": "Grails middleware plugin", |
| "labels": [ |
| "middleware" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/driverpt/grails-middleware/issues", |
| "latestVersion": "0.0.3", |
| "updated": "2016-03-31T13:31:54.765Z", |
| "systemIds": [ |
| "org.grails.plugins:middleware" |
| ], |
| "vcsUrl": "https://github.com/driverpt/grails-middleware" |
| }, |
| "documentationUrl": "https://driverpt.github.io/grails-middleware/latest", |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/driverpt/grails-middleware\"><img src=\"https://travis-ci.org/driverpt/grails-middleware.svg\" alt=\"Build Status\" /></a></p>\n<h1>Grails Middleware Plugin</h1>\n<p>See <a href=\"https://driverpt.github.io/grails-middleware/latest\">documentation</a> for further information.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "modninfobip", |
| "repo": "plugins-libraries", |
| "owner": "modnsolutions", |
| "desc": "Infobip SMS Grails plugin", |
| "labels": [ |
| "infobip", |
| "sms" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/osaetinevbuoma/modninfobip/issues", |
| "latestVersion": "1.0.2", |
| "updated": "2016-08-31T14:10:51.013Z", |
| "systemIds": [ |
| "com.modnsolutions:modninfobip", |
| "org.grails.plugins:modninfobip" |
| ], |
| "vcsUrl": "https://github.com/osaetinevbuoma/modninfobip" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Infobip plugin <a href=\"https://travis-ci.org/osaetinevbuoma/modninfobip\"><img src=\"https://travis-ci.org/osaetinevbuoma/modninfobip.svg?branch=master\" alt=\"Build Status\" /></a></h1>\n<p>Grails plugin for Infobip SMS API</p>\n<h2>Prerequisite to using <strong>modninfobip</strong> plugin</h2>\n<ul>\n<li>Sign up for an <a href=\"www.infobip.com\">infobip</a> account</li>\n<li>Confirm your account</li>\n</ul>\n<h2>Method Declarations</h2>\n<h3>Generate basic authorization</h3>\n<pre><code>String basicAuthorization(String username, String password)\n</code></pre>\n<ul>\n<li>username - infobip username</li>\n<li>password - infobip password</li>\n</ul>\n<p><strong>NB</strong>: Basic authorization is mandatory for all infobip REST API requests.</p>\n<h3>Send an SMS to a single phone number</h3>\n<pre><code>JSONObject sendSingleMessage(String authorization, String from, String to, String text)\n</code></pre>\n<ul>\n<li>from - Sender phone number registered on infobip (Phone numbers are usually prefixed with <em>+ (plus sign)</em>, followed by a <em>country code</em>, <em>network code</em> and the <em>subscriber number</em>)</li>\n<li>to - Recipient phone number</li>\n<li>text - SMS message to send</li>\n</ul>\n<h3>Send an SMS to multiple phone numbers</h3>\n<pre><code>JSONObject sendSingleMessage(String authorization, String from, List to, String text)\n</code></pre>\n<ul>\n<li>to - A list of string types of recipients' phone numbers</li>\n</ul>\n<h3>Send multiple SMS's to multiple or same recipient phone number</h3>\n<pre><code>JSONObject sendMultipleMessages(String authorization, JSONObject data)\n</code></pre>\n<ul>\n<li>data - A json object of data. An example is show below.</li>\n</ul>\n<pre><code>{ \n "messages":[ \n { \n "from":"InfoSMS",\n "to":[ \n "41793026727",\n "41793026731"\n ],\n "text":"May the Force be with you!"\n },\n { \n "from":"41793026700",\n "to":"41793026785",\n "text":"A long time ago, in a galaxy far, far away... It is a period of civil war. Rebel spaceships, striking from a hidden base, have won their first victory against the evil Galactic Empire."\n }\n ]\n}\n</code></pre>\n<h3>Get delivery reports</h3>\n<pre><code>JSONObject deliveryReport(String authorization)\n</code></pre>\n<h3>Get filtered delivery reports</h3>\n<pre><code>JSONObject deliveryReport(String authorization, Map filters)\n</code></pre>\n<ul>\n<li>filters - A filter map. View <a href=\"https://dev.infobip.com/docs/delivery-reports\">here</a> for more filter information.</li>\n</ul>\n<p><strong>NB</strong>: Delivery reports can only be gotten once. A second call returns an empty result.</p>\n<h3>Pull received messages to phone number from Infobip server</h3>\n<pre><code>JSONObject pullReceivedMessages(String authorization)\nJSONObject pullReceivedMessages(String authorization, int limit)\n</code></pre>\n<ul>\n<li>limit - The number of messages to pull from server. Default is 50 and maximum is 10000</li>\n</ul>\n<h3>Get logs</h3>\n<pre><code>// Call the messageLog method of corresponding service \n// class (SendMessageService or ReceiveMessageService)\nJSONObject messageLog(String authorization)\n</code></pre>\n<h3>Get filtered logs</h3>\n<pre><code>// Call the messageLog method of corresponding service \n// class (SendMessageService or ReceiveMessageService)\nJSONObject messageLog(String authorization, Map filters)\n</code></pre>\n<ul>\n<li>filters - A filter map. View <a href=\"https://dev.infobip.com/docs/message-logs\">here</a> for filter information for sent messages and\n<a href=\"https://dev.infobip.com/docs/received-messages-logs\">here</a> for filter information for received messages.</li>\n</ul>\n<h3>Check Account Balance</h3>\n<pre><code>JSONObject checkAccountBalance(String authorization)\n</code></pre>\n<h2>Installation</h2>\n<p>Edit <code>application.groovy</code> (or <code>application.yml</code> if you prefer) and <code>build.gradle</code></p>\n<ul>\n<li>application.groovy</li>\n</ul>\n<pre><code>infobip.host = "https://api.infobip.com/sms/1"\n</code></pre>\n<p><strong>OR</strong></p>\n<ul>\n<li>application.yml</li>\n</ul>\n<pre><code>infobip:\n host: https://api.infobip.com/sms/1\n</code></pre>\n<ul>\n<li>build.gradle</li>\n</ul>\n<pre><code>repositories {\n maven {\n url "http://dl.bintray.com/modnsolutions/plugins-libraries" \n }\n}\n\ndependencies {\n compile "org.grails.plugins:modninfobip:1.0.2"\n}\n</code></pre>\n<h2>Usage</h2>\n<ul>\n<li>Import the required service classes into you Grails Service or Controller class.</li>\n</ul>\n<pre><code>import com.modnsolutions.ReceiveMessageService //service to pull received messages and message log from infobip server\nimport com.modnsolutions.SendMessageService // service to send messages via infobip, get delivery report and message logs\nimport com.modnsolutions.UtilitiesService\n</code></pre>\n<ul>\n<li>Inject AuthorizationService and SendMessageService classes into your Grails Service or Controller class.</li>\n</ul>\n<pre><code>ReceiveMessageService receiveMessageService\nSendMessageService sendMessageService\nUtilitiesService utilitiesService\n</code></pre>\n<ul>\n<li>In your class method, generate your basic authorization code and send your messages</li>\n</ul>\n<pre><code>String basicAuthorization = utilitiesService.basicAuthorization("INFOBIP_USERNAME", "INFOBIP_PASSWORD")\nJSONObject singleMessageResponse = sendMessageService.sendSingleMessage(basicAuthorization, from, to, text)\nprintln singleMessageResponse\n</code></pre>\n<h3>Example</h3>\n<pre><code>import com.modnsolutions.ReceiveMessageService\nimport com.modnsolutions.SendMessageService\nimport com.modnsolutions.UtilitiesService\n\n// In Grails you can handle json objects and arrays by importing and using\n// import org.grails.web.json.JSONArray\n// import org.grails.web.json.JSONObject\n\nclass SMSController {\n ReceiveMessageService receiveMessageService\n SendMessageService sendMessageService\n UtilitiesService utilitiesService\n \n def sendSingleSMS(String from, String to, String text) {\n String basicAuthorization = utilitiesService.basicAuthorization("INFOBIP_USERNAME", "INFORBIP_PASSWORD")\n render sendMessageService.sendSingleMessage(basicAuthorization, from, to, text)\n }\n \n def pullMessages() {\n String basicAuthorization = utilitiesService.basicAuthorization("INFOBIP_USERNAME", "INFORBIP_PASSWORD")\n render receiveMessageService.pullReceivedMessages(basicAuthorization)\n }\n \n def checkAccountBalance() {\n String basicAuthorization = utilitiesService.basicAuthorization("INFOBIP_USERNAME", "INFORBIP_PASSWORD")\n render utilitiesService.checkAccountBalance(basicAuthorization)\n }\n \n ...\n}\n</code></pre>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "mongodb", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "GORM for MongoDB", |
| "labels": [ |
| "gorm", |
| "mongodb" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/gorm-mongodb/issues", |
| "latestVersion": "8.2.0", |
| "updated": "2024-03-15T19:26:14.000Z", |
| "systemIds": [ |
| "org.grails.plugins:mongodb" |
| ], |
| "vcsUrl": "https://github.com/grails/gorm-mongodb" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/grails/plugins/mongodb/maven-metadata.xml", |
| "readme": "<p><img src=\"https://github.com/grails/gorm-mongodb/workflows/Java%20CI/badge.svg?branch=master\" alt=\"Java CI\" />\n<img src=\"https://github.com/grails/gorm-mongodb/workflows/Release/badge.svg?branch=master\" alt=\"Release\" /></p>\n<h1>GORM for MongoDB</h1>\n<p>This project implements <a href=\"http://gorm.grails.org/latest/\">GORM</a> for the MongoDB Document Database.</p>\n<p>NOTE: This source code here is for version 6.x and above. For prevoius versions' source see the relevant branch on the <a href=\"https://github.com/grails/grails-data-mapping/tree/5.x/grails-datastore-gorm-mongodb\">Grails Data Mapping project</a>.</p>\n<p>For more information see the following links:</p>\n<ul>\n<li><a href=\"http://gorm.grails.org/latest/mongodb/manual\">Documentation</a></li>\n<li><a href=\"http://gorm.grails.org/latest/mongodb/api\">API</a></li>\n<li><a href=\"https://grails.org/plugins.html#plugin/mongodb\">Grails Plugin</a></li>\n</ul>\n<p>For the current development version see the following links:</p>\n<ul>\n<li><a href=\"http://gorm.grails.org/snapshot/mongodb/manual\">Beta Documentation</a></li>\n<li><a href=\"http://gorm.grails.org/snapshot/mongodb/api\">Beta API</a></li>\n</ul>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "mongogee", |
| "repo": "plugins", |
| "owner": "ikalizpet", |
| "desc": "Mongogee is a Grails plugin for MongoDB data migration management", |
| "labels": [ |
| "migration", |
| "mongodb" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/ikaliZpet/mongogee/issues", |
| "latestVersion": "0.9.4", |
| "updated": "2018-01-04T18:58:41.518Z", |
| "systemIds": [ |
| "org.grails.plugins:mongogee" |
| ], |
| "vcsUrl": "https://github.com/ikaliZpet/mongogee" |
| }, |
| "documentationUrl": "https://binlecode.github.io/grails-mongogee/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>mongogee</h1>\n<p>MongoDB data migration Grails Plugin.</p>\n<p>TravisCI <a href=\"https://travis-ci.org/binlecode/mongogee\"><img src=\"https://travis-ci.org/binlecode/mongogee.svg?branch=master\" alt=\"Build Status\" /></a></p>\n<h2>INTRODUCTION</h2>\n<p>Mongogee Grails plugin is a simple, secure service for mongodb data migration management.\nThis plugin is inspired by Mongobee (https://github.com/mongobee/mongobee) MongoDB data migration toolset.</p>\n<p><strong>All the credits of the annotation based migration change management logic go to the Mongobee authors.</strong></p>\n<p>This repository contains source code of Mongogee, and a testing sample host Grails application.</p>\n<h2>INSTALL</h2>\n<p>In host Grails application's build.gradle file:</p>\n<pre><code>plugins {\n\tcompile ':mongogee:$version'\n}\n</code></pre>\n<h2>PREREQUISITES</h2>\n<p>Hosting Grails application version 3.0+.</p>\n<h2>CONFIGURATION</h2>\n<p>In host Grails application grails-app/conf/application.yml</p>\n<pre><code class=\"language-yaml\">mongogee:\n changeEnabled: true \t\t # default is true\n continueWithError: false \t # default is false\n changeLogsScanPackage: 'some.package' # required, no default value\n lockingRetryEnabled: false # default to true\n lockingRetryIntervalMillis: 3000 # default to 5s\n lockingRetryMax: 60 # default to 120, aka 10min\n</code></pre>\n<h2>WRITE MIGRATION CHANGES</h2>\n<p>Adopting and extending Mongobee (https://github.com/mongobee/mongobee) annotations. There are two level of migration change units: change-logs (class level) and change-sets (method level).\nChange-logs can be written in either Java or Groovy. Some groovy examples are below:</p>\n<pre><code class=\"language-groovy\">@ChangeLog(order = '001')\n\tclass MongogeeTestChangeLog {\n\t\n\t @ChangeSet(author = "testuserA", id = "test1", order = "01")\n\t void testChangeSet1() {\n\t System.out.println("invoked 1")\n\t }\n\t\n\t @ChangeSet(author = "testuserB", id = "test2", order = "02")\n\t void testChangeSet2(DB db) {\n\t System.out.println("invoked 2 with mongodb DB argument: $db")\n\t }\n\t\n\t @ChangeSet(author = 'testuser', id = 'test3', order = '03', runAlways = true)\n\t void testChangeSetRunAlways() {\n\t println 'invoke runAlways'\n\t }\n\t\n\t @ChangeSet(author = 'testuser', id = 'test4', order = '04')\n\t @ChangeEnv('development')\n\t void testChangeSetEnvDevelopment() {\n\t println 'invoke test for env development'\n\t }\n\t\n\t @ChangeSet(author = 'testuser', id = 'test5', order = '05')\n\t @ChangeEnv('test')\n\t void testChangeSetEnvTest() {\n\t println 'invoke test for env test'\n\t }\n\t}\n</code></pre>\n<h2>RUN MIGRATION</h2>\n<p><strong>Version 0.9 and up:</strong> The manual line adding below is no longer needed. Mongogee migration service will be executed automatically if <code>changeEnabled</code> is set to <code>true</code> (which is also default).</p>\n<p><strong>Version 0.8 and below:</strong> Add following to init/BootStrap.groovy</p>\n<pre><code class=\"language-groovy\">class BootStrap {\n\n MongogeeService mongogeeService\n\n def init = { servletContext ->\n // ...\n\n mongogeeService.execute()\n\n }\n\n // ...\n}\n</code></pre>\n<h2>CHANGE LOG</h2>\n<h4>v 0.9.1</h4>\n<ul>\n<li>issue-11: change entry log can intercept and save exception error information during change set invocation, and then bubble up back to main execution flow</li>\n</ul>\n<h4>v 0.9</h4>\n<ul>\n<li>issue-9: simplify hosting app to save the manual line adding in host app bootstrap.groovy</li>\n</ul>\n<h4>v 0.8</h4>\n<ul>\n<li>issue-4: add run-count support in changeEntry persistence for those repeatable changeSets</li>\n</ul>\n<h4>v 0.7 and under</h4>\n<ul>\n<li>issue-3: add loop/lock-retry ability to application start-up</li>\n</ul>\n<h2>CONTRIBUTORS</h2>\n<p>Bin Le (bin.le.code@gmail.com)</p>\n<h2>LICENSE</h2>\n<p>Apache License Version 2.0. (http://www.apache.org/licenses/)</p>\n" |
| }, |
| { |
| "deprecated": "Since Grails 3.2 - Use GORMs built-in support for multitenancy.", |
| "bintrayPackage": { |
| "name": "multitenant", |
| "repo": "plugins", |
| "owner": "troutbird", |
| "desc": null, |
| "labels": [ |
| "multitenant" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/ejaz-ahmed/grails-multitenant-plugin/issues", |
| "latestVersion": "0.1", |
| "updated": "2016-03-31T13:31:54.724Z", |
| "systemIds": [ |
| "org.grails.plugins:multitenant" |
| ], |
| "vcsUrl": "https://github.com/ejaz-ahmed/grails-multitenant-plugin" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<p># TOC</p>\n<h1>grails-multitenant-plugin</h1>\n<p>This plugin is sponsored by <a href=\"https://ipgeolocation.io\">IP Geolocation</a>. It adds multitenant support for grails 3 applications based on hibernate filters. Tenants are resolved using spring security.</p>\n<h2>Note</h2>\n<p>Only branch grails3.0.xhibernate4 is working. Rest of branches are for GORM5 which has broken the way hibernate filters are applied. So they won't work. Also, this plugin works only for Grails 3.0 and 3.1. For later versions of grails, use GORM's built in multi-tenancy support.\nThe work on this plugin has been stopped in favor of Grails internal support for Multi-tenant architecture.</p>\n<h2>Installation</h2>\n<p>Add following dependency in build.gradle</p>\n<pre><code>compile 'org.grails.plugins:multitenant:0.1'\n</code></pre>\n<p>Add configClass attribute in application.yml under dataSource section like this:</p>\n<pre><code> configClass: org.grails.plugin.multitenant.HibernateMultitenantConfiguration \n</code></pre>\n<h1>Architecture</h1>\n<p>This plugin uses single database single schema differentiator based technique to identify tenants.</p>\n<h2>Resolving Tenant</h2>\n<p>Currently it resolves tenant using spring security. So you have to edit spring security user domain class to implement TenantIdentifier trait like this:</p>\n<pre><code>class User implements Serializable, TenantIdentifier\n</code></pre>\n<p>It add userTenantId property to User domain class and injects two closures dynamically to this domain</p>\n<h3>withTenantId</h3>\n<p>This closure executes a particular code inside its scope with a tenantId supplied as parameters even if the logged in user does not belong to that tenant. You can only execute idempotent code inside this block. If your code is query, or some other read only operation, it will execute that with supplied tenantId. If your code is going to change something in database, it will use tenantId of logged in user. Be careful . .</p>\n<pre><code>User.withTenantId(12){\n\n// Your code goes here\n\n}\n\n</code></pre>\n<h3>withoutTenantId</h3>\n<p>As the name states, you can bypass tenantId filter temporarily to do operations not specific to any tenant.</p>\n<pre><code>User.withoutTenantId(){\n\n// You code goes here\n\n</code></pre>\n<p>The code in this scope should be read only as is the case with withTenantId method above.</p>\n<h2>Multitenat Domain Classes</h2>\n<p>You have to implement Multitenant trait in all domain classes you want to be multitenant.</p>\n<pre><code>class Book implement Multitenant\n</code></pre>\n<p>This will add a property tenantId to domain class and three methods as below:</p>\n<pre><code>Long tenantId\n\n def beforeInsert() {\n if(tenantId == null){\n tenantId = tenantResolverService.resolveTenant()\n }\n }\n\n def beforeValidate() {\n if(tenantId == null){\n tenantId = tenantResolverService.resolveTenant()\n }\n }\n\n def beforeUpdate() {\n if(tenantId == null){\n tenantId = tenantResolverService.resolveTenant()\n }\n }\n \n</code></pre>\n<p>So if you want to use these methods in any of multitenant domain class, you have to reproduce above code along with your own implementation as yours will overwrite these methods.</p>\n<h2>TenantResolverService</h2>\n<p>This plugin provide TenantResolverService to your application which can be injected anywhere just like normal grails services. It provides only one method resolveTenant which provides tenantId of current user. Multitenant plugin makes extensive use of this service at various places inside the code. Multitenant filter intercepts controller actions only. If you want to do some multitenant stuff inside a service then you should call that service from controller or use withTenantId as below:</p>\n<pre><code>def tenantResolverService\nUser.withTenantId(tenantResolverService.resolveTenant()){\n // your code here\n}\n</code></pre>\n<h1>About ipgeolocation.io</h1>\n<p><a href=\"https://ipgeolocation.io\">IP Geolocation's</a> IP intelligence APIs help developer's find out Geolocation, Tim Zone, Local Currency and much more from just an IP address. For more information checkout <a href=\"https://ipgeolocation.io/documentation\">document page</a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "neo4j", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "GORM for Neo4j", |
| "labels": [ |
| "gorm", |
| "graph", |
| "neo4j" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/gorm-neo4j/issues", |
| "latestVersion": "8.1.0", |
| "updated": "2024-03-15T21:01:53.000Z", |
| "systemIds": [ |
| "org.grails.plugins:neo4j" |
| ], |
| "vcsUrl": "https://github.com/grails/gorm-neo4j" |
| }, |
| "documentationUrl": "https://gorm.grails.org/latest/neo4j/manual/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/grails/plugins/neo4j/maven-metadata.xml", |
| "readme": "<h1>GORM for Neo4j</h1>\n<p>This project implements <a href=\"http://gorm.grails.org/latest/\">GORM</a> for the Neo4j 3.x Graph Database using the Bolt Java Driver.</p>\n<p>For more information see the following links:</p>\n<ul>\n<li><a href=\"http://gorm.grails.org/latest/neo4j/manual\">Documentation</a></li>\n<li><a href=\"http://gorm.grails.org/latest/neo4j/api\">API</a></li>\n<li><a href=\"https://grails.org/plugins.html#plugin/neo4j\">Grails Plugin</a></li>\n<li><a href=\"https://travis-ci.org/grails/gorm-neo4j\"><img src=\"https://travis-ci.org/grails/gorm-neo4j.svg?branch=master\" alt=\"Build Status\" /></a></li>\n</ul>\n<p>For the current development version see the following links:</p>\n<ul>\n<li><a href=\"http://gorm.grails.org/snapshot/neo4j/manual\">Beta Documentation</a></li>\n<li><a href=\"http://gorm.grails.org/snapshot/neo4j/api\">Beta API</a></li>\n</ul>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "newrelic", |
| "repo": "plugins", |
| "owner": "agorapulse", |
| "desc": "Grails NewRelic plugin", |
| "labels": [ |
| "newrelic" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/agorapulse/grails-newrelic/issues", |
| "latestVersion": "5.2.0", |
| "updated": "2019-07-16T09:16:45.158Z", |
| "systemIds": [ |
| "org.grails.plugins:newrelic" |
| ], |
| "vcsUrl": "https://github.com/agorapulse/grails-newrelic" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>NewRelic Grails Plugin</h1>\n<p><a href=\"https://travis-ci.org/agorapulse/grails-newrelic\"><img src=\"https://travis-ci.org/agorapulse/grails-newrelic.svg\" alt=\"Build Status\" /></a>\n<a href=\"https://bintray.com/agorapulse/plugins/newrelic/_latestVersion\"><img src=\"https://api.bintray.com/packages/agorapulse/plugins/newrelic/images/download.svg\" alt=\"Download\" /></a></p>\n<h1>Introduction</h1>\n<p>This plugin will make <a href=\"http://newrelic.com\">New Relic</a> instrumentation available to a Grails project.<br />\nIt is a port to Grails 3.X of the original <a href=\"https://github.com/Sensis/grails-newrelic-plugin/\">NewRelic Grails Plugin</a>, originally written by <a href=\"https://github.com/cplim\">CP Lim</a>.\nStarting with version <code>5.2.0</code> the plugin is compatibile with Grails 4.</p>\n<p><strong>Grails NewRelic Plugin</strong> provides the following Grails artefacts:</p>\n<ul>\n<li><strong>NewRelicInterceptor</strong> - An interceptor matching all requests to automatically name transactions as <code>{controllerName}/{actionName}</code>.</li>\n<li><strong>NewRelicService</strong> - A client to call <a href=\"https://docs.newrelic.com/docs/agents/java-agent/custom-instrumentation/java-agent-api\">NewRelic Java agent API</a>, which is a wrapper around <a href=\"http://newrelic.github.io/java-agent-api/javadoc/com/newrelic/api/agent/NewRelic.html\">NewRelic API java library</a>.</li>\n<li><strong>NewRelicTagLib</strong> - A collection of tags to easily integrate <a href=\"http://newrelic.com/browser-monitoring\">NewRelic Browser</a> in your GSPs for Real User Monitoring (RUM).</li>\n</ul>\n<p>New Relic needs to be installed on the running application server in order for the plugin to work.\nThis is <a href=\"https://newrelic.com/docs/java/java-agent-installation\">extensively documented</a> by the New Relic team.\nOnce installed, New Relic Browser will need to be configured for <a href=\"https://docs.newrelic.com/docs/agents/java-agent/instrumentation/page-load-timing-java#manual_instrumentation\">manual instrumentation</a> .</p>\n<h1>Installation</h1>\n<p>Declare the plugin dependency in the <em>build.gradle</em> file, as shown here:</p>\n<pre><code class=\"language-groovy\">repositories {\n ...\n maven { url "http://dl.bintray.com/agorapulse/plugins" }\n}\ndependencies {\n ...\n compile "org.grails.plugins:newrelic:5.2.0"\n}\n</code></pre>\n<p>Thanks to binary incompability of trait between the different Groovy version, current version can be used with Grails <code>3.2.11</code> and newer.\nTry older versions of this plugin if you need to use it with older version of Grails.</p>\n<h1>Config</h1>\n<p>By default the New Relic RUM code will only be enabled for Production environments.\nIf you need it to be enabled for other environments, make sure that it is explicitly enabled in your configs</p>\n<pre><code class=\"language-yml\">newrelic:\n enabled: true\n</code></pre>\n<h1>Usage</h1>\n<p>Once New Relic and this plugin has been added to your web application, you are ready to add the tags to your page(s).<br />\nNew Relic provides some <a href=\"https://docs.newrelic.com/docs/agents/java-agent/instrumentation/page-load-timing-best-practices-java\">best practices</a> on when to all these tag methods.<br />\nIdeally, you would only need to add it to your layout page(s) as follows:</p>\n<pre><code class=\"language-jsp\"><!DOCTYPE html>\n<html>\n<head>\n <meta name="viewport" content="width=device-width, initial-scale=1">\n <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>\n <newrelic:browserTimingHeader/>\n <!-- other tags -->\n</head>\n<body>\n <!-- more tags -->\n <newrelic:browserTimingFooter/>\n</body>\n</html>\n</code></pre>\n<p>However, if there are more GSP that need these tags, then just make sure they are added at the appropriate locations in the DOM.</p>\n<h1>Enabling NewRelic for Development</h1>\n<p>NewRelic should be enabled in the production environment as per the instructions <a href=\"https://newrelic.com/docs/java/java-agent-installation\">here</a>, but if you need to enable this in other environments, make sure that the configs have enabled NewRelic for your environment, and add the following to your GRAILS_OPT environment</p>\n<pre><code class=\"language-bash\">export GRAILS_OPTS="-javaagent:/path/to/newrelic.jar"\n</code></pre>\n<p>The next time you execute 'run-app' or 'run-war', NewRelic instrumentation code will be included in your generated HTML pages.</p>\n<p>On newer versions of grails that use a forked jvm, you may need to include the java agent in your tomcat configuration. This is in BuildConfig.groovy.</p>\n<pre><code class=\"language-groovy\">grails.tomcat.jvmArgs = ["-javaagent:/path/to/newrelic.jar"]\n</code></pre>\n<h1>BONUS - Installing and configuring NewRelic on AWS Elastic Beanstalk</h1>\n<p>Here are some instructions to install/configure NewRelic app AND server monitoring on AWS ElasticBeanstalk.\nIt will also call the NewRelic deployment API each time you start a new env.</p>\n<p>1- Create a folder <code>src/main/webapp/.ebextensions</code>, a folder <code>src/main/webapp/.ebextensions/files</code> and add the <code>newrelic.jar</code> in it.</p>\n<p>2- Create a file <code>src/main/webapp/.ebextensions/files/newrelic.yml.sh</code> (to dynamically generate newrelic.yml based on app env properties)</p>\n<pre><code class=\"language-bash\">cat << EOF\ncommon: &default_settings\nlicense_key: '$NR_LICENSE'\nenable_auto_transaction_naming: false\napp_name: $NR_APPNAME\nEOF\n</code></pre>\n<p>3- Create a file <code>src/main/webapp/.ebextensions/newrelic.sh</code></p>\n<pre><code class=\"language-bash\">#!/bin/sh\n# New Relic (Application monitoring)\nmkdir /var/lib/newrelic\nmv ./.ebextensions/files/newrelic*.jar /var/lib/newrelic/\nbash ./.ebextensions/files/newrelic.yml.sh > /var/lib/newrelic/newrelic.yml\n\n# New Relic Agent (Server monitoring)\nrpm -Uvh https://yum.newrelic.com/pub/newrelic/el5/x86_64/newrelic-repo-5-3.noarch.rpm\nyum -y install newrelic-sysmond\n/usr/sbin/nrsysmond-config \ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdset license_key=$NR_LICENSE\n/etc/init.d/newrelic-sysmond start\n\n# New Relic deployment event\nexport AP_VERSION=`` `cat ./META-INF/grails.build.info | grep info.app.version | cut -d= -f2` ``\njava -jar /var/lib/newrelic/newrelic.jar deployment \ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdrevision=$AP_VERSION\n</code></pre>\n<p>4- Create a file <code>src/main/webapp/.ebextensions/app.config</code></p>\n<pre><code>container_commands:\n newrelic:\n command: "bash -x .ebextensions/newrelic.sh"\n</code></pre>\n<p>Then, in your Beanstalk app config options, add <code>-javaagent:/var/lib/newrelic/newrelic.jar</code> to the JVM command line parameter and set <code>NR_LICENSE</code> and <code>NR_APPNAME</code> env properties.</p>\n<h1>Bugs</h1>\n<p>To report any bug, please use the project <a href=\"http://github.com/agorapulse/grails-newrelic/issues\">Issues</a> section on GitHub.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "novamail", |
| "repo": "plugins", |
| "owner": "novadge", |
| "desc": "The Novamail plug-in provides e-mail sending and retrieving capabilities to a Grails application. It is also capable of sending emails asynchronously by using a scheduled Job", |
| "labels": [ |
| "mail" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/Novadge/novamail/issues", |
| "latestVersion": "0.1.8", |
| "updated": "2020-05-25T03:31:08.817Z", |
| "systemIds": [ |
| "org.grails.plugins:novamail", |
| "com.novadge.plugins:novamail", |
| "novamail:novamail" |
| ], |
| "vcsUrl": "https://github.com/Novadge/novamail" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Novamail</h1>\n<p><a href=\"https://travis-ci.org/Novadge/novamail\"><img src=\"https://travis-ci.org/Novadge/novamail.svg?branch=master\" alt=\"Build Status\" /></a></p>\n<h2>Description</h2>\n<p>The Novamail plug-in provides e-mail sending and receiving capabilities to a Grails application. It is also capable of sending emails asynchronously by using a scheduled Job.</p>\n<h2>Configuration</h2>\nI recommend you add the following to application.groovy config file. Please create the file if it doesn't exist. \n<p>Add your email provider properties to grails configuration file: Example\nAssuming you want to add config for a gmail account for 'john@gmail.com' then add the following to your grails config file.</p>\n<p><code>novamail.hostProps = [</p>\n<pre><code> ["host":'imap.gmail.com'],\n ["mail.imap.host":"imap.gmail.com"],\n ["mail.store.protocol": "imaps"],\n ["mail.imap.socketFactory.class": "javax.net.ssl.SSLSocketFactory"],\n ["mail.imap.socketFactory.fallback": "false"],\n ["mail.imaps.partialfetch":"false"],\n ["mail.mime.address.strict": "false"],\n ["mail.smtp.starttls.enable": "true"],\n ["mail.smtp.host": "smtp.gmail.com"],\n ["mail.smtp.auth": "true"],\n ["mail.smtp.socketFactory.port": "465"],\n ["mail.smtp.socketFactory.class": "javax.net.ssl.SSLSocketFactory"],\n ["mail.smtp.socketFactory.fallback": "false"]\n</code></pre>\n<p>]\n</code></p>\n <code>\n novamail{\n<pre><code> hostname= System.getenv("CS_HOSTNAME")\n username= System.getenv("CS_USERNAME")\n password= System.getenv("CS_PASSWORD")\n store= System.getenv("CS_STORE")\n \n }\n</code></pre>\n </code> \n<p><small>Avoid having passwords in your code. Store them as Environment variables. </small></p>\n<h3>Side note </h3>\nNovamail will try to use predefined host props for some popular email providers if you do not provide hostProps\n<h2>Usage</h2>\n<p>Inject messagingService into your class</p>\n<p><code>def messagingService</code></p>\n<p><em>messagingService</em> is a Grails service that provides a single method called sendEmail that takes parameters.\nPlease note that 'sendEmail()' is overloaded 'see http://en.wikipedia.org/wiki/Function_overloading' and can take various variations of parameters.</p>\n<br/>\nOne simple form is:\n<code>\nsendEmail(Map map)\n</code>\n<p>Where ......</p>\n<p>map contains parameters...\nmap.to: Email recipient eg recipient@gmail.com</p>\n<p>map.subject: "Your email subject"</p>\n<p>map.body: "The body of your message"</p>\n<h2>Example</h2>\n<p>An example usage can be seen below.</p>\n<code>\n<pre><code>Class YourController{\n \n def messagingService\n ...\n def yourMethod(){\n def map = [to:"recipient@gmail.com",subject:"Email subject",body:"email body"]\n messagingService.sendEmail(map)\n \n }\n\n}\n</code></pre>\n</code>\n<h1>Second form</h1>\n<h2>Requirements</h2>\n<p>To use the <code>messagingService</code> with mapped parameters, you need to declare a\nmap with the required variables. These are,\n<code>\nhostname, username, password,\nfrom, to, subject, body, html, attachments, hostProps</p>\n<p></code>.</p>\n<ul>\n<li>hostname : String</li>\n<li>username: Stiring</li>\n<li>password : String</li>\n<li>from : String </li>\n<li>to : String </li>\n<li>subject : String </li>\n<li>body : String </li>\n<li>html : boolean </li>\n<li> attachments : List<File> </li>\n</ul>\n<p><code>html</code> is boolean that defaults to <code>true</code>,</p>\n<p><code>attachments</code> is a List of type File (for file attachments) and is optional,\nand</p>\n<p><code>hostProps</code> is a map of host properties (see above). <br /></p>\n<p>If <code>hostname, username, password, from, hostProps</code> have been set in the\nConfig.groovy file, they do not have to be added to your map parameter.\n<code>html</code> defaults to <code>true</code> so that can be\nomitted as well except when set explicitly (your choice). <br /></p>\n<h2>Example Usage</h2>\n<code>\n<pre><code>Class MyController {\n def messagingService\n \n def myMethod() {\n ...\n def map = [username:"john@doe.com", password:"john_password", from:"JOHN Doe<john@doe.com>", to: "recepeitn@gmail.com", subject: "Hello there!", body: "Just to test out awesome Novamail"]\n messagingService.sendEmail(map) // Call the messagingService sendEmail method passing in the map\n }\n}\n</code></pre>\n</code>\n" |
| }, |
| { |
| "deprecated": "Duplicate entry of plugin from same author. This entry should probably be removed from the registry.", |
| "bintrayPackage": { |
| "name": "org.grails.plugins:csv", |
| "repo": "plugins", |
| "owner": "vsachinv", |
| "desc": "Grails CSV plugin", |
| "labels": [ |
| "csv" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/vsachinv/grails-csv/issues", |
| "latestVersion": null, |
| "updated": "2017-11-15T13:54:48.264Z", |
| "systemIds": [ |
| |
| ], |
| "vcsUrl": "https://github.com/vsachinv/grails-csv" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>grails-csv</h1>\n<p>The csv plugin provides utility methods and also support for reading/writing to csv files. It uses <code>opencsv</code> library.</p>\n<h1>Installation</h1>\n<p>Add dependency to your build.gradle for Grails 3.x:</p>\n<pre><code>repositories {\n ...\n maven { url "http://dl.bintray.com/sachinverma/plugins" }\n}\n\ndependencies {\n compile 'org.grails.plugins:grails-csv:1.0.1'\n}\n</code></pre>\n<p>For further info: [https://github.com/vsachinv/grails-csv/wiki/Grails-CSV]</p>\n" |
| }, |
| { |
| "deprecated": "Source repository is merged into https://github.com/grails-plugins/grails-database-migration and closed. This entry should probably be removed from the registry to avoid confusion.", |
| "bintrayPackage": { |
| "name": "org.grails.plugins:database-migration", |
| "repo": "plugins", |
| "owner": "yamkazu", |
| "desc": "Grails database-migration plugin", |
| "labels": [ |
| "migration" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/yamkazu/database-migration/issues", |
| "latestVersion": "2.0.0.RC1", |
| "updated": "2016-04-14T09:18:54.806Z", |
| "systemIds": [ |
| "org.grails.plugins:database-migration" |
| ], |
| "vcsUrl": "https://github.com/yamkazu/database-migration" |
| }, |
| "documentationUrl": "https://yamkazu.github.io/database-migration/", |
| "mavenMetadataUrl": null, |
| "readme": "<p>This repository has been merged into the https://github.com/grails-plugins/grails-database-migration</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "enforcer", |
| "repo": "plugins", |
| "owner": "virtualdogbert", |
| "desc": "A plugin for enforcing business rules/permissions, that works with Spring Security Core, is easier to implement, and extend. It can also be used as an alternative to Spring Security ACL", |
| "labels": [ |
| "acl", |
| "business-rules", |
| "permissions", |
| "security", |
| "spring-security" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/virtualdogbert/Enforcer/issues", |
| "latestVersion": "3.0.0", |
| "updated": "2023-07-16T17:59:10.000Z", |
| "systemIds": [ |
| "io.github.virtualdogbert:enforcer" |
| ], |
| "vcsUrl": "https://github.com/virtualdogbert/Enforcer" |
| }, |
| "documentationUrl": "https://virtualdogbert.github.io/Enforcer/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/io/github/virtualdogbert/enforcer/maven-metadata.xml", |
| "readme": "<p>The Enforcer Plugin, is a lightweight, easier to maintain/extend/use, alternative to Spring Security ACL. The plugin works off of an EnforcerService and an Enforce Ast transform, The service takes up to 3 closures, a predicate, a failure(defaults to an EnforcerException if not specified) and a success(defaulted to a closure that returns true).</p>\n<p>For documentation see the github page:\n<a href=\"https://virtualdogbert.github.io/Enforcer\">documentation</a></p>\n" |
| }, |
| { |
| "displayName": "feature-switch", |
| "bintrayPackage": { |
| "name": "org.grails.plugins:feature-switch", |
| "repo": "grails-plugins", |
| "owner": "desirable-objects", |
| "desc": "Grails feature-switch plugin", |
| "labels": [ |
| |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/antony/grails-feature-switch/issues", |
| "latestVersion": "1.0", |
| "updated": "2016-03-31T13:31:54.885Z", |
| "systemIds": [ |
| "org.grails.plugins:feature-switch" |
| ], |
| "vcsUrl": "https://github.com/antony/grails-feature-switch" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": null |
| }, |
| { |
| "deprecated": "Duplicate of geb plugin at https://github.com/grails/geb. This entry should probably be removed from the registry.", |
| "bintrayPackage": { |
| "name": "org.grails.plugins:geb", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Grails geb plugin", |
| "labels": [ |
| "testing", |
| "geb" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails3-plugins/geb/issues", |
| "latestVersion": "1.0.1", |
| "updated": "2016-04-01T15:40:48.261Z", |
| "systemIds": [ |
| "org.grails.plugin:geb" |
| ], |
| "vcsUrl": "https://github.com/grails3-plugins/geb/" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails 3.x Geb Plugin</h1>\n<p><a href=\"https://travis-ci.org/grails3-plugins/geb\"><img src=\"https://travis-ci.org/grails3-plugins/geb.svg?branch=master\" alt=\"Build Status\" /></a></p>\n<p>Geb Functional Testing for Grails 3.0</p>\n<p>This plugin just provides the Geb dependencies and a <code>create-functional-test</code> command for generating Geb tests in a Grails 3.0 app. For further reference please see the <a href=\"http://www.gebish.org\">Geb documentation</a></p>\n<p>##\ufffd\ufffd Examples</p>\n<p>If you are looking for examples check:</p>\n<p><a href=\"https://github.com/grails-samples/geb-example-grails\">Geb/Grails example project</a></p>\n<p>or <a href=\"https://github.com/grails/grails3-functional-tests\">Grails 3.x functional test suite</a> where Geb tests are used extensively.</p>\n<h1>Additional Drivers</h1>\n<p>To setup additional drivers you need to add the driver to your <code>build.gradle</code> for example:</p>\n<pre><code>testRuntime 'com.github.detro:phantomjsdriver:1.2.0'\n</code></pre>\n<p>Then you need to create a <code>GebConfig.groovy</code> file to your <code>src/test/resources/</code> directory. For example:</p>\n<pre><code>/*\n\tThis is the Geb configuration file.\n\n\tSee: http://www.gebish.org/manual/current/#configuration\n*/\nimport org.openqa.selenium.chrome.ChromeDriver\nimport org.openqa.selenium.firefox.FirefoxDriver\nimport org.openqa.selenium.phantomjs.PhantomJSDriver\n\nwaiting {\ntimeout = 2\n}\ndriver = { new PhantomJSDriver() }\n</code></pre>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "gorm-envers", |
| "repo": "plugins", |
| "owner": "yingliang-du", |
| "desc": "The gorm-envers Grails plugin add auditting functionality to GROM in your Grails application using Hibernate Envers. The only thing you need to do is add @Audited annotation to the Domain Class that you want to audit. Hibernate Envers will create audit table in the Database for the annotated domain and log all change history.", |
| "labels": [ |
| "envers" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/Yingliang-Du/gorm-envers-grails-plugin/issues", |
| "latestVersion": "0.3", |
| "updated": "2016-03-31T13:31:54.924Z", |
| "systemIds": [ |
| "org.grails.plugins:gorm-envers" |
| ], |
| "vcsUrl": "https://github.com/Yingliang-Du/gorm-envers-grails-plugin" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>gorm-envers-grails-plugin</h1>\n<p>A Grails Plugin for Auditing GORM Domain class using Hibernate Envers. This plugin only work with Grails 3 or later.</p>\n<h2>Using the gorm-envers plugin in your Grails application</h2>\n<p>Add the release version of the plugin dependency in build.gradle</p>\n<pre><code>compile ("org.grails.plugins:gorm-envers:0.3") {\n\texclude module: 'hibernate-core'\n\texclude module: 'hibernate-entitymanager'\n}\n</code></pre>\n<h2>Build from source</h2>\n<h3>Install gorm-envers plugin on your machine</h3>\n<pre><code>git clone https://github.com/Yingliang-Du/gorm-envers-grails-plugin.git\ncd gorm-envers-grails-plugin/gorm-envers\ngrails clean\ngrails compile\ngrails install\n</code></pre>\n<h3>Add the installed plugin dependency in build.gradle</h3>\n<pre><code>compile ("org.grails.plugins:gorm-envers:0.4-SNAPSHOT") {\n\texclude module: 'hibernate-core'\n\texclude module: 'hibernate-entitymanager'\n}\n</code></pre>\n<h2>Audit domain classes in your Grails application</h2>\n<p>Add @Audited annotation to the domain class you want to audit</p>\n<p>That is it!</p>\n<h2>Auditing methods added to domain classes</h2>\n<ul>\n<li><code>findAllRevisions()</code></li>\n<li><code>isAudited()</code></li>\n<li><code>findCurrentRevision()</code></li>\n<li><code>findRevisionNumberForDate()</code></li>\n</ul>\n<h2>Demo after install gorm-envers plugin</h2>\n<pre><code>cd pathto/gorm-envers-grails-plugin/demo\ngrails \ngrails> clean\ngrails> compile\ngrails> run-app\n</code></pre>\n<ul>\n<li>Grails application running at http://localhost:8080</li>\n<li>Do CRUD operation on AuditedDomain and NonAuditedDomain with Grails default interface</li>\n<li>Check out the Database Console in browser at: http://localhost:8080/dbconsole</li>\n<li>Notice the audit table for AuditedDomain had been created: AUDITED_DOMAIN_AUD, and change history of that domain object was loged into this table</li>\n</ul>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "aws", |
| "repo": "grails-plugins", |
| "owner": "grails-aws", |
| "desc": "Grails AWS Plugin", |
| "labels": [ |
| "aws" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-aws/grails-aws/issues", |
| "latestVersion": "2.0.4", |
| "updated": "2017-11-07T07:28:55.078Z", |
| "systemIds": [ |
| "org.grails.plugins:grails-aws" |
| ], |
| "vcsUrl": "https://github.com/grails-aws/grails-aws" |
| }, |
| "documentationUrl": "https://grails-aws.github.io/grails-aws/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Amazon Web Services Grails Plugin</h1>\n<p><a href=\"https://travis-ci.org/grails-aws/grails-aws\"><img src=\"https://travis-ci.org/grails-aws/grails-aws.png?branch=master\" alt=\"Build Status\" /></a>\n<a href=\"https://coveralls.io/github/grails-aws/grails-aws?branch=master\"><img src=\"https://coveralls.io/repos/grails-aws/grails-aws/badge.svg?branch=master&service=github\" alt=\"Coverage Status\" /></a></p>\n<h4>A Grails plugin for interacting with Amazon Web Services</h4>\n<p>Currently supports S3 and S3S</p>\n<h2>Getting Started</h2>\n<p>Add the plugin to the plugins section of <code>grails-app/conf/BuildConfig.groovy</code></p>\n<pre><code class=\"language-groovy\">dependencies {\n runtime 'org.grails.plugins:grails-aws:2.0.1'\n}\n</code></pre>\n<p>Configure the plugin in <code>grails-app/conf/application.yaml</code></p>\n<pre><code class=\"language-yaml\">grails:\n plugin:\n aws:\n credentials:\n accessKey: ASDASDASDASD\n secretKey: fASDd1h/1Hf/0pkQ+nJx+oRSm36t/R8jUI/A1D2\n s3:\n bucket: my-bucket\n</code></pre>\n<h2>Documentation</h2>\n<ul>\n<li><a href=\"http://grails-aws.github.io/grails-aws/1.7.5.0/\">Reference Documentation</a></li>\n<li><a href=\"http://grails-aws.github.io/grails-aws/1.7.5.0/gapi/\">Groovy Documentation</a></li>\n</ul>\n<h2>Contributing</h2>\n<ul>\n<li>Fork it.</li>\n<li>Create a branch (<code>git checkout -b my_markup</code>)</li>\n<li>Commit your changes (<code>git commit -am "Added Snarkdown"</code>)</li>\n<li>Push to the branch (<code>git push origin my_markup</code>)</li>\n<li>Create an <a href=\"issues/new\">Issue</a> with a link to your branch</li>\n<li>Enjoy a refreshing Diet Coke and wait</li>\n</ul>\n<h2>Changelog</h2>\n<p>2.0.1 - October 13 2015</p>\n<ul>\n<li>Grails 3.x support.</li>\n<li>Scripts are not converted yet</li>\n<li>S3 functionality only</li>\n<li>SES not tested!</li>\n</ul>\n<p>1.9.13.4 - September 11 2015</p>\n<ul>\n<li>upgrade jets3t to 0.9.1, httpclient to 4.3.2, and httpcore to 4.3.1</li>\n</ul>\n<p>1.9.13.0 - January 5 2015</p>\n<ul>\n<li>Upgrade to AWS SDK version 1.9.13</li>\n</ul>\n<p>1.7.5.0 - April 11 2014</p>\n<ul>\n<li>Upgrade to AWS SDK version 1.7.5</li>\n<li>Ability to configure SES AWS region</li>\n</ul>\n<p>1.6.7.4 - January 15 2014</p>\n<ul>\n<li>Add the ability to start SWF executions</li>\n<li>Upgrade to httpclient 4.2</li>\n</ul>\n<p>1.6.7.1 - December 10 2013</p>\n<ul>\n<li>Update to AWS SDK version 1.6.7</li>\n</ul>\n<p>1.2.12.4 - November 30 2013</p>\n<ul>\n<li>Added support to access only file metadata on S3</li>\n<li>Remove usages of the deprecated ConfigurationHolder which added warnings in grails logs</li>\n<li>Added support to specify charset for SES</li>\n</ul>\n<p>1.2.12.3 - September 30 2012</p>\n<ul>\n<li>Add support for S3 Server Side Encryption</li>\n</ul>\n<p>1.1.9.2 - May 10 2011</p>\n<ul>\n<li>Release notes: Fixed bug that was always storing the past sent mail addresses in next mail messages.</li>\n</ul>\n<h2>TODO</h2>\n<ul>\n<li>Amazon Cloudfront * Cloudfront Distribution creation</li>\n<li>Amazon SNS * Basic integration with Amazon SNS</li>\n<li>Amazon SQS * Basic integration with Amazon SQS with Typica (http://code.google.com/p/typica/wiki/TypicaSampleCode)</li>\n<li>Amazon Beanstalk * Scripts for allowing deploy directly to Amazon Beanstalk infrastructure</li>\n</ul>\n" |
| }, |
| { |
| "comment": "There are releases for v0.2.1 and v0.2.2 but no artifacts are published.", |
| "bintrayPackage": { |
| "name": "flyway", |
| "repo": "plugins", |
| "owner": "saw303", |
| "desc": "Grails flyway plugin", |
| "labels": [ |
| "migration", |
| "flyway" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/saw303/grails-flyway/issues", |
| "latestVersion": "0.2", |
| "updated": "2016-05-09T15:25:38.033Z", |
| "systemIds": [ |
| "org.grails.plugins:grails-flyway" |
| ], |
| "vcsUrl": "https://github.com/saw303/grails-flyway" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Flyway - Database Migration for Grails</h1>\n<p>This plugin provides <a href=\"http://flywaydb.org/\">Flyway</a> support for your Grails 3 application.</p>\n" |
| }, |
| { |
| "deprecated": "Source repository is gone.", |
| "bintrayPackage": { |
| "name": "org.grails.plugins:grails-markdown", |
| "repo": "grails-plugins", |
| "owner": "tednaleid", |
| "desc": "Grails grails-markdown plugin", |
| "labels": [ |
| "markdown" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://bitbucket.org/tednaleid/grails-markdown/issues", |
| "latestVersion": "3.0.0", |
| "updated": "2016-03-31T13:31:56.039Z", |
| "systemIds": [ |
| "org.grails.plugins:grails-markdown" |
| ], |
| "vcsUrl": "https://bitbucket.org/tednaleid/grails-markdown" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "cas-client", |
| "repo": "maven", |
| "owner": "cwang", |
| "desc": null, |
| "labels": [ |
| |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/cwang/grails3-cas-client/issues", |
| "latestVersion": "3.0", |
| "updated": "2016-03-31T13:31:54.822Z", |
| "systemIds": [ |
| "org.grails.plugins:grails3-cas-client" |
| ], |
| "vcsUrl": "https://github.com/cwang/grails3-cas-client" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>grails3-cas-client</h1>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "grooscript", |
| "repo": "grooscript", |
| "owner": "cdrchops", |
| "desc": "Grooscript Grails Plugin", |
| "labels": [ |
| "grooscript", |
| "groovy", |
| "javascript" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/cdrchops/grooscript-plugins/issues", |
| "latestVersion": "1.3.0", |
| "updated": "2017-05-19T17:34:31.179Z", |
| "systemIds": [ |
| "org.grails.plugins:grooscript" |
| ], |
| "vcsUrl": "https://github.com/cdrchops/grooscript-plugins" |
| }, |
| "documentationUrl": "https://www.grooscript.org/doc.html#_grails_plugin", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grooscript plugins</h1>\n<p><a href=\"https://semaphoreci.com/chiquitinxx/grooscript-plugins\"><img src=\"https://semaphoreci.com/api/v1/chiquitinxx/grooscript-plugins/branches/master/badge.svg\" alt=\"Build Status\" /></a>\n<a href=\"https://ci.appveyor.com/project/chiquitinxx/grooscript-plugins/branch/master\"><img src=\"https://ci.appveyor.com/api/projects/status/rdu67y0p9fac50pu/branch/master?svg=true\" alt=\"Build status\" /></a></p>\n<p>This is a gradle multiproject where the grooscript gradle and grails plugins sources are.</p>\n<p>More info about <a href=\"http://grooscript.org/\">grooscript</a></p>\n<h2>Multi-project</h2>\n<p>Grails 3 build, there are 5 projects:</p>\n<ul>\n<li>grails-core: library used by grooscript gradle and grails plugins</li>\n<li>grails-plugin: grooscript grails 3 plugin(*)</li>\n<li>gradle-plugin: grooscript gradle plugin(*)</li>\n<li>test-app: a grails 3 app to test the grails plugin (build from test-app-sources with gradle task createTestApp )</li>\n<li>websockets-test-app: a grails 3 app to test the grails plugin websocket features (build from websockets-test-app-sources with gradle task createWebsocketsTestApp)</li>\n</ul>\n<p>(*) published in <a href=\"https://bintray.com/chiquitinxx/grooscript\">bintray</a></p>\n<h2>TO-DO</h2>\n<ul>\n<li>Test components (how check final test? not in normal DOM).</li>\n<li>Update documentation.</li>\n</ul>\n<h2>Build</h2>\n<p>To make all checks (included geb tests using chrome remote driver if you built test apps):</p>\n<pre><code>./gradlew check\n</code></pre>\n<h2>Test jar & components</h2>\n<p>To test jar generation with components, first test app must be created with:</p>\n<pre><code>./gradlew createTestApp\n</code></pre>\n<p>Later, run the test with:</p>\n<pre><code>./gradlew checkComponentInJar\n</code></pre>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "iCalendar", |
| "repo": "plugins", |
| "owner": "saw303", |
| "desc": "Grails iCalendar plugin", |
| "labels": [ |
| "calendar", |
| "icalendar" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/saw303/grails-ic-alender/issues", |
| "latestVersion": "0.6.4", |
| "updated": "2019-06-06T07:11:40.354Z", |
| "systemIds": [ |
| "org.grails.plugins:iCalendar" |
| ], |
| "vcsUrl": "https://github.com/saw303/grails-ic-alender" |
| }, |
| "documentationUrl": "https://saw303.github.io/grails-ic-alender/", |
| "mavenMetadataUrl": null, |
| "readme": null |
| }, |
| { |
| "deprecated": "The source repository url for this entry is redirecting to the source repository of another plugin with the same name by ZenHarbinger. This entry in the registry should probably be removed to avoid confusion.", |
| "bintrayPackage": { |
| "name": "org.grails.plugins:jasypt-encryption", |
| "repo": "grails-plugins", |
| "owner": "dtanner", |
| "desc": "Integration with Jasypt, allows easy encryption of information including Hibernate/GORM integration", |
| "labels": [ |
| "encryption", |
| "jasypt" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/dtanner/grails-jasypt/issues", |
| "latestVersion": "2.0.2", |
| "updated": "2017-01-20T05:46:31.670Z", |
| "systemIds": [ |
| "org.grails.plugins:jasypt-encryption" |
| ], |
| "vcsUrl": "https://github.com/dtanner/grails-jasypt" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<p>The Grails Jasypt Encryption plugin provides strong field-level encryption support on Grails GORM String fields. It leverages the <a href=\"http://www.jasypt.org\">Jasypt</a> simplified encryption framework that makes working with the Java Cryptographic Extension (JCE) much easier.</p>\n<p>It also comes with the <a href=\"http://www.bouncycastle.org/java.html\">Bouncy Castle</a> encryption provider, which gives you access to the very secure <a href=\"http://en.wikipedia.org/wiki/Advanced_Encryption_Standard\">AES</a> algorithm.</p>\n<h3>Installation</h3>\n<pre><code>plugins {\n compile "org.grails.plugins:jasypt-encryption:x.x.x"\n}\n</code></pre>\n<p>If your app is using <strong>Grails 4</strong> or higher, then use version <strong>4.0.3</strong> of this plugin.<br />\nIf your app is using <strong>Grails 3</strong> or higher, then use version <strong>2.0.2</strong> of this plugin.<br />\nIf your app is using <strong>Grails 2</strong> and <strong>Hibernate 4</strong>, then use version <strong>1.3.1</strong> of this plugin.<br />\nIf your app is using <strong>Grails 2</strong> and <strong>Hibernate 3</strong>, then use version <strong>1.2.1</strong> of this plugin.</p>\n<h3>Configuration</h3>\n<p>You'll then need to configure the encryption in your Grails configuration using a stanza like this (make sure to change the password):</p>\n<pre><code>jasypt {\n algorithm = "PBEWITHSHA256AND256BITAES-CBC-BC"\n providerName = "BC"\n password = "<your very secret passphrase>"\n keyObtentionIterations = 1000\n}\n</code></pre>\n<p>This will configure your encryption to use a 256 bit AES algorithm to do the encryption. Key generation will also be repeated 1000 times (to slow down any brute force attacks). Changing any of these values will result in different results (and will also prevent the ability to decrypt previously encrypted information).</p>\n<h3>External Config Files in Grails</h3>\n<p>You can put the encryption configuration in Config.groovy, but a better location would be an external configuration file that does not get checked into source code (and can vary based on environment). Just put something like this in your Config.groovy file to define an external config file:</p>\n<pre><code>def configFIlePath = System.getenv('ENCRYPTION_CONFIG_LOCATION') ?: "file:${userHome}/.jasypt"\ngrails.config.locations = [configFilePath]\n</code></pre>\n<p>This enables you to set an environment variable with the location of the encryption configuration, otherwise it will look for a .encryption file in the current user's home (useful for developers).</p>\n<h3>Enabling "Unlimited" Encryption in Java</h3>\n<p>Because of American export standards, and the notion that <a href=\"http://en.wikipedia.org/wiki/Export_of_cryptography_in_the_United_States\">cryptographically strong algorithms are "munitions"</a>, you'll want to make sure that the encryption policy jars that came with your installation of Java allow "unlimited" encryption, rather than the default "strong" (which are actually pretty weak).</p>\n<p>To check to see what level of encryption your installation of Java has, you'll need to do one of two things:\nA: Run the code from this <a href=\"https://gist.github.com/jehrhardt/5167854\">gist on github</a></p>\n<p>or</p>\n<p>B: crack open your <code>$JAVA_HOME/jre/lib/security/local_policy.jar</code> to see what's inside.:</p>\n<pre><code>% cd /tmp\n% cp $JAVA_HOME/jre/lib/security/local_policy.jar .\n% jar xvf local_policy.jar\n inflated: META-INF/MANIFEST.MF\n inflated: META-INF/JCE_RSA.SF\n inflated: META-INF/JCE_RSA.RSA\n created: META-INF/\n inflated: default_local.policy\n\n% cat default_local.policy\n// Country-specific policy file for countries with no limits on crypto strength.\ngrant {\n // There is no restriction to any algorithms.\n permission javax.crypto.CryptoAllPermission;\n};\n</code></pre>\n<p>If the permissions look like that, you're set. Mac laptops bought in the US have this configured by default, all other installations I've seen have needed to be upgraded (including all Linux distros).</p>\n<p>Installing the new jar files is easy, just go download the "Java Cryptography Extension (JCE)" <a href=\"http://www.oracle.com/technetwork/java/javase/downloads/index.html\">under "Other Downloads" on Oracle's website</a>.</p>\n<p>Unzip the zip file and copy the jar files into your <code>$JAVA_HOME/jre/lib/security directory</code> to overwrite the existing, limited encryption jars.</p>\n<pre><code class=\"language-sh\">#make a backup copy of your existing files\nmkdir old_java_security\ncp -r $JAVA_HOME/jre/lib/security old_java_security\n\nunzip jce_policy-6.zip\nsudo cp jce/*.jar $JAVA_HOME/jre/lib/security\n</code></pre>\n<h3>Defining Fields in your Domain to Encrypt</h3>\n<p>Defining fields in your domain object that you want to be encrypted within the database is easy once the plugin is installed and configured, just define the "type" within the domain class' mapping:</p>\n<pre><code>package com.bloomhealthco.domain\n\nimport com.bloomhealthco.jasypt.GormEncryptedStringType\n\nclass Member {\n String firstName\n String lastName\n String ssn\n static mapping = {\n \tssn type: GormEncryptedStringType\n }\n}\n</code></pre>\n<p>One other caveat, if you're setting the length of the field within the database schema, you'll need to give yourself extra room as the encrypted value will be longer than the unencrypted value was. This length will depend on the encryption algorithm that you use. It's easy to write an integration test that can spit out all of the encrypted lengths for you. See <code>testEncryptionWithLongNamesFit()</code> in the https://github.com/ZenHarbinger/grails-jasypt/blob/master/src/test/projects/sample/src/integration-test/groovy/com/bloomhealthco/domain/JasyptDomainEncryptionTests.groovy for an example.</p>\n<h3>Custom Encryption Types</h3>\n<p>As of version 1.1 the plugin provides 'Gorm' versions of all the built in Encrypted types provide by the jasypt plugin, http://www.jasypt.org/hibernate.html.</p>\n<p>It is also possible to define your own GORM encrypted types. This happens in two steps. First, you need a UserType that handles the encryption. This might be a class you have already from a existing java application or you could extend the jasypt class <a href=\"https://jasypt.svn.sourceforge.net/svnroot/jasypt/trunk/jasypt-hibernate3/src/main/java/org/jasypt/hibernate3/type/AbstractEncryptedAsStringType.java\">AbstractEncryptedAsStringType</a>. Second, you define a new Gorm Encrypted type that composes that UserType to provide the wiring to the Grails configuration.</p>\n<p>Here's an example that can encrypt joda-time dates (requires the joda-time jar to work):</p>\n<pre><code>package com.bloomhealthco.jasypt\n\nimport org.jasypt.hibernate.type.AbstractEncryptedAsStringType\nimport org.joda.time.LocalDate;\n\npublic class EncryptedLocalDateAsStringType extends AbstractEncryptedAsStringType {\n\n protected Object convertToObject(String string) {\n if (!string) return null\n if (!(string =~ /\\d{4}-\\d{2}-\\d{2}/)) throw new IllegalArgumentException("String does not match YYYY-MM-dd pattern")\n new LocalDate(string)\n }\n\n protected String convertToString(Object object) {\n if (!object) return null\n if (object.class != LocalDate) throw new IllegalArgumentException("Expected ${LocalDate.name} but was ${object.class.name}")\n object.toString("YYYY-MM-dd")\n }\n\n public Class returnedClass() { LocalDate }\n}\n\npublic class GormEncryptedLocalDateAsStringType extends JasyptConfiguredUserType<EncryptedLocalDateAsStringType> {\n}\n\n</code></pre>\n<h3>Further Documentation</h3>\n<p>For now, documentation is a little light. There's a <a href=\"https://github.com/ZenHarbinger/grails-jasypt/tree/master/src/test/projects/sample\">test project</a> checked in as part of the repository that shows the plugin being used (and has tests that exercise the functionality). The <a href=\"https://github.com/ZenHarbinger/grails-jasypt/blob/master/src/test/projects/sample/grails-app/domain/com/bloomhealthco/domain/Patient.groovy\">Patient domain object</a> has encrypted firstName and lastName fields on it.</p>\n<h3>Release Notes</h3>\n<ul>\n<li>4.0.3 - initial support for Grails 4</li>\n<li>2.0.1 - initial support for Grails 3</li>\n<li>1.3.1 - initial support for Hibernate 4</li>\n<li>1.2.1 - code cleanup contribution from Burt Beckwith</li>\n<li>1.2.0 - support grails 2.3.8 and up</li>\n<li>1.1.0 - Support all the encrypted UserTypes provided by jasypt's hibernate support while reusing the existing implementations; thanks to Jon Palmer for pull request & work on this</li>\n<li>1.0.0 - upgraded to jasypt 1.9 - support for grails 2.0.0 thanks to pull request from Jon Palmer</li>\n<li>0.1.2 - upgraded to jasypt 1.7 - support for hibernate 3.6 and grails 1.3.6. Could also work with earlier versions of grails but it has only been tested on 1.3.6 currently</li>\n</ul>\n" |
| }, |
| { |
| "deprecated": "Source repository for this entry is archived. This entry should probably be removed from the registry.", |
| "bintrayPackage": { |
| "name": "org.grails.plugins:json-annotations-marshaller", |
| "repo": "plugins", |
| "owner": "anthofo", |
| "desc": "Grails json-annotations-marshaller plugin", |
| "labels": [ |
| "json" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/anthofo/grails3-json-annotations-marshaller/issues", |
| "latestVersion": "1.0", |
| "updated": "2015-07-03T11:50:00.000Z", |
| "systemIds": [ |
| "org.grails.plugins:json-annotations-marshaller" |
| ], |
| "vcsUrl": "https://github.com/anthofo/grails3-json-annotations-marshaller" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>json-apis</h1>\n<h2>Grails plugin for managing multiple JSON apis using domain class annotations</h2>\n<p>The goal of this plugin is to help convert Grails domain classes into various\nJSON representations needed in different parts of your web application or to\nsupport various API versions.</p>\n<p>Features:</p>\n<ul>\n<li>Allows you to declare multiple named JSON configurations for different use cases</li>\n<li>Configuration is very straightforward: all that is required is to mark domain class\nproperties with a single annotation naming the configurations under which that\nproperty should be included in the serialized JSON object</li>\n<li>Works for collections as well as <code>belongsTo</code> properties</li>\n<li>Enables developers to avoid the circular object reference problem elegantly by\ndefining appopriate namespaces - this way it is possible to start the serialization\neither in a parent or child entity, depending on the use case</li>\n<li>Works for objects serialized inside a <a href=\"http://grails.org/doc/latest/guide/theWebLayer.html#moreOnJSONBuilder\">JSON builder</a></li>\n<li>Uses the Grails' <code>ObjectMarshaller</code> mechanism under the hood</li>\n<li>Detects API changes during development time live reloads</li>\n</ul>\n<h2>Example of use</h2>\n<p>Several API variants can be easily defined in domain classes by annotating properties with\n<code>JsonApi</code> and providing a list of API profile names under which that property should appear in the\nresulting JSON. Marking a property with the <code>JsonApi</code> annotation but providing no API names will\ninclude that property in all APIs. The database identity property will always be included\nautomatically. One could for instance define the following domain class:</p>\n<pre><code class=\"language-groovy\">import grails.plugins.jsonapis.JsonApi\n\nclass User {\n\t@JsonApi\n\tString screenName\n\n\t@JsonApi('userSettings')\n\tString email\n\n\t@JsonApi(['userSettings', 'detailedInformation'])\n\tString twitterUsername\n}\n</code></pre>\n<p>Then in the controller one would call the desired named JsonApi configuration to get only\nthe fields defined for that API. The following code:</p>\n<pre><code class=\"language-groovy\">JSON.use("detailedInformation")\nrender person as JSON\n</code></pre>\n<p>...would convert the <code>person</code> object into JSON containing the <code>id</code>, <code>screenName</code> and <code>twitterUsername</code>\nproperties but not the <code>email</code>. It works for collections as well, converting each collection\nmember using the same API profile that was used to convert the parent:</p>\n<pre><code class=\"language-groovy\">static hasMany = [\n\tpets: Pet\n]\n@JsonApi('detailedInformation')\nSet pets\n</code></pre>\n<p>To include a domain object's parent in a JSON API, declare a <code>belongsTo</code> property explicitly\nand annotate it with <code>JsonApi</code> (but be careful not to create circular paths by including both\nends of a <code>belongsTo</code>/<code>hasMany</code> pair):</p>\n<pre><code class=\"language-groovy\">static belongsTo = [\n\tuser:User\n]\n\n@JsonApi('petDetails') \nUser user\n</code></pre>\n<p>JSONBuilder is supported, too:</p>\n<pre><code class=\"language-groovy\">JSON.use("userSettings")\nrender(contentType: "text/json") {\n user = User.first()\n pet = Pet.first()\n}\n</code></pre>\n<h2>Future plans</h2>\n<ul>\n<li>Detect circular APIs and display a warning on startup, perhaps disable them entirely</li>\n<li>Add a script/controller that would document the registered APIs in one or more formats</li>\n<li>Read the domain class annotations and produce configurations for those 3rd party JSON\nrenderers which currently seem to perform better than the native Grails implementation</li>\n</ul>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "log-hibernate-stats", |
| "repo": "plugins", |
| "owner": "ishults", |
| "desc": "A simple plugin to log Hibernate statistics across controller actions.", |
| "labels": [ |
| "logging" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/ishults/log-hibernate-stats/issues", |
| "latestVersion": "1.0.20", |
| "updated": "2016-03-31T13:31:55.695Z", |
| "systemIds": [ |
| "org.grails.plugins:log-hibernate-stats" |
| ], |
| "vcsUrl": "https://github.com/ishults/log-hibernate-stats" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>logHibernateStats</h1>\n<h3>Summary</h3>\n<p>A simple Grails 3 plugin to log Hibernate statistics on controller actions.</p>\n<p>For the Grails 2 plugin code and documentation, see: https://github.com/ishults/log-hibernate-stats/tree/grails_2.x</p>\n<h3>Configuration and Usage</h3>\n<p>To add this plugin, in your <code>build.gradle</code> add:</p>\n<pre><code>repositories {\n ...\n maven { url "http://dl.bintray.com/ishults/plugins" }\n}\ndependencies {\n ...\n compile "org.grails.plugins:log-hibernate-stats:1.0.20"\n}\n</code></pre>\n<p>Then just update your config (such as <code>application.yml</code>) to add</p>\n<pre><code>logHibernateStats:\n enabled: 'ALWAYS'// From ALWAYS, ALLOWED, NEVER\n</code></pre>\n<p>for the environments you want to track statistics for.</p>\n<p>Then in your <code>logback.groovy</code> set:</p>\n<pre><code>logger 'grails.app.controllers.org.grails.plugins.LogHibernateStatsInterceptor',\n DEBUG, ['STDOUT'], false // Or INFO\n</code></pre>\n<p>You should now be seeing output like:</p>\n<pre><code>INFO controller.ControllerFilters -\n############## Hibernate Stats ##############\nAction: /controller/actionName\n\nTransaction Count: 2\nFlush Count: 1\nPrepared Statement Count: 2\n\nTotal time: 500 ms\n#############################################\n</code></pre>\n<p>after each request. If you set the logging to 'debug', you will also see:</p>\n<pre><code>DEBUG controller.ControllerFilters -\n### Start logging for action: controller/actionName ###\n</code></pre>\n<p>at the start of each action (useful if logSql is enabled too).</p>\n<p>If instead you'd like to target only specific actions, you can set</p>\n<pre><code>logHibernateStats.enabled = 'ALLOWED'\n</code></pre>\n<p>and instead append the parameter '_logHibernateStats=true' to your request. This will isolate the logging to just that request.</p>\n<p>It is recommended to keep the plugin enabled value at 'NEVER' by default, and setting it to 'ALLOWED' or 'ALWAYS' when debugging in development.</p>\n<h3>Caveats</h3>\n<ul>\n<li>This plugin heavily assumes that no other place in the code is clearing/using Hibernate statistics.</li>\n<li>If there are background services interacting with Hibernate, or if multiple requests are sent in succession, the statistics may not be accurate.</li>\n</ul>\n<h3>Credits</h3>\n<p>Plugin created by Igor Shults.</p>\n<p>Official Grails 3.x plugin page here: https://bintray.com/ishults/plugins/org.grails.plugins%3Alog-hibernate-stats/view</p>\n<p>Official Grails 2.x plugin page here: http://grails.org/plugin/log-hibernate-stats</p>\n<p>If you're not interested in running this as a plugin, I wrote a blog post on some standalone code here: http://www.objectpartners.com/2014/04/22/tracking-hibernate-statistics-across-grails-actions/</p>\n<p>Inspired by a post on Hibernate logging by Himanshu Seth: http://www.intelligrape.com/blog/2011/11/07/grails-find-number-of-queries-executed-for-a-particular-request/</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "quartz-monitor", |
| "repo": "plugins", |
| "owner": "jamescookie", |
| "desc": "Grails quartz-monitor plugin", |
| "labels": [ |
| "quartz", |
| "scheduling" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/jamescookie/quartz-monitor/issues", |
| "latestVersion": "1.3", |
| "updated": "2016-04-19T21:51:32.924Z", |
| "systemIds": [ |
| "org.grails.plugins:quartz-monitor" |
| ], |
| "vcsUrl": "https://github.com/jamescookie/quartz-monitor" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<p>#Quartz Monitor Plugin for Grails</p>\n<p>Allows you to view and administer all your Quartz jobs in one place.</p>\n<p>##Prerequisites</p>\n<p>This plugin requires the <a href=\"http://grails.org/plugin/quartz\">Quartz</a> and <a href=\"http://grails.org/plugin/asset-pipeline\">Asset Pipeline</a> plugins to run.</p>\n<p>##Usage</p>\n<p>Once you have the Quartz plugin installed and have created some jobs, then you will probably start wondering if they are all running as desired.</p>\n<p>This is where you need the 'Quartz Monitor' plugin.</p>\n<p>Simply install the plugin and go to the URL: http://localhost:8080/<yourapp>/quartz and you will find all a list of all the jobs you have scheduled to run.</p>\n<p>##Enhanced Experience</p>\n<p>To have the page keep you constantly up to date requires <a href=\"http://grails.org/plugin/jquery\">jQuery</a>. It will still work without jQuery, but it won't look as good.</p>\n<p>##Configuration</p>\n<p>There are various configuration options, all start with <code>quartz.monitor</code>:</p>\n<p>###layout</p>\n<p>Allows you to change the sitemesh layout that page will use. Defaults to 'main'.</p>\n<p>###showTriggerNames</p>\n<p>If this is set to true, then the names of the triggers will be shown in the list - useful if you have multiple triggers for the same job.</p>\n<p>###showCountdown</p>\n<p>Will add javascript to the page in order to show a countdown to when the job will fire next, unless this is set to 'false'.</p>\n<p>###showTickingClock</p>\n<p>Will add javascript to the page in order to show a clock with the current time, unless this is set to 'false'.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "p6spy-ui", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Grails p6spy-ui plugin", |
| "labels": [ |
| "logging", |
| "p6spy" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/burtbeckwith/grails-p6spy-ui/issues", |
| "latestVersion": "3.0.0", |
| "updated": "2016-04-01T15:40:04.213Z", |
| "systemIds": [ |
| "org.grails.plugins:p6spy-ui" |
| ], |
| "vcsUrl": "https://github.com/burtbeckwith/grails-p6spy-ui" |
| }, |
| "documentationUrl": "https://burtbeckwith.github.io/grails-p6spy-ui/", |
| "mavenMetadataUrl": null, |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "paypal-payments", |
| "repo": "plugins", |
| "owner": "novadge", |
| "desc": "Accept and process payments with Paypal SDK", |
| "labels": [ |
| "payment", |
| "paypal" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/Novadge/paypal-payments/issues", |
| "latestVersion": "0.1.0", |
| "updated": "2016-03-31T13:31:54.940Z", |
| "systemIds": [ |
| "org.grails.plugins:paypal-payments" |
| ], |
| "vcsUrl": "https://github.com/Novadge/paypal-payments" |
| }, |
| "documentationUrl": "https://Novadge.github.io/paypal-payments/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>paypal payments</h1>\n<p>Accept and process payments with Paypal REST API</p>\n<h3>Introduction</h3>\n<p>The Paypal payments plugin simplifies the integration of Paypal into Grails applications. With this plugin, you are not required to be a Paypal sdk guru in order to accept payments.</p>\n<p>This guide documents how to use the plugin to process payments for Grails applications.</p>\n<h3>Getting Started</h3>\n<p>I will assume that you already have your Grails application designed and ready to accept payments. A demo application will be sufficient for this exercise.</p>\n<p>####Create a Paypal account\nYou will need to create a Paypal account and obtain API keys for a Paypal app. The Paypal app will represent your Grails application. To create a Paypal app, please visit [https://developer.paypal.com/developer/applications/](Paypal developer page) to create a sandbox account.</p>\n<p>The Sandbox account will allow you to play around with most of the API features available. It is also a good way to test your application integration before moving over to a live environment.</p>\n<p>####Obtain your client id and client secret\nObtain the API keys for your sandbox account/app and add it to your Grails config file [Config.groovy for grails 2.x and application.groovy for grails 3.x]. Here's what my config file looks like:</p>\n<pre><code>paypal.email="omasiri@novadge.com"\npaypal.clientId = 'your client id'\npaypal.sandbox.clientId = 'your client id'\npaypal.clientSecret = 'your client secret'\npaypal.sandbox.clientSecret ='your client secret'\npaypal.endpoint = "https://api.paypal.com"\npaypal.sandbox.endpoint = "https://api.sandbox.paypal.com"\n</code></pre>\n<p>Notice that I added config for sandbox and live environment. The reason is to be able to switch between both environments during app development.</p>\n<p>####Create a grails controller and add required actions\nCreate a grails controller. Personally, I called my own controller PaypalController.</p>\n<pre><code>grails create-controller com.mypackage.Paypal\n</code></pre>\n<p>####Add required actions</p>\n<p>Normally, Paypal payments requires three steps to complete.</p>\n<ol>\n<li>Make approval request to paypal.</li>\n<li>Approval - Customer approves the payment</li>\n<li>Execution - Process response from Paypal in order to capture the payment.</li>\n</ol>\n<h3>Approval Step</h3>\n<p>For the approval step, here's my action inside my PaypalController.\nInject paypalService into your controller like this...</p>\n<pre><code>def paypalService\n</code></pre>\n<p>And then create your Controller action</p>\n<pre><code>import com.paypal.base.Constants\n...\n\ndef approve() {\n\n String clientId = grailsApplication.config.paypal.clientId\n String clientSecret = grailsApplication.config.paypal.clientSecret\n String endpoint = grailsApplication.config.paypal.endpoint\n Map sdkConfig = [(Constants.CLIENT_ID): clientId,\n (Constants.CLIENT_SECRET): clientSecret,\n (Constants.ENDPOINT): endpoint]\n def accessToken = paypalService.getAccessToken(clientId, clientSecret, sdkConfig)\n def apiContext = paypalService.getAPIContext(accessToken, sdkConfig)\n\n\n BigDecimal total = formatNumber(number: params.amount, minFractionDigits: 2) as BigDecimal\n\n def details = paypalService.createDetails(subtotal: "12.50")\n def amount = paypalService.createAmount(currency: currencyCode, total: "12.50", details: details)\n\n def transaction = paypalService.createTransaction(amount: amount, description: "your description", details: details)\n def transactions = [transaction]\n\n def payer = paypalService.createPayer(paymentMethod: 'paypal')\n def cancelUrl = "http://myexampleurl/cancel"\n def returnUrl = "http://mypaypalController/execute"\n\n def redirectUrls = paypalService.createRedirectUrls(cancelUrl: cancelUrl, returnUrl: returnUrl)\n\n def payment\n try {\n // create the paypal payment\n payment = paypalService.createPayment(\n payer: payer, intent: 'sale',\n transactionList: transactions,\n redirectUrls: redirectUrls,\n apiContext: apiContext)\n }\n catch (e) {\n flash.message = "Could not complete the transaction because: ${e.message ?: ''}"\n redirect controller: 'bill', action: "show", id: params.refId\n return\n }\n\n def approvalUrl = ""\n def retUrl = ""\n // retrieve links from returned paypal object\n for (Links links in payment?.links) {\n if (links?.rel == 'approval_url') {\n approvalUrl = links.href\n }\n if (links?.rel == 'return_url') {\n retUrl = links.href\n }\n }\n\n redirect url: approvalUrl ?: '/', method: 'POST'\n}\n</code></pre>\n<h3>Approval</h3>\n<p>The customer will be redirected to the Paypal website for approval. After the customer approves or\ncancels the payment, Paypal will either call the returnUrl or cancelUrl you provided depending on\nwhat action the customer performs.</p>\n<pre><code>def execute() {\n\n String clientId = grailsApplication.config.paypal.clientId\n String clientSecret = grailsApplication.config.paypal.clientSecret\n String endpoint = grailsApplication.config.paypal.endpoint\n Map sdkConfig = [:] //= grailsApplication.config.paypal.sdkConfig//[mode: 'live']\n //sdkConfig['grant-type'] = "client_credentials"\n sdkConfig[Constants.CLIENT_ID] = clientId\n sdkConfig[Constants.CLIENT_SECRET] = clientSecret\n sdkConfig[Constants.ENDPOINT] = endpoint\n def accessToken = paypalService.getAccessToken(clientId, clientSecret, sdkConfig)\n def apiContext = paypalService.getAPIContext(accessToken, sdkConfig)\n //the paypal website will add params to the call to your app. Eg. PayerId, PaymentId\n // you will use the params to 'execute' the payment\n def paypalPayment = paypalService.createPaymentExecution(paymentId: params.paymentId, payerId: params.PayerID, apiContext)\n\n def map = new JsonSlurper().parseText(paypalPayment.toString())\n\n redirect url: "to your url"\n}\n</code></pre>\n<h3>Authors and Contributors</h3>\n<p>Omasirichukwu Joseph Udeinya (@omasiri)</p>\n<h3>Support or Contact</h3>\n<p>Please feel free to reach out to us for assistance with this plugin and we\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdll help you sort it out.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "paystack-grails", |
| "repo": "plugins", |
| "owner": "dubems", |
| "desc": "Plugin to communicate with paystack API", |
| "labels": [ |
| "payment" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/dubems/paystack-grails/issues", |
| "latestVersion": "1.0.5", |
| "updated": "2020-07-30T18:43:08.745Z", |
| "systemIds": [ |
| "org.grails.plugins:paystack-grails" |
| ], |
| "vcsUrl": "https://github.com/dubems/paystack-grails" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "postgresql-extensions", |
| "repo": "plugins", |
| "owner": "kaleidos", |
| "desc": "This plugin provides hibernate user types to support for Postgresql Native Types like Array, HStore, JSON as well as new criterias to query this native types.", |
| "labels": [ |
| "postgresql", |
| "gorm" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/kaleidos/grails-postgresql-extensions/issues", |
| "latestVersion": "7.0.0", |
| "updated": "2019-07-29T19:41:48.286Z", |
| "systemIds": [ |
| "org.grails.plugins:postgresql-extensions" |
| ], |
| "vcsUrl": "https://github.com/kaleidos/grails-postgresql-extensions" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails Postgresql Extensions</h1>\n<h4>THIS BRANCH (master) IS FOR GRAILS 4 AND HIBERNATE 5.4</h4>\n<p><a href=\"https://bintray.com/kaleidos/plugins/postgresql-extensions/4.8.0/link\"><img src=\"https://api.bintray.com/packages/kaleidos/plugins/postgresql-extensions/images/download.svg?version=4.8.0\" alt=\"Download\" /></a>\n<a href=\"https://bintray.com/kaleidos/plugins/postgresql-extensions/5.3.0/link\"><img src=\"https://api.bintray.com/packages/kaleidos/plugins/postgresql-extensions/images/download.svg?version=5.3.0\" alt=\"Download\" /></a>\n<a href=\"https://bintray.com/kaleidos/plugins/postgresql-extensions/6.1.0/link\"><img src=\"https://api.bintray.com/packages/kaleidos/plugins/postgresql-extensions/images/download.svg?version=6.1.0\" alt=\"Download\" /></a>\n<a href=\"https://bintray.com/kaleidos/plugins/postgresql-extensions/7.0.0/link\"><img src=\"https://api.bintray.com/packages/kaleidos/plugins/postgresql-extensions/images/download.svg?version=7.0.0\" alt=\"Download\" /></a>\n<a href=\"https://travis-ci.org/kaleidos/grails-postgresql-extensions\"><img src=\"https://travis-ci.org/kaleidos/grails-postgresql-extensions.svg?branch=master\" alt=\"Build Status\" /></a></p>\n<p>This is a grails plugin that provides hibernate user types to use Postgresql native types such as Array, Hstore, Json,\nJsonb... from a Grails application. It also provides new criterias to query this new native types.</p>\n<p>Currently the plugin supports array, hstore, json and jsonb fields as well as some query methods.\nMore native types and query methods will be added in the future.</p>\n<ul>\n<li><a href=\"#installation\">Installation</a>\n<ul>\n<li><a href=\"#postgresql-driver\">Postgresql driver</a></li>\n<li><a href=\"#hibernate-plugin\">Hibernate plugin</a></li>\n</ul>\n</li>\n<li><a href=\"#configuration\">Configuration</a></li>\n<li><a href=\"#native-types\">Native Types</a>\n<ul>\n<li><a href=\"#arrays\">Arrays</a>\n<ul>\n<li><a href=\"#example\">Example</a></li>\n<li><a href=\"#criterias\">Criterias</a>\n<ul>\n<li><a href=\"#contains\">Contains</a></li>\n<li><a href=\"#is-contained\">Is contained</a></li>\n<li><a href=\"#overlaps\">Overlaps</a></li>\n<li><a href=\"#is-empty\">Is Empty</a></li>\n<li><a href=\"#is-not-empty\">Is Not Empty</a></li>\n<li><a href=\"#is-empty-or-contains\">Is Empty or Contains</a></li>\n<li><a href=\"#equals\">Equals</a></li>\n<li><a href=\"#not-equals\">Not Equals</a></li>\n<li><a href=\"#ilike\">Ilike</a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li><a href=\"#hstore\">Hstore</a>\n<ul>\n<li><a href=\"#using-hstore\">Using Hstore</a></li>\n<li><a href=\"#hstore-criterias\">Criterias</a>\n<ul>\n<li><a href=\"#contains-key\">Contains Key</a></li>\n<li><a href=\"#contains\">Contains</a></li>\n<li><a href=\"#is-contained\">Is Contained</a></li>\n<li><a href=\"#ilike-value\">ILike Value</a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li><a href=\"#json\">JSON</a>\n<ul>\n<li><a href=\"#using-json\">Using json</a></li>\n<li><a href=\"#json-criterias\">Criterias</a>\n<ul>\n<li><a href=\"#has-field-value\">Has field value</a></li>\n<li><a href=\"#generic-criterion\">Generic criterion</a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li><a href=\"#jsonb\">JSONB</a>\n<ul>\n<li><a href=\"#jsonb-criterias\">Criterias</a>\n<ul>\n<li><a href=\"#contains\">Contains</a></li>\n<li><a href=\"#is-contained\">Is contained</a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li><a href=\"#order\">Order</a>\n<ul>\n<li><a href=\"#random-order\">Random order</a></li>\n<li><a href=\"#sql-formula\">Sql formula</a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li><a href=\"#authors\">Authors</a></li>\n<li><a href=\"#release-notes\">Release Notes</a></li>\n</ul>\n<h2>Installation</h2>\n<p>The Grails 3 version supports both Hibernate 4.X (versions 4.x.x of the plugin) and Hibernate 5.X (versions 5.x.x of the\nplugin). In <code>build.gradle</code> add the <code>jcenter</code> repository and the following dependency to install the plugin:</p>\n<pre><code class=\"language-groovy\">repositories {\n ...\n jcenter()\n ...\n}\n\ndependencies {\n ...\n compile 'org.grails.plugins:postgresql-extensions:<version>'\n ...\n}\n</code></pre>\n<h3>Postgresql driver</h3>\n<p>You also need to install the Postgresql jdbc driver. You can see all available Postgresql jdbc libraries versions at\n<a href=\"http://mvnrepository.com/artifact/org.postgresql/postgresql\">MVN Repository</a>.</p>\n<pre><code class=\"language-groovy\">dependencies {\n ...\n provided 'org.postgresql:postgresql:9.4.1211.jre7'\n ...\n}\n</code></pre>\n<h3>Hibernate plugin</h3>\n<p>It's also necessary to install the Grails-Hibernate plugin. Depending if you use Hibernate 4 or Hibernate 5 you'll need\ndifferent dependencies. Please make sure you use the latest versions of the plugin and the hibernate dependencies</p>\n<pre><code class=\"language-groovy\">// Hibernate 4\nbuildscript {\n ...\n dependencies {\n ...\n classpath "org.grails.plugins:hibernate4:6.0.3"\n }\n}\n\ndependencies {\n ...\n compile "org.grails.plugins:hibernate4"\n compile "org.hibernate:hibernate-core:4.3.11.Final"\n compile "org.hibernate:hibernate-ehcache:4.3.11.Final"\n ...\n}\n</code></pre>\n<pre><code class=\"language-groovy\">// Hibernate 5\nbuildscript {\n ...\n dependencies {\n ...\n classpath "org.grails.plugins:hibernate5:6.0.3"\n }\n}\n\ndependencies {\n ...\n compile "org.grails.plugins:hibernate5"\n compile "org.hibernate:hibernate-core:5.1.1.Final"\n compile "org.hibernate:hibernate-ehcache:5.1.1.Final"\n ...\n}\n</code></pre>\n<h2>Configuration</h2>\n<p>After install the plugin you have to use a new Postgresql Hibernate Dialect in your application. Add it to the\n<code>grails-app/conf/application.yml</code> file:</p>\n<pre><code class=\"language-yaml\">---\ndataSource:\n pooled: true\n jmxExport: true\n driverClassName: org.postgresql.Driver\n username: user\n password: password\n url: jdbc:postgresql://localhost:5432/db_name\n dbCreate: update\n\nhibernate:\n dialect: net.kaleidos.hibernate.PostgresqlExtensionsDialect\n</code></pre>\n<p>If you just only add the dialect, hibernate will create a new sequence for every table to generate the sequential ids\nused for the primary keys instead of a global sequence for all your tables.</p>\n<p>If you're using Hibernate 4 you can also deactivate this behaviour and create only one unique sequence for all the tables with the following\nproperty in your datasource definition:</p>\n<pre><code class=\"language-yaml\">dataSource:\n postgresql:\n extensions:\n sequence_per_table: false\n}\n</code></pre>\n<p>For Hibernate 5 add the following to <code>grails-app/conf/application.groovy</code>:</p>\n<pre><code class=\"language-groovy\">grails.gorm.default.mapping = {\n id generator: 'org.hibernate.id.enhanced.SequenceStyleGenerator', params: [prefer_sequence_per_entity: true]\n}\n</code></pre>\n<p>Please be aware that Hibernate 5 has changed the default name of the sequences so for a domain class <code>TestMapJson</code> the\ntable name is <code>test_map_json</code> and the sequence name is <code>seq_test_map_json</code> in Hibernate 4 and <code>testmapjson_seq</code> in\nHibernate 5.</p>\n<h2>Native Types</h2>\n<h3>Arrays</h3>\n<p>The plugin supports the definition of <code>Integer</code>, <code>Long</code>, <code>Float</code>, <code>Double</code>, <code>String</code>, and <code>Enum</code> arrays in your domain\nclasses.</p>\n<p>The <code>Enum</code> arrays behaves almost identical to <code>Integer</code> arrays in that they store and retrieve an array of ints. The\ndifference, however, is that this is used with an Array of Enums, rather than Ints. The Enums are serialized to their\nordinal value before persisted to the database. On retrieval, they are then converted back into their original <code>Enum</code>\ntype.</p>\n<h4>Example</h4>\n<pre><code class=\"language-groovy\">import net.kaleidos.hibernate.usertype.ArrayType\n\nclass Like {\n Integer[] favoriteNumbers = []\n Long[] favoriteLongNumbers = []\n Float[] favoriteFloatNumbers = []\n Double[] favoriteDoubleNumbers = []\n String[] favoriteMovies = []\n Juice[] favoriteJuices = []\n UUID[] favoriteMovieUUIDs = []\n\n static enum Juice {\n ORANGE(0),\n APPLE(1),\n GRAPE(2)\n\n private final int value\n Juice(int value) { this.value = value }\n }\n\n static mapping = {\n favoriteNumbers type:ArrayType, params: [type: Integer]\n favoriteLongNumbers type:ArrayType, params: [type: Long]\n favoriteFloatNumbers type:ArrayType, params: [type: Float]\n favoriteDoubleNumbers type:ArrayType, params: [type: Double]\n favoriteMovies type:ArrayType, params: [type: String]\n favoriteJuices type:ArrayType, params: [type: Juice]\n favoriteMovieUUIDs type:ArrayType, params: [type: UUID]\n }\n}\n</code></pre>\n<p>Now you can create domain objects using lists (or arrays) of integers, longs and strings and when you save the object\nit will be stored as an postgresql array:</p>\n<pre><code class=\"language-groovy\">def myLikes = new Like(favoriteNumbers: [5, 17, 9, 6],\n favoriteLongNumbers: [123, 239, 3498239, 2344235],\n favoriteFloatNumbers: [0.3f, 0.1f],\n favoriteDoubleNumbers: [100.33d, 44.11d],\n favoriteMovies: ["Spiderman", "Blade Runner", "Starwars"],\n favoriteJuices: [Like.Juice.ORANGE, Like.Juice.GRAPE])\nmyLikes.save()\n</code></pre>\n<p>And now, with <code>psql</code>:</p>\n<pre><code>=# select * from like;\n\n id | favorite_long_numbers | favorite_float_numbers | favorite_double_numbers | favorite_movies | favorite_numbers | favorite_juices\n----+---------------------------+---------------------------+---------------------------+----------------------------------------+------------------+----------------\n 1 | {123,239,3498239,2344235} | {0.3,0.1} | {100.33,44.11} | {Spiderman,"Blade Runner",Starwars} | {5,17,9,6} | {0,2}\n</code></pre>\n<h4>Criterias</h4>\n<p>The plugin also includes some hibernate criterias to use in your queries. Please check the\n<a href=\"https://github.com/kaleidos/grails-postgresql-extensions/tree/master/grails-app/services/test/criteria/array\">services</a>\nand the <a href=\"https://github.com/kaleidos/grails-postgresql-extensions/tree/master/src/integration-test/groovy/net/kaleidos/hibernate/array\">tests</a>\ncreated to see all usage examples.</p>\n<p>You can also check the official <a href=\"http://www.postgresql.org/docs/9.4/static/functions-array.html#ARRAY-OPERATORS-TABLE\">Postgresql Array operators</a>.</p>\n<h5>Contains</h5>\n<p>With this criteria you can get all the rows that contain all the values in the array field. To use it just use the new\ncriteria <code>pgArrayContains</code>:</p>\n<pre><code class=\"language-groovy\">// number can be just a value...\ndef number = 3\ndef result = Like.withCriteria {\n pgArrayContains 'favoriteNumbers', number\n}\n\n// ...or a list\ndef numbers = [5, 17]\ndef result = Like.withCriteria {\n pgArrayContains 'favoriteNumbers', numbers\n}\n\n// If using enums, pass the enum right through\ndef juices = Like.Juice.ORANGE\ndef result = Like.withCriteria {\n pgArrayContains 'favoriteJuices', juices\n}\n\n</code></pre>\n<h4>Is contained</h4>\n<p>With this criteria you can get all the rows that are contained by the values. To use it just use the new criteria\n<code>pgArrayIsContainedBy</code>:</p>\n<pre><code class=\"language-groovy\">// movie can be just a string or a list\ndef movie = "Starwars" // or movie = ["Starwars"]\ndef result = Like.withCriteria {\n pgArrayIsContainedBy 'favoriteMovies', movie\n}\n\n// The plugin also support joins\ndef movies = ["Starwars", "Matrix"]\ndef results = User.withCriteria {\n like {\n pgArrayIsContainedBy 'favoriteMovies', movies\n }\n}\n</code></pre>\n<h4>Overlaps</h4>\n<p>With this criteria you can get all the rows that contains any of the values. To use it just use the new criteria\n<code>pgArrayOverlaps</code>:</p>\n<pre><code class=\"language-groovy\">def result = Like.withCriteria {\n pgArrayOverlaps 'favoriteNumbers', numbers\n}\n</code></pre>\n<h4>Is Empty</h4>\n<p>With this criteria you can get all the rows that contains an-empty array in the selected field. To use it just use the\nnew criteria <code>pgArrayIsEmpty</code>:</p>\n<pre><code class=\"language-groovy\">def result = Like.withCriteria {\n pgArrayIsEmpty 'favoriteMovies'\n}\n</code></pre>\n<h4>Is Not Empty</h4>\n<p>With this criteria you can get all the rows that contains a not empty array in the selected field. To use it just use\nthe new criteria <code>pgArrayIsNotEmpty</code>:</p>\n<pre><code class=\"language-groovy\">def result = Like.withCriteria {\n pgArrayIsNotEmpty 'favoriteMovies'\n}\n</code></pre>\n<h4>Is Empty or Contains</h4>\n<p>This criteria is a mix of the <code>pgContains</code> and <code>pgIsEmpty</code>. Sometimes you have to execute 'pgContains' criteria if the\nlist has elements or a 'pgIsEmpty' if the list is empty. It could be something like this:</p>\n<pre><code class=\"language-groovy\">def numbers = ... // A list with zero or more elements\ndef result = Like.withCriteria {\n if (numbers) {\n pgArrayContains 'favoriteNumbers', numbers\n } else {\n pgArrayIsEmpty 'favoriteMovies'\n }\n}\n</code></pre>\n<p>With <code>pgIsEmptyOrContains</code> you can write the previous code as follows:</p>\n<pre><code class=\"language-groovy\">def numbers = ... // A list with zero or more elements\ndef result = Like.withCriteria {\n pgArrayIsEmptyOrContains 'favoriteNumbers', numbers\n}\n</code></pre>\n<h4>Equals</h4>\n<p>With this criteria you can get all the rows that are equal to a value. To use it just use the new criteria <code>pgArrayEquals</code>:</p>\n<pre><code class=\"language-groovy\">def result = Like.withCriteria {\n pgArrayEquals 'favoriteNumbers', numbers\n}\n</code></pre>\n<h4>Not Equals</h4>\n<p>With this criteria you can get all the rows that are not equal to a value. To use it just use the new criteria\n<code>pgArrayNotEquals</code>:</p>\n<pre><code class=\"language-groovy\">def result = Like.withCriteria {\n pgArrayNotEquals 'favoriteNumbers', numbers\n}\n</code></pre>\n<h4>ILike</h4>\n<p>With this criteria you can get all the rows that are ilike to a value. To use it just use the new criteria <code>pgArrayILike</code>.</p>\n<p>It only can be used on arrays of string.</p>\n<p>It uses the ilike syntaxis, so you can do for example:</p>\n<pre><code class=\"language-groovy\">def result = Like.withCriteria {\n pgArrayILike 'favoriteMovies', "%tarwar%"\n}\n</code></pre>\n<h3>Hstore</h3>\n<p>The first thing you need to do is install hstore support in Postgresql. In Debian/Ubuntu you have to install the\n<code>postgresql-contrib</code> package:</p>\n<pre><code>sudo apt-get install postgresql-contrib-9.4\n</code></pre>\n<p>Once the package is installed in the system you have to create the extension in the database you want to use hstore into:</p>\n<pre><code>CREATE EXTENSION hstore;\n</code></pre>\n<p>You can test that the hstore extension is correctly installed running:</p>\n<pre><code>=# SELECT 'foo=>bar, xxx=>yyy'::hstore;\n hstore\n----------------------------\n "foo"=>"bar", "xxx"=>"yyy"\n(1 row)\n</code></pre>\n<h4>Using Hstore</h4>\n<p>You only have to define the domain class with a <code>Map</code> attribute and use the Hibernate user type <code>HstoreMapType</code>.</p>\n<pre><code class=\"language-groovy\">import net.kaleidos.hibernate.usertype.HstoreMapType\n\nclass TestHstore {\n\n Map testAttributes\n String anotherProperty\n\n static mapping = {\n testAttributes type: HstoreMapType\n }\n}\n</code></pre>\n<p>Now you can create and instance of the domain class. Due to a limitation of the Hstore Postgresql type you can only\nstore Strings as key and value.</p>\n<pre><code class=\"language-groovy\">def instance = new TestHstore(testAttributes: [foo: "bar"], anotherProperty: "Groovy Rocks!")\ninstance.save()\n\ndef instance2 = new TestHstore(testAttributes: [xxx: 1, zzz: 123], anotherProperty: "")\ninstance2.save()\n</code></pre>\n<pre><code>=# select * from test_hstore;\n id | version | another_property | test_attributes\n----+---------+------------------+-----------------\n 1 | 0 | Groovy Rocks! | "foo"=>"bar"\n 2 | 0 | | "xxx"=>"1", "zzz"=>"123"\n</code></pre>\n<h4>Hstore Criterias</h4>\n<p>The following criteria operations are available to query rows using the Hstore custom type. You can\ncheck the <a href=\"https://github.com/kaleidos/grails-postgresql-extensions/tree/master/grails-app/services/test/criteria/hstore\">services</a>\nand the <a href=\"https://github.com/kaleidos/grails-postgresql-extensions/tree/master/src/integration-test/groovy/net/kaleidos/hibernate/hstore\">tests</a>\ncreated to see all usage examples.</p>\n<p>You can also check the official <a href=\"http://www.postgresql.org/docs/9.4/static/hstore.html\">Postgresql Hstore operators</a>.</p>\n<h5>Contains Key</h5>\n<p>With this operation you can search for rows that contain an Hstore with the key passed as parameter.</p>\n<pre><code class=\"language-groovy\">def wantedKey = "my-custom-key"\ndef result = MyDomain.withCriteria {\n pgHstoreContainsKey "attributes", wantedKey\n}\n</code></pre>\n<h5>Contains</h5>\n<p>You can search for data that contains certain pairs of <em>key</em> and <em>value</em>.</p>\n<pre><code class=\"language-groovy\">def result = Users.withCriteria {\n pgHstoreContains 'configuration', ["language": "es"]\n}\n</code></pre>\n<h5>Is Contained</h5>\n<p>The operation is contained can be used when looking for rows that has all the elements in the map\npassed as parameter.</p>\n<pre><code class=\"language-groovy\">def result = TestHstore.withCriteria {\n pgHstoreIsContained 'testAttributes', ["1": "a", "2": "b"]\n}\n</code></pre>\n<p>The example above returns the rows that contains elements like:</p>\n<pre><code>testAttributes = ["1": "a"]\ntestAttributes = ["2": "b"]\ntestAttributes = ["1": "a", "2": "b"]\n</code></pre>\n<p>This criteria can also be used to look for exact matches.</p>\n<h5>ILike Value</h5>\n<p>With this operation you can search for rows that contain an Hstore in which any value matches (ilike) to the parameter.\nIt uses the ilike syntaxis, so you can do for example:</p>\n<pre><code class=\"language-groovy\">def wantedValue = "%my-value%"\ndef result = MyDomain.withCriteria {\n pgHstoreILikeValue "attributes", wantedKey\n}\n</code></pre>\n<h3>JSON</h3>\n<p>To define a json field you only have to define a <code>Map</code> field and use the <code>JsonMapType</code> hibernate user type.</p>\n<pre><code class=\"language-groovy\">import net.kaleidos.hibernate.usertype.JsonMapType\n\nclass TestMapJson {\n Map data\n\n static constraints = {\n }\n static mapping = {\n data type: JsonMapType\n }\n}\n</code></pre>\n<h4>Using Json</h4>\n<p>Now you can create and instance of the domain class:</p>\n<pre><code class=\"language-groovy\">def instance = new TestMapJson(data: [name: "Iv\ufffd\ufffd\ufffd\ufffdn", age: 35, hasChilds: true, childs: [[name: 'Judith', age: 8], [name: 'Adriana', age: 5]]])\ninstance.save()\n</code></pre>\n<pre><code>=# select * from test_map_json;\n\n id | version | data\n----+---------+-------------------------------------------------------------------------------------------------------------\n 1 | 0 | {"hasChilds":true,"age":35,"name":"Iv\ufffd\ufffd\ufffd\ufffdn","childs":[{"name":"Judith","age":8},{"name":"Adriana","age":5}]}\n</code></pre>\n<p>As you can see the plugin converts to Json automatically the attributes and the lists in the map type.</p>\n<h4>Json Criterias</h4>\n<p>The plugin provides some criterias to query json fields. You can check the official\n<a href=\"http://www.postgresql.org/docs/9.3/static/functions-json.html\">Postgresql Json functions and operators</a> in case you\nneed additional ones.</p>\n<h5>Has field value</h5>\n<p>With this criteria you can check if a json field contains some <em>value</em> in some <em>key</em>. To use it just use the criteria\n<code>pgJsonHasFieldValue</code>:</p>\n<pre><code class=\"language-groovy\">def obj1 = new TestMapJson(data: [name: 'Iv\ufffd\ufffd\ufffd\ufffdn', lastName: 'L\ufffd\ufffd\ufffd\ufffdpez']).save(flush: true)\ndef obj2 = new TestMapJson(data: [name: 'Alonso', lastName: 'Torres']).save(flush: true)\ndef obj3 = new TestMapJson(data: [name: 'Iv\ufffd\ufffd\ufffd\ufffdn', lastName: 'P\ufffd\ufffd\ufffd\ufffdrez']).save(flush: true)\n\ndef result = TestMapJson.withCriteria {\n pgJsonHasFieldValue 'data', 'name', 'Iv\ufffd\ufffd\ufffd\ufffdn'\n}\n</code></pre>\n<p>The previous criteria will return all the rows that have a <code>name</code> attribute in the json field <code>data</code> with the value\n<code>Iv\ufffd\ufffd\ufffd\ufffdn</code>. In this example <code>obj1</code> and <code>obj3</code>.</p>\n<h5>Generic criterion</h5>\n<p>With this criterion you can use more operators using a syntax close to the one described in Postgresql documentation.\nTo use it just use <code>pgJson</code>:</p>\n<pre><code class=\"language-groovy\">def obj1 = new TestMapJson(data: [name: 'Iv\ufffd\ufffd\ufffd\ufffdn', lastName: 'L\ufffd\ufffd\ufffd\ufffdpez', other: [followersCount: 150]]).save(flush: true)\ndef obj2 = new TestMapJson(data: [name: 'Alonso', lastName: 'Torres', other: [followersCount: 148]]).save(flush: true)\ndef obj3 = new TestMapJson(data: [name: 'Iv\ufffd\ufffd\ufffd\ufffdn', lastName: 'P\ufffd\ufffd\ufffd\ufffdrez', other: [followersCount: 149]]).save(flush: true)\n\ndef result1 = TestMapJson.withCriteria {\n pgJson 'data', '->>', 'name', 'ilike', '%iv%'\n}\n</code></pre>\n<p>The previous query will return all the rows that have a <code>name</code> attribute in the json field <code>data</code> containing <code>iv</code>\n(case insensitive). In this example <code>obj1</code> and <code>obj3</code>.</p>\n<pre><code class=\"language-groovy\">def result2 = TestMapJson.withCriteria {\n pgJson 'data', '#>>', '{other, followersCount}', '>', 149\n}\n</code></pre>\n<p>The previous query will return all the rows that have an <code>other</code> value whose <code>followersCount</code> value is greater than\n<code>149</code>. In this example <code>obj1</code>.</p>\n<h3>Jsonb</h3>\n<p>Since postgresql-extensions version 4.4.0 it is possible to use <a href=\"http://www.postgresql.org/docs/9.4/static/datatype-json.html\">Postgresql Jsonb</a>\ninstead of just json. You need to use at least Postgresql 9.4.</p>\n<p>To define a jsonb field you only have to define a <code>Map</code> field and use the <code>JsonbMapType</code> hibernate user type.</p>\n<pre><code class=\"language-groovy\">import net.kaleidos.hibernate.usertype.JsonbMapType\n\nclass TestMapJsonb {\n Map data\n\n static constraints = {\n }\n static mapping = {\n data type: JsonbMapType\n }\n}\n</code></pre>\n<h4>Jsonb Criterias</h4>\n<p>The same criterias implemented for Json are valid for Jsonb. Besides that, there are some criterias that are only\nvalid for Jsonb. Check the <a href=\"http://www.postgresql.org/docs/9.4/static/functions-json.html\">documentation</a>.</p>\n<h5>Contains</h5>\n<p>With this criteria you can get all the rows that contain all the values in the map. To use it just use the criteria\n<code>pgJsonContains</code>:</p>\n<pre><code class=\"language-groovy\">def obj1 = new TestMapJsonb(data: [a: 'foo', b: '1']).save(flush: true)\ndef obj2 = new TestMapJsonb(data: [b: 1, d: '2']).save(flush: true)\ndef obj3 = new TestMapJsonb(data: [a: 'foo', b: '1', c: 'test',]).save(flush: true)\n\ndef result = TestMapJsonb.withCriteria {\n pgJsonbContains data, [a: 'foo', b: '1']\n}\n</code></pre>\n<p>The previous criteria will return all the rows that contains all the keys/values (<code>[a: 'foo', b: '1']</code> in the example)\nin the <code>data</code> field. In this example will return <code>obj1</code> and <code>obj3</code>.</p>\n<h4>Is contained</h4>\n<p>With this criteria you can get all the rows that are contained by the values. To use it just use the criteria\n<code>pgArrayIsContainedBy</code>:</p>\n<pre><code class=\"language-groovy\">def obj1 = new TestMapJsonb(data: [a: 'foo', b: '1']).save(flush: true)\ndef obj2 = new TestMapJsonb(data: [b: 1, d: '2']).save(flush: true)\ndef obj3 = new TestMapJsonb(data: [b: '1', a: 'foo', c: 'test',]).save(flush: true)\n\ndef result = TestMapJsonb.withCriteria {\n pgJsonbIsContained data, [a: 'foo', b: '1', c: 'test']\n}\n</code></pre>\n<p>The previous criteria will return all the rows that are contained in the map. In the example it will retun the objects\n<code>obj1</code> and <code>obj3</code>.</p>\n<h3>Order</h3>\n<h4>Random order</h4>\n<p>Sometimes you need to get some results ordered randomly from the database. Postgres provides a native function to do\nthat. So you can write something like this:</p>\n<pre><code class=\"language-sql\">select * from foo order by random();\n</code></pre>\n<p>The plugin now offers a new order method to do this random sorting:</p>\n<pre><code class=\"language-groovy\">import static net.kaleidos.hibernate.order.OrderByRandom.byRandom\n\nclass MyService {\n List<TestMapJsonb> orderByRandom() {\n return TestMapJsonb.withCriteria {\n order byRandom()\n }\n }\n}\n</code></pre>\n<h4>Sql formula</h4>\n<p>You may need to do a more complex sorting. Imagine that you have a table with a <code>jsonb</code> column and you want to order\nby a field in that json. Using sql you can write:</p>\n<pre><code class=\"language-sql\">select * from foo order by (data->'name') desc\n</code></pre>\n<p>With the plugin you can do the same with a new order method called <code>sqlFormula</code>:</p>\n<pre><code class=\"language-groovy\">import static net.kaleidos.hibernate.order.OrderBySqlFormula.sqlFormula\n\nclass MyService {\n List<TestMapJsonb> orderByJson() {\n return TestMapJsonb.withCriteria {\n order sqlFormula("(data->'name') desc")\n }\n }\n}\n</code></pre>\n<p>It's important to note that the "raw" sql is appended to the criteria, so you need to be sure that it's valid because\nif not you'll get a sql error during runtime.</p>\n<h2>Authors</h2>\n<p>You can send any questions to:</p>\n<ul>\n<li>Iv\ufffd\ufffd\ufffd\ufffdn L\ufffd\ufffd\ufffd\ufffdpez: lopez.ivan@gmail.com (<a href=\"https://twitter.com/ilopmar\">@ilopmar</a>)</li>\n<li>Alonso Torres: alonso.javier.torres@gmail.com (<a href=\"https://twitter.com/alotor\">@alotor</a>)</li>\n</ul>\n<p>Collaborations are appreciated :-)</p>\n<h2>Release Notes</h2>\n<p>Version | Date | Comments\n------- | ------------| ---------\n7.0.0 | 29/Jul/2019 | Grails 4 (Hibernate 5.4): Add support for Grails 4 and Hibernate 5.4. Thanks to <a href=\"https://github.com/jamesdh\">James Hardwick</a> and <a href=\"https://github.com/zhuravskiy\">Zhuravskiy Vitaliy</a>.\n6.1.0 | 24/Sep/2018 | Grails 3 (Hibernate 5.2): Fix <a href=\"https://github.com/kaleidos/grails-postgresql-extensions/issues/30\">#30</a>. Thanks to <a href=\"https://github.com/butters16\">John Keith</a> and <a href=\"https://github.com/jglapa\">jglapa</a>.\n5.3.0 | 24/Sep/2018 | Grails 3 (Hibernate 5): Fix <a href=\"https://github.com/kaleidos/grails-postgresql-extensions/issues/30\">#30</a>. Thanks to <a href=\"https://github.com/butters16\">John Keith</a> and <a href=\"https://github.com/jglapa\">jglapa</a>.\n4.8.0 | 24/Sep/2018 | Grails 3 (Hibernate 4): Fix <a href=\"https://github.com/kaleidos/grails-postgresql-extensions/issues/30\">#30</a>. Thanks to <a href=\"https://github.com/butters16\">John Keith</a> and <a href=\"https://github.com/jglapa\">jglapa</a>.\n6.0.0 | 05/Jun/2018 | Grails 3: Add support for Hibernate 5.2. <a href=\"https://github.com/kaleidos/grails-postgresql-extensions/pull/114\">#114</a>. Thanks to <a href=\"https://github.com/donbeave/\">Alexey Zhokhov</a> and <a href=\"https://github.com/abcfy2\">Feng Yu</a>.\n5.2.0 | 03/Nov/2017 | Grails 3 (Hibernate 5): Merged <a href=\"https://github.com/kaleidos/grails-postgresql-extensions/pull/107\">#107</a> and <a href=\"https://github.com/kaleidos/grails-postgresql-extensions/pull/109\">#109</a>.\n5.1.0 | 22/May/2017 | Grails 3 (Hibernate 5): Change db credentials to make it compatible with Postgresql 9.6.\n4.7.0 | 22/May/2017 | Grails 3 (Hibernate 4): Change db credentials to make it compatible with Postgresql 9.6.\n5.0.1 | 21/May/2017 | Grails 3 (Hibernate 5): Fix <a href=\"https://github.com/kaleidos/grails-postgresql-extensions/issues/96\">#96</a>. Thanks to <a href=\"https://github.com/jglapa\">jglapa</a>.\n4.6.9 | 21/May/2017 | Grails 3 (Hibernate 4): Fix <a href=\"https://github.com/kaleidos/grails-postgresql-extensions/issues/96\">#96</a>. Thanks to <a href=\"https://github.com/jglapa\">jglapa</a>.\n5.0.0 | 07/Nov/2016 | Grails 3: Add support for Hibernate 5.1. Upgrade dialect to Postgresql 9.4, Grails to 3.2.2 and GORM to 6.0.3.\n4.6.8 | 03/Nov/2016 | Grails 3: Add support for generic Json/Jsonb criteria <a href=\"https://github.com/kaleidos/grails-postgresql-extensions/pull/95\">#95</a>. Thanks to Sabst.\n4.6.7 | 01/Nov/2016 | Grails 3: Add UUID arrays. Thanks to <a href=\"https://twitter.com/karaken12\">Tom Potts</a>. Fix <a href=\"https://github.com/kaleidos/grails-postgresql-extensions/issues/87\">#87</a>\n5.0.0-RC1 | 28/Oct/2016 | Grails 3: Add support for Hibernate 5. Thanks to <a href=\"https://github.com/donbeave/\">Alexey Zhokhov</a> and <a href=\"https://github.com/erichelgeson/\">Eric Helgeson</a>.\n4.6.6 | 24/Apr/2016 | Grails 3: Migrate (almost) all Java code to Groovy + @CompileStatic. No new features added.\n4.6.5 | 31/Dec/2015 | Grails 3: Fix <a href=\"https://github.com/kaleidos/grails-postgresql-extensions/issues/84\">#84</a>. Starting Grails 3.0.10 the default <code>sequence_per_table</code> parameter was not working.\n4.6.4 | 29/Dec/2015 | Grails 3: Cleanup and new jar file with the same functionality as previous version. It seems that version 4.6.3 is corrupted.\n4.6.3 | 08/Dec/2015 | Grails 3: Add new criterias for Jsonb: contains and isContained.\n4.6.2 | 05/Dec/2015 | Grails 3: Cleanup old code for support Hstore in old Grails versions.\n4.6.1 | 02/0ct/2015 | Plugin migrated to Grails 3.\n4.6.1 | 21/Sep/2015 | Hibernate 4.x. Fix <a href=\"https://github.com/kaleidos/grails-postgresql-extensions/issues/76\">#76</a>.\n4.6.0 | 08/Sep/2015 | Hibernate 4.x. Add support to order by a sql formula and by random. Fix <a href=\"https://github.com/kaleidos/grails-postgresql-extensions/issues/72\">#72</a>.\n4.5.0 | 02/Jun/2015 | Hibernate 4.x. GR8Conf Hackergarten! Merge PRs: <a href=\"https://github.com/kaleidos/grails-postgresql-extensions/pull/62\">#62</a>, <a href=\"https://github.com/kaleidos/grails-postgresql-extensions/pull/66\">#66</a>, <a href=\"https://github.com/kaleidos/grails-postgresql-extensions/pull/67\">#67</a>, <a href=\"https://github.com/kaleidos/grails-postgresql-extensions/pull/68\">#68</a>, <a href=\"https://github.com/kaleidos/grails-postgresql-extensions/pull/69\">#69</a>.\n3.4.0 | 02/Jun/2015 | Hibernate 3.x. GR8Conf Hackergarten! Add Jsonb support for Hibernate 3.x <a href=\"https://github.com/kaleidos/grails-postgresql-extensions/issues/64\">#64</a>.\n4.4.0 | 15/Mar/2015 | Hibernate 4.x. Add support for Jsonb.\n3.3.0 | 18/Aug/2014 | Hibernate 3.x. Fix <a href=\"https://github.com/kaleidos/grails-postgresql-extensions/issues/49\">#49</a>. Configure sequence per table or a global sequence for all tables.\n4.3.0 | 17/Aug/2014 | Hibernate 4.x. Fix <a href=\"https://github.com/kaleidos/grails-postgresql-extensions/issues/49\">#49</a>. Configure sequence per table or a global sequence for all tables.\n3.2.0 | 02/Aug/2014 | Hibernate 3.x. pgJsonHasFieldValue criteria.\n4.2.0 | 28/Jul/2014 | Hibernate 4.x. pgJsonHasFieldValue criteria.\n3.1.0 | 25/Jul/2014 | Add JSON support for Hibernate 3.x. It's now possible to store and read domain classes with map types persisted to json.\n4.1.0 | 24/Jul/2014 | Add JSON support. It's now possible to store and read domain classes with map types persisted to json.\n4.0.0 | 18/Jul/2014 | Version compatible with Hibernate 4.x.\n3.0.0 | 18/Jul/2014 | Version compatible with Hibernate 3.x.\n<a href=\"https://github.com/kaleidos/grails-postgresql-extensions/issues?milestone=1\">0.9</a> | 16/Jun/2014 | Add new array criterias: pgArrayEquals, pgArrayNotEquals.\n0.8.1 | 24/Apr/2014 | Fix NPE when array is null.\n0.8 | 24/Apr/2014 | Added support for Double and Float arrays. Refactored the ArrayType to be used as a parametrized type.\n0.7 | Unreleased | New HstoreMapType and update plugin to Grails 2.2.5.\n0.6.8 | 22/Apr/2014 | Fix NPE in HstoreType.\n0.6.7 | 14/Feb/2014 | Support Java Arrays in criterias.\n0.6.6 | 14/Feb/2014 | New criteria pgArrayIsEmptyOrContains.\n0.6.5 | 13/Feb/2014 | Fix bug deleting instances with Hstore type. Thanks to Manuel Unno Vio!\n0.6.4 | 30/Jan/2014 | Convert automatically the keys of Hstore to string.\n0.6.3 | 19/Jan/2014 | Display the class name during startup when detecting a hstore property.\n0.6.2 | Unreleased | Refactor some tests.\n0.6.1 | 28/Nov/2013 | Update postgresql jdbc driver to version 9.2 and do not export hibernate plugin.\n0.6 | 21/Nov/2013 | Use a more complete Hstore parser. Thanks to Moritz Kobel!\n0.5.1 | 10/Nov/2013 | Change base directory to compile AST before the plugin classes. Thanks to Moritz Kobel!\n0.5 | 08/Nov/2013 | Add criteria operation for Hstore types.\n0.4.1 | Unreleased | Compile AST before the project itself.\n0.4 | 28/Oct/2013 | Add support to Hstore. It's only possible to save and get, but no queries has been implemented.\n0.3 | 18/Sep/2013 | Add support to define the schema name for the sequences.\n0.2 | 25/Aug/2013 | Support for arrays of Enums with automatic serialization/deserialization to ordinal integer value. Thanks to Matt Feury!\n0.1.1 | 22/Jul/2013 | Some refactors of the code. No functionality added.\n0.1 | 16/Jul/2013 | Initial version of the plugin with support for integer, long and string array types and criterias pgArrayContains, pgArrayIsContainedBy, pgArrayOverlaps, pgArrayIsEmpty and pgArrayIsNotEmpty.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "qrcode", |
| "repo": "plugins", |
| "owner": "technipelago", |
| "desc": "A plugin that allows you to create QR codes as part of your Grails application without the need for an external service", |
| "labels": [ |
| "qrcode" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/goeh/grails-qrcode/issues", |
| "latestVersion": "0.9", |
| "updated": "2016-03-31T13:31:55.574Z", |
| "systemIds": [ |
| "org.grails.plugins:qrcode" |
| ], |
| "vcsUrl": "https://github.com/goeh/grails-qrcode" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<p>This plugin allows you to create QR codes as part of your Grails\napplication without the need for an external service.</p>\n<h1>Installation</h1>\n<p>For Grails 2 use version 0.7, for Grails 3 use version 0.8+.</p>\n<h2>Grails 2</h2>\n<p>Add a dependency in BuildConfig.groovy:</p>\n<pre><code class=\"language-groovy\">grails.project.dependency.resolution = {\n // ...\n plugins {\n compile ':qrcode:0.7'\n // ...\n }\n}\n</code></pre>\n<h2>Grails 3</h2>\n<p>Add a dependency in build.gradle</p>\n<pre><code class=\"language-groovy\">compile 'org.grails.plugins:qrcode:0.9'\n</code></pre>\n<h1>Usage</h1>\n<h2>QrcodeController</h2>\n<p>Render text QRCode at default size (300x300px)</p>\n<pre><code>.../qrcode/text/Hello+World\n</code></pre>\n<p>Render text QRCode in 30x30px</p>\n<pre><code>.../qrcode/text?w=30&text=test\n</code></pre>\n<p><img src=\"src/test/resources/qrcode.png\" alt=\"QRCode\" /></p>\n<pre><code>Render url QRCode\n\n.../qrcode/url?u=http://grails.org/plugin/qrcode\n</code></pre>\n<h3>Configuration</h3>\n<p>The maximum value of the <em>width</em> parameter can be configured with <em>qrcode.size.max</em> (default 1024).</p>\n<pre><code>qrcode.size.max = 2048\n</code></pre>\n<h2>QrCodeService</h2>\n<pre><code>qrCodeService.renderPng("test", 30, outputStream)\n</code></pre>\n<h2>Tag Library</h2>\n<p>Namespace: <em>qrcode</em></p>\n<p>Render text as QRCode</p>\n<pre><code><qrcode:image height="100" width="100" text="TEST TEXT"/>\n</code></pre>\n<p>If you want to include a QRCode image in an email and you use a GSP to render email content you must set attribute <em>absolute="true"</em>.\nOtherwise the image url will not start with <em>http://</em> and will probably not render correct.</p>\n<pre><code><qrcode:image height="100" width="100" text="#648357" alt="Invoice #648357" absolute="true"/>\n</code></pre>\n<p>Render current request url as QRCode</p>\n<pre><code><qrcode:url width="64"/>\n</code></pre>\n<h3>Render vCard contact information as QRCode</h3>\n<p>In this example we have a method on the Person domain class that returns contact information as a vCard formatted String.</p>\n<pre><code>class Person {\n ...\n transient String getVcard() {\n def s = new StringBuilder()\n s << "BEGIN:VCARD\\n"\n s << "VERSION:3.0\\n"\n s << "N:${lastName};${firstName};;;\\n"\n s << "FN: ${fullName}\\n"\n s << "ORG:${companyName}\\n"\n s << "TITLE:${title ? title.replace(',', '\\\\,') : ''}\\n"\n s << "TEL;TYPE=work,voice,pref:${phone}\\n"\n s << "TEL;TYPE=cell,voice:${cellphone}\\n"\n s << "EMAIL;type=internet,pref:${email}\\n"\n s << "ADR;TYPE=work,postal,pref:;;${address};${city};${state};${postalCode};${country}\\n"\n def timestampFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")\n s << "REV:${timestampFormat.format(lastUpdated ?: dateCreated)}\\n"\n s << "END:VCARD\\n"\n return s.toString()\n }\n}\n</code></pre>\n<p>Now it's easy to render a QRCode of the contact information.\nThis QRCode can be scanned with a smartphone and imported as a contact.</p>\n<pre><code><qrcode:image height="150" text="${person.vcard}" alt="${person.fullName} ${person.address} ${person.city}"/>\n</code></pre>\n<h2>Changes</h2>\n<p>Version 0.9: Prevent DoS attempts using large size/width values.</p>\n<p>Version 0.8: Grails 3 support.</p>\n<p>Version 0.7: Upgraded zxing dependency to 3.2.0.</p>\n<p>Version 0.6: Upgraded pngj dependency to 2.1.0.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "quartz", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Grails quartz plugin", |
| "labels": [ |
| "quartz", |
| "scheduling" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/grails-quartz/issues", |
| "latestVersion": "3.0.0", |
| "updated": "2024-04-04T01:05:36.000Z", |
| "systemIds": [ |
| "org.grails.plugins:quartz" |
| ], |
| "vcsUrl": "https://github.com/grails/grails-quartz" |
| }, |
| "documentationUrl": "https://grails.github.io/grails-quartz/latest/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/grails/plugins/quartz/maven-metadata.xml", |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "quartz-config-scheduler", |
| "repo": "grails-plugins", |
| "owner": "9ci", |
| "desc": "Quartz Config Scheduler - Allow creating quartz job from configuration", |
| "labels": [ |
| "quartz", |
| "scheduling" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/yakworks/quartz-config-scheduler/issues", |
| "latestVersion": "4.0.0", |
| "updated": "2020-10-31T05:17:26.442Z", |
| "systemIds": [ |
| "org.grails.plugins:quartz-config-scheduler" |
| ], |
| "vcsUrl": "https://github.com/yakworks/quartz-config-scheduler" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://circleci.com/gh/yakworks/view-tools\"><img src=\"https://img.shields.io/circleci/project/github/yakworks/quartz-config-scheduler/master.svg?longCache=true&style=for-the-badge&logo=circleci\" alt=\"CircleCI\" /></a>\n<a href=\"http://9ci.com\"><img src=\"https://img.shields.io/badge/BUILT%20BY-9ci%20Inc-blue.svg?longCache=true&style=for-the-badge\" alt=\"9ci\" /></a>\n<img src=\"https://forthebadge.com/images/badges/built-with-love.svg\" height=\"28\">\n<a href=\"https://forthebadge.com\"><img src=\"https://forthebadge.com/images/badges/made-with-groovy.svg\" alt=\"forthebadge\" /></a>\n<img src=\"https://forthebadge.com/images/badges/gluten-free.svg\" height=\"28\">\n<a href=\"https://forthebadge.com\"><img src=\"https://forthebadge.com/images/badges/approved-by-george-costanza.svg\" alt=\"forthebadge\" /></a></p>\n<h2>Install</h2>\n<p><strong>grails 4</strong></p>\n<pre><code class=\"language-groovy\">compile "org.grails.plugins:quartz-config-scheduler:4.0.0"\n</code></pre>\n<p><strong>grails 3+</strong></p>\n<pre><code class=\"language-groovy\">compile "org.grails.plugins:quartz-config-scheduler:2.0.0"\n</code></pre>\n<h2>Quartz config scheduler</h2>\n<p>The plugin builds on top of quartz grails plugin and makes it possible to schedule quartz job on the fly from configuration.</p>\n<h2>Quickstart</h2>\n<p>Enable <code>grails.plugin.quartz.autoStartup = true</code></p>\n<p>And then schedule a closure job as shown below.</p>\n<p>File <code>application.groovy</code> or an external configuration file.</p>\n<pre><code class=\"language-groovy\">import org.quartz.Trigger\nimport org.quartz.Scheduler\nimport org.springframework.context.ApplicationContext\nimport grails.plugin.quartzconfigscheduler.ClosureJob\nimport org.quartz.JobExecutionContext\nimport org.quartz.TriggerBuilder\n\ngrails.plugin.quartz.jobSetup.testJob = { Scheduler scheduler, ApplicationContext context ->\n \n Trigger trigger = TriggerBuilder.newTrigger().withIdentity("closureJobTrigger")\n .withSchedule(\n simpleSchedule()\n .withIntervalInMilliseconds(10)\n .withRepeatCount(2)\n ).startNow().build()\n \n Map jobParams = [param1:value1]\n ClosureJob.schedule(trigger, jobParams) { JobExecutionContext jobCtx ->\n println "Job executed"\n } \n\n}\n\n</code></pre>\n<h2>Configuration</h2>\n<ul>\n<li><code>grails.plugin.quartz.autoStartup</code> - set to true enable scheduling jobs from configuration on application startup.</li>\n<li><code>grails.plugin.quartz.jobSetup</code> - All jobs are configured under this key.</li>\n</ul>\n<h2>Scheduling jobs</h2>\n<p>Plugin provides two job classes to setup jobs from configuration. <code>ClosureJob</code> and <code>SpringBeanJob</code>\nPlugin looks for configuration key <code>grails.plugin.quartz.jobSetup</code> and each child key of it is considered as a job setup\nIt must be a closure, the closure gets executed on application startup and is passed two parameters <code>Scheduler</code> and <code>ApplicationContext</code></p>\n<h2>ClosureJob</h2>\n<p><code>ClosureJob</code> provides one static method <code>schedule</code> which takes a trigger, Map of job params and a closure and schedules the quartz job.\nThe closure is executed each time the job is triggered. The <code>JobExecutionContext</code> is passed to the closure as argument.</p>\n<p><em><strong>Example</strong></em></p>\n<pre><code class=\"language-groovy\">\nTrigger trigger //build trigger as per the need\nClosureJob.schedule(trigger, jobParams) { JobExecutionContext jobCtx ->\n println "Job executed"\n\n} \n</code></pre>\n<h2>SpringBeanJob</h2>\n<p><code>SpringBeanJob</code> can be used to schedule a job which will invoke a specified method on a configured spring bean.\nThe <code>SpringBeanJob</code> provides a static method which takes <code>Trigger</code>, spring bean name, method name and arguments to pass to the method as parameters\nand calls the method on the spring bean with specified arguments every time the job is triggered.</p>\n<p><strong>Example</strong>\nimport grails.plugin.quartzconfigscheduler.SpringBeanJob</p>\n<p>File: <code>application.groovy</code></p>\n<pre><code class=\"language-groovy\">\nTrigger trigger //build trigger as per the need\nSpringBeanJob.schedule(trigger, "myService", "testMethod", "testArg")\n\n\nclass MyService {\n\n void testMethod(String arg) {\n println "Method is executed with arg $arg" \n }\n\n}\n\n</code></pre>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "queuekit", |
| "repo": "maven", |
| "owner": "vahid", |
| "desc": "Queuekit is a plugin for grails which uses TaskExecutor with Spring Events for grails 2 and for grails 3 using default `Reactor` events to manage concurrent submitted reports.", |
| "labels": [ |
| "reporting", |
| "scheduling", |
| "queue" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/vahidhedayati/grails-queuekit-plugin/issues", |
| "latestVersion": "1.10", |
| "updated": "2016-11-02T21:53:15.054Z", |
| "systemIds": [ |
| "org.grails.plugins:queuekit" |
| ], |
| "vcsUrl": "https://github.com/vahidhedayati/grails-queuekit-plugin" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>queuekit</h1>\n<h3>Side note - similar / related projects</h3>\n<ul>\n<li>\n<p><a href=\"https://github.com/vahidhedayati/grails-queuekit-plugin\">grails-queuekit-plugin (this)</a></p>\n</li>\n<li>\n<p><a href=\"https://github.com/vahidhedayati/grails-queuemail-plugin\">grails-queuemail-plugin</a></p>\n</li>\n</ul>\n<h4>Queuekit is a plugin for grails which uses TaskExecutor with Spring Events for grails 2 and for grails 3 using</h4>\n<p>default <code>Reactor</code> events to manage concurrent submitted reports.You can use it for your own custom reporting needs or\nsimply combine it with grails export plugin to queue export requests.</p>\n<h5>At work we face a scenario where reports and core application are integrated and even if separated they would</h5>\n<p>still hit the same database.</p>\n<h5>The reports are typically rendered through response as a file stream and saved to user's desktop.</h5>\n<h5>At some periods of the day the application runs slow, we think due to people running reports concurrently.</h5>\n<p>Without going into further complexity of database, application and reporting system. A cure would be to limit the amount\nof concurrent reports that can run and sort reports based on a priority system allowing (HIGHER: Speedier ones through\nover LOWER: Calculations would suggest it will take long per report basis)</p>\n<h5>Queuekit plugin incorporates TaskExecutor ArrayBlocking / LinkBlocking and PriorityBlocking.</h5>\n<h4>It also enhances on PriorityBlocking with a new custom method called EnhancedPriorityBlocking.</h4>\n<h5>Define queue limit which in turn limits concurrent usage of all users.</h5>\n<h5>Typical request on demand report system will change to background queued reports system. Choose the</h5>\n<p>best blocking method for your queues.</p>\n<h5>Both Priority and EnhancedPriority allow queue items to have a default or on the fly priority.</h5>\n<h5>EnhancedPriorityBlocking is more costly and launches addition threads per job but all in aid of actually being</h5>\n<p>able to kill a live running IO task.</p>\n<h5>When master task or live running task is cancelled. The underlying thread is cancelled. This gives you the</h5>\n<p>feature to cancel live background threaded tasks.</p>\n<h5>If you run reports in such a manner, read on since with a minor tweak and the help of this plugin you can easily</h5>\n<p>convert those reports to background queued tasks that you then define limitation over.</p>\n<h2>1. Installation:</h2>\n<h3>Grails 3:</h3>\n<pre><code class=\"language-groovy\">compile "org.grails.plugins:queuekit:1.10"\n</code></pre>\n<h5><a href=\"https://github.com/vahidhedayati/grails-queuekit-plugin/\">source</a> |</h5>\n<p><a href=\"https://github.com/vahidhedayati/test-queuekit3/\">demo</a></p>\n<h3>Grails 2:</h3>\n<pre><code class=\"language-groovy\">compile ":queuekit:1.5"\n</code></pre>\n<h5><a href=\"https://github.com/vahidhedayati/grails-queuekit-plugin/tree/grails2\">source</a> |</h5>\n<p><a href=\"https://github.com/vahidhedayati/test-queuekit\">demo</a></p>\n<h2>2.<a href=\"https://github.com/vahidhedayati/grails-queuekit-plugin/tree/master/grails-app/conf/SampleConfig.groovy\">Configuration</a></h2>\n<p>The configuration provided would be added to Config.groovy on grails 2 and application.groovy in grails 3.</p>\n<p>####Videos</p>\n<h5><a href=\"https://www.youtube.com/watch?v=hVC8IOagAwo\">Video 1:- grails queuekit plugin part 1 : Why you would use this plugin?</a></h5>\n<h5><a href=\"https://www.youtube.com/watch?v=QntcB_k3JfI\">Video 1:- grails queuekit plugin part 1.5 : Combine grails export plugin with queuekit so export requests are queued</a></h5>\n<h5><a href=\"https://www.youtube.com/watch?v=JgoSSOG_iRI\">Video 2:- grails queuekit plugin part 2 : Configuration walkthrough</a></h5>\n<h5><a href=\"https://www.youtube.com/watch?v=QDZ5-A-4_8o\">Video 3:- grails queuekit plugin part 3 : Demonstrating cancellation of live threadExecutor Threads</a></h5>\n<h5><a href=\"https://www.youtube.com/watch?v=6MOzoPp7o1g\">Video 4:- grails queuekit plugin part 4 : Binding plugin with your grails application security</a></h5>\n<h5><a href=\"https://www.youtube.com/watch?v=ACKo7o6DkkA\">Video 5:- grails queuekit plugin part 5: Preserving a running queue slot for defined priority or above</a></h5>\n<h4><a href=\"https://www.youtube.com/watch?v=hVC8IOagAwo&list=PLfZr1vB6p8XIHP-d8ta8fyYVCgRfr4Y7h\">Video Boxset (all of above)</a></h4>\n<h2>3.Information</h2>\n<p>=====</p>\n<h3>Provides a variety of methods managing your queue:</h3>\n<blockquote>\n<ol>\n<li>ArrayBlockingQueue - This is the most basic and provided are database functionality to manage the queue for you\nArrayBlockingQueue has no mechanism to manage incoming threads, it will take on as much as available and beyond that\nreject them. Additional steps have been added to capture / re-queue those that exhaust the queue and to manually check\nthe queue upon completion of last task.</li>\n</ol>\n</blockquote>\n<blockquote>\n<ol start=\"2\">\n<li>LinkedBlockingQueue - This manages the queue automatically\nLinkedBlockingQueue is the next phase up, Since it manages the queue for you. If you have 3 maximum threads and fire 5.\n2 will wait until the first 2 are done and then their picked up. Queue is processed and limited to items as they arrive.</li>\n</ol>\n</blockquote>\n<blockquote>\n<ol start=\"3\">\n<li>PriorityBlockingQueue - This manages the queue automatically and also attempts to run concurrent requests with a priority.\nPriorityBlockingQueue by default provides a mechanism to manage queue items according to each items priorities.</li>\n</ol>\n</blockquote>\n<blockquote>\n<ol start=\"4\">\n<li>EnhancedPriorityBlockingQueue - This manages the queue automatically and also attempts to run concurrent requests\nwith a priority. PriorityBlockingQueue by default provides a mechanism to manage queue items according to each items priorities.\nIt also binds a new thread task to an inner thread. This means you can also cancel a live running thread.\nWhen a cancel request is issued. The main running thread also kills off the inner thread that is the running task.\nThis required further concurrentHashMaps to track / remove elements.</li>\n</ol>\n</blockquote>\n<p>With both PriorityBlocking and EnhancedPriorityBlocking which was really my own additional work around PriorityBlocking,</p>\n<p>The priority itself is defined by you in your Config.groovy depending on the name given to it.\nThere is also an additional hook that you can add to all/some of your reports that will go off and look at custom\nparameters provided by the report and decide if it should lower/higher the default config priority.\nAn example for this is also provided. The policy as to how it decides is entirely based on what works for you.\nYou could use the example to expand on your business logic.</p>\n<h5>Must outline the topics covered in point 4 EnhancedPriority are all very experimental,</h5>\n<p>it's the end ambition/desire to achieve all that without any side effects. I think you may find odd behaviour.\nYour input / enhancements are most welcome.</p>\n<p>You can configure the following:</p>\n<pre><code class=\"language-groovy\">reportThreads=3\npreserveThreads = 1\npreservePriority = Priority.MEDIUM\n</code></pre>\n<h5>If you have 3 threads and 6 LOW Priority reports launched</h5>\n<h4>If after (reportThreads - preserveThreads) = 3 - 1 = 2 (So only 2 would run at most at any time of LOW Priority)</h4>\n<p>This means all those below Priority.MEDIUM will have a spare slot to run within. In short an fast lane left open always\nfor those below medium and 2 slow lanes. You should be able to configure 6 report</p>\n<h2>With admin rights you can:</h2>\n<h4>> Change a priority of a queued report from the main listing screen.</h4>\n<p>But beyond that when a report is queued you can click on report item and choose change priority. If it was LOW and set\nby Config or override hook you now as the human can set it to be a higher priority which will take effect when next\nthread becomes available.</p>\n<h4>> Increase / Decrease (override Config values of) reportThreads / preserveThreads and preservePriority.</h4>\n<p>This means you can on the fly increase or decrease and change preservePriority group from the main report screen.\nThe changes are only for runtime. Meaning upon restart the defaults from Config.groovy or if not defined what\nplugin thinks is best is used.</p>\n<h4>> Shutdown ThreadExecutor</h4>\n<p>No idea why you want to do this unless you are testing in worst case scenario with intentions of testing\n<code>useEmergencyExecutor=false</code> or <code>manualDownloadEnabled=true</code></p>\n<h4>> Control maximum running time before killing a running task and canelling it.</h4>\n<p>configure <code>killLongRunningTasks=300</code> where 300 = 5 minutes in seconds. Provide the time in seconds you wish to wait\nbefore the taskExecutor sechedule is killed off. This only works for EnhancedPriorityBlockingExecutor and when it\nattempts to pickup the next thread, it checks running task of existing threads.\nIf any match your set limit and beyond they are killed and set to status Cancelled</p>\n<h2>With Configuration you can:</h2>\n<h4>> Configure report time highlight</h4>\n<p>In this example if report takes:</p>\n<blockquote>\n<p>over 01:10:02 (1 hour 10 minutes and 2 seconds) it will highlight in blue\nover 00:01:05 (1 minute and 5 seconds) it will highlight in orange\nover 00:00:12 (12 seconds) it will highlight in html colour code: #FFFFAA</p>\n</blockquote>\n<pre><code class=\"language-groovy\"> durationThreshHold = [\n\t\t[hours: 1, minutes: 10, seconds: 2, color: 'blue'],\n\t\t[minutes: 1, seconds: 5, color: 'orange'],\n\t\t[seconds: 12, color: '#FFFFAA']\n\t]\n</code></pre>\n<h4>> Configure a backup Executor for when / if main Executor is down</h4>\n<p>When tasks go into rejection it is typically due to Executor having issues. This is all true for all Executor\ntypes provides besides ArrayBlocking.\nSo this feature is available for all besides ArrayBlocking. Since ArrayBlocking has no queue mechanism and is managed\nby plugin DB lookups. It automatically puts a new task in rejection if over limit running. Therefore we capture those\nand re-queue them in this case. For all other cases if you enable\n<code>useEmergencyExecutor=true</code> This will tell the plugin to fall over to a single executor and launch a schedule of the\nuser request. This is all transparent to the end user and happens in the back-end. It will throw errors in the log.\nAll the rules of priorities goes out of the window and there are no limitations as many requests made is as many\nthreads launched. It keeps business flowing whilst a fix / resolution is found I guess.</p>\n<p>If main Executor is shutdown - due to how it is wired - (behaving like a service) it needs an application restart\nfor it to reset. Ideas welcome, some comments in EnhancedPriorityBlockingExecutor in regards to this.</p>\n<h4>> Configure a backup of a backup or disable backup Executor and fall back to manualDownload</h4>\n<p>Like above if tasks go into rejection, if you have configured backup executor and even that appears to be shutdown -\nwhich would be strange since the backup is a single executor launched per request. Either way, you can also set this\nto true <code>manualDownloadEnabled=true</code> in your Config.groovy.</p>\n<p>This again is transparent to the end user, but if all of above has failed it will actually launch a new single\nrunnable task to execute the task, the report is treated like all of above, it is captured in report listing, shows\nthat it is running and completed and is also timed. But has totally bypassed all of the threadExecutors and just\nlaunched as a thread within application.</p>\n<p>This also behaves like all of above meaning the end user will get a prompt report has been triggered and if trained to\ndo all ove above they would go to the normal listing screen and wait for it to complete.</p>\n<p>If you wanted to make this fail over behave like a real download, you could refer to <code>ReportDemoController</code> <code>index</code>\naction which has the following:\n(It makes the user wait on the screen whilst the manual thread goes through the process of being created. When it has a\nfile, it redirects to download page like they would have if they had clicked on a live report download action.</p>\n<h2>4. Additional simplification / explanation</h2>\n<p>This plugin is from a concept I put together for work and will convert the process of user report interaction from one of :</p>\n<p>Click on a report - or define report criteria and click download</p>\n<p>If the process is to then go off and get data produce a CSV,XLS,TSV,DOC,PDF of some form and you are using your controller request mechanism\nto deliver file through a stream.</p>\n<p>If above describes your scenario then as you are probably well aware, as database/user-base grows and more reports are\nrequested. Specially concurrent requests by many users can have an impact on your application performance.</p>\n<p>This plugin will be able to change that process and limit to concurrent threads as well as provide a queueing / user\nreport interface. Since the jobs are converted to background tasks the files are produced when system has completed\nand user has to check another interface rather than on demand file generated on the fly as they clicked save/download.</p>\n<p>The process to convert your existing reports should be really kept to a minimal so long as Controller was used to\ngenerate file from some result set that came back from some service. The only minor change is where you\ndefined <code>request type</code> and <code>out</code> and <code>filename</code>. These segments can be stripped out and rest will be near\nenough what you had :</p>\n<h2>Examples</h2>\n<h4>Binding queuekit with grails export plugin</h4>\n<p>Most importantly pay attention to bufferedWriterTypes configuration ensure you have removed CSV and csv from it. If you\nare going to use this plugin for working with export plugin. The export plugin uses a different way to export csv compared\nto how you would normally through a controller as described further down under manual reports.</p>\n<p>You can use this plugin in conjunction with the export plugin to essentially change the mechanism from files produced\nas requested to user requests for export plugin being quueed through queuekit.</p>\n<p>Please feel free to browse through the grails 3 demo site which has all of this in place, I will show the more\nadvanced version since it is probably most feasible.</p>\n<p>You have installed/been using export plugin, you have configured the required addition in the controller to send\nreport to exportService.</p>\n<p>I installed the plugin, created a domain class generated controllers and views and then amended the call to\nexportService to :\n<code>queueReportService.buildReport(reportName,userId , locale, params)</code></p>\n<p>Change that to this</p>\n<pre><code class=\"language-groovy\">\n //def exportService\n def myUserService\n def queueReportService\n\n def index(Integer max) {\n params.max = Math.min(max ?: 10, 100)\n String format=params.f ?: params.extensions ?: 'html'\n if(format && format != "html"){\n def locale = RequestContextUtils.getLocale(request)\n def userId = myUserService.currentuser\n String reportName = 'exportPluginAdvanced'\n /**\n * ! -- IMPORTANT\n * In order to let this dynamic exportPluginAdvancedReportingService pickup the correct domainClass\n * We must send an additional params as part of reports calls and bind in the actual domainClass we would be listing\n * just like shown here\n *\n */\n params.domainClass=TestAddress.class\n\n log.debug "Sending task as default priority to queueReportService instead of exportService.export"\n //def queue = queueReportService.buildReport(reportName,userId , locale, params,Priority.HIGH,ReportsQueue.PRIORITYBLOCKING)\n def queue = queueReportService.buildReport(reportName,userId , locale, params)\n\n flash.message = g.message(code: 'queuekit.reportQueued.label', args: [reportName, queue?.id])\n\n /**\n * How you would normally export using Export plugin\n * Changed to above to go through queuekit plugin and queue request instead\n *\n * Take a look at ExportPluginAdvancedReportingService to see how you can do the same\n *\n */\n // response.contentType = grailsApplication.config.grails.mime.types[format]\n // response.setHeader("Content-disposition", "attachment; filename=books.${params.extension}")\n // exportService.export(format, response.outputStream,TestExport.list(params), [:], [:])\n }\n respond TestAddress.list(params), model:[testAddressCount: TestAddress.count()]\n }\n</code></pre>\n<p>Now with this in place I will need to create a new service called <code>ExportPluginAdvancedReportingService</code>:</p>\n<pre><code class=\"language-groovy\">package test\n\n\nimport grails.util.Holders\nimport org.grails.plugin.queuekit.ReportsQueue\nimport org.grails.plugin.queuekit.reports.QueuekitBaseReportsService\n\nclass ExportPluginAdvancedReportingService extends QueuekitBaseReportsService {\n\n\tdef exportService\n\n\tdef runReport(ReportsQueue queue,Map params) {\n\t\trunReport(queue,[something:'aa'],params)\n\t}\n\t// This doesn't matter so much so long as it meets the Type that is not of\n\t// config value of config.bufferedWriterTypes\n\t// Since it needs to call the other method in QueuekitBaseReportsService\n\t// Actual fileName extension is overriden right at the very bottom of this\n\t// class in getReportName by bean.extension (this ensures file is correctly labelled\n\tString getReportExension() {\n\t\treturn 'xls'\n\t}\n\n\tdef actionInternal(ReportsQueue queue,out,bean, queryResults,Locale locale) {\n \t\tactionReport1Report(queue,out,bean,queryResults)\n \t}\n\n\n \t/**\n \t *\n \t *\n \t * @param out -> Where out is provided by plugin\n \t * @param bean ->Where bean is your actual user params from the front end screen\n \t * @param queryResults -> QueryResults would be what would be produced by your code\n \t * \t\t\t\tIn the case of this we are setting it to [something:'aa']\n \t * \t\t\t\tabove. This then will continue working and hit this block\n \t * \t\t\t\twhich will carry out real export service task at hand.\n */\n\n \tprivate void actionReport1Report(queue,out,bean,queryResults) {\n \t\tString format=bean.f ?: 'html'\n \t\tif(format && format != "html"){\n \t\t\tlog.debug "Params received ${bean.f} ${bean.extension} "\n \t\t\tdef domain= bean.domainClass\n \t\t\ttry {\n \t\t\t\tif (domain) {\n \t\t\t\t\tprintln "got Domain ${domain}"\n \t\t\t\t\t//\tdef domainClass = Holders.grailsApplication?.domainClasses?.find { it.clazz.simpleName == uc(domain) }?.clazz\n \t\t\t\t\tdef domainClass = Holders.grailsApplication.getDomainClass(domain)?.clazz\n \t\t\t\t\tif (domainClass) {\n \t\t\t\t\t\tprintln "we have a real domainClass ${domainClass}"\n \t\t\t\t\t\tdomainClass.withTransaction {\n \t\t\t\t\t\t\tMap formatters=[:]\n \t\t\t\t\t\t\tMap parameters=[:]\n \t\t\t\t\t\t\tswitch (domain) {\n \t\t\t\t\t\t\t\tcase 'testing.TestAddress':\n \t\t\t\t\t\t\t\t\tprintln "custom testAddress stuff here"\n \t\t\t\t\t\t\t\t\t//formatters=[:]\n \t\t\t\t\t\t\t\t\t//parameters=[:]\n \t\t\t\t\t\t\t\t\t//bean.something=SomethingElse\n \t\t\t\t\t\t\t\t\tbreak\n \t\t\t\t\t\t\t\tcase 'testing.TestAttribues':\n \t\t\t\t\t\t\t\t\tprintln "custom testAttributes stuff here"\n \t\t\t\t\t\t\t\t\t//What would you like to do\n \t\t\t\t\t\t\t\t\t//formatters=[:]\n \t\t\t\t\t\t\t\t\t//parameters=[:]\n \t\t\t\t\t\t\t\t\tbreak\n \t\t\t\t\t\t\t}\n \t\t\t\t\t\t\texportService.export(format, (OutputStream) out, domainClass.list(bean),formatters,parameters)\n \t\t\t\t\t\t}\n \t\t\t\t\t}\n \t\t\t\t}\n \t\t\t} catch (Exception e) {\n \t\t\t\tsuper.errorReport(queue,bean)\n \t\t\t}\n \t\t}\n\n\t/*\n\t *\n\t * Overriding how QueuekitBaseReportsService names it here\n\t */\n\tString getReportName(ReportsQueue queue,bean) {\n\t\treturn "ExportPlugin-${queue.id}.${bean.extension?:reportExension}"\n\t}\n\n}\n\n</code></pre>\n<p>That's it, the user reports will now be queued through the queuekit plugin,\nYou can see export feature is called in the <code>ExportPluginAdvancedReportingService</code>.\nThe code in the controller can be copied from controller to controller.\nJust pay attention to: (Ensure you are passing in correct domainClass that you will use in the sharedExport service.</p>\n<pre><code class=\"language-groovy\"> /**\n * ! -- IMPORTANT\n * In order to let this dynamic exportPluginAdvancedReportingService pickup the correct domainClass\n * We must send an additional params as part of reports calls and bind in the actual\n * domainClass we would be listing\n * just like shown here\n *\n */\n params.domainClass=TestAddress.class\n</code></pre>\n<h1>Manual Reports using plugin with your own methods of producing reports</h1>\n<h4>Apache-poi XLS files - manual report</h4>\n<p>Check out <a href=\"https://github.com/vahidhedayati/test-queuekit3/\">grails queuekit demo site for grails 3</a>. Follow the example to see how I got it to work\nAll very similar to instructions below besides that it is using custom libraries to produce the output. (different file types to standard csv/tsv described below)</p>\n<h4>Examples demonstrated on</h4>\n<p><a href=\"https://github.com/vahidhedayati/grails-queuekit-plugin/tree/master/grails-app/controllers/org/grails/plugin/queuekit/examples/ReportDemoController.groovy\">org.grails.plugin.queuekit.examples.ReportDemoController</a></p>\n<p>``</p>\n<p>Assuming you have:</p>\n<pre><code class=\"language-groovy\">response.setHeader 'Content-type','text/plain; charset=utf-8'\nresponse.setHeader "Content-disposition", "attachment; filename=index.tsv"\ndef out = response.outputStream\ndef queryResults=tsvService.runParams(params)\n\tout << 'name\\t'\n\tout << "testing"\n\tout << '\\rtext\\t'\n\tout << "testing text"\n\tout << '\\r'\n\tqueryResults?.each{field->\n\t\tout << field.id << '\\t'\n\t\tout << field.text << '\\t'\n\t\tout << '\\r'\n\t}\nout.flush()\nout.close()\n</code></pre>\n<p>If you change to be like this:</p>\n<pre><code class=\"language-groovy\">def controllerCall() {\n response.setHeader 'Content-type','text/plain; charset=utf-8'\n response.setHeader "Content-disposition", "attachment; filename=index.tsv"\n def out = response.outputStream\n def queryResults=tsvService.runParams(params)\n actionReport(out,queryResults,params)\n}\nprivate actionReport(out,queryResults,params) {\n out << 'name\\t'\n out << params.report\n out << '\\rtext\\t'\n out << params.sample\n out << '\\r'\n queryResults?.each{field->\n\tout << field.id << '\\t'\n\tout << field.text << '\\t'\n\tout << '\\r'\n }\n out.flush()\n out.close()\n}\n</code></pre>\n<p>Then you are half way there, in principal the same thing would be put in to your service that would be in the action\nreport. The plugin handles out so there will be no need to define response or out variables. So all of above would become:</p>\n<pre><code class=\"language-groovy\">def controllerCall() {\n\tdef locale = RequestContextUtils.getLocale(request)\n\tdef userId = queuekitUserService.currentuser\n\tString reportName = 'paramsExample'\n\n\t/*\n\t * these are your own params really\n\t */\n\tparams.report='Params examples'\n\tparams.sample='Some sample text'\n\t\t\n\t//No queue defined - by default Priority\n\tdef queue = queueReportService.buildReport(reportName,userId , locale, params)\n\tflash.message = g.message(code: 'queuekit.reportQueued.label', args: [reportName, queue?.id])\n}\n</code></pre>\n<p>Then we create a service called <a href=\"https://github.com/vahidhedayati/grails-queuekit-plugin/tree/master/grails-app/services/org/grails/plugin/queuekit/examples/reports/ParamsExampleReportingService.groovy\">ParamsExampleReportingService</a></p>\n<pre><code class=\"language-groovy\">package org.grails.plugin.queuekit.examples.reports\n\nimport org.grails.plugin.queuekit.ReportsQueue\nimport org.grails.plugin.queuekit.reports.QueuekitBaseReportsService\n\n\nclass ParamsExampleReportingService extends QueuekitBaseReportsService {\n\n\tdef tsvService\n\t\n /*\n\t * Must be declared gives you params \n\t * You must run your service to get back the results\n\t * Push results params and queue into runReport as show\n\t */\n\tdef runReport(ReportsQueue queue,Map params) {\n\t\tdef queryResults = tsvService.runParams(params)\n\t\trunReport(queue,queryResults,params)\n\t}\n\n /*\n * You must define this as shown. Plugin will provide you at this point\n * with out. Push out queryResults and bean = your original params back into \n * your own custom method which like shown above iterates through your list\n * and pushes into out\n */\n\tdef actionInternal(ReportsQueue queue,out,bean, queryResults,Locale locale) {\n\t\tactionReport1Report(out,bean,queryResults)\n\t}\n\n\tprivate void actionReport1Report(out,bean,queryResults) {\n\t\tout << 'name\\t'\n\t\tout << bean.report\n\t\tout << '\\rtext\\t'\n\t\tout << bean.sample\n\t\tout << '\\r'\n\t\tqueryResults?.each{field->\n\t\t\tout << field.id << '\\t'\n\t\t\tout << field.text << '\\t'\n\t\t\t//This will also work like in your controller\n\t\t\t//out << "${g.message(code:'some.code')}"\n\t\t\tout << '\\r'\n\t\t}\n\t\tout.flush()\n\t\tout.close()\n\t}\n}\n</code></pre>\n<p>That now queues the report requests when someone clicks controllerCall and the report can be seen Here</p>\n<p>You can also use this technology for any other type of files you were generating on the fly in a controller so for example apache-poi</p>\n<pre><code class=\"language-groovy\">String filename = 'Report3Example.xls'\n\tHSSFWorkbook wb = new HSSFWorkbook()\n\tHSSFSheet sheet = wb.createSheet()\n\t....\n\ttry {\n\t\t\n\t\t// When copying your method over to your new Service\n\t\t// as already mentioned out is already provided by plugin \n\t\t// the below 4 lines should not be provided in the new service call\n\t\t// everything else is identical\n\t\tresponse.setContentType("application/ms-excel")\n\t\tresponse.setHeader("Expires:", "0") // eliminates browser caching\n\t\tresponse.setHeader("Content-Disposition", "attachment; filename=$filename")\n\t\tOutputStream out = response.outputStream\n\t\t// End of no longer required - when converted to plugin service method \n\t\twb.write(out)\n\t\tout.close()\n\t} catch (Exception e) {\n\t}\n</code></pre>\n<p>Would be changed to like per above:</p>\n<pre><code class=\"language-groovy\">def controllerCall() {\n\tdef locale = RequestContextUtils.getLocale(request)\n\tdef userId = queuekitUserService.currentuser\n\tString reportName = 'xlsExample'\n\n\t/*\n\t * these are your own params really\n\t */\n\tparams.report='Params examples'\n\tparams.sample='Some sample text'\n\t\t\n\t//No queue defined - by default Priority\n\tdef queue = queueReportService.buildReport(reportName,userId , locale, params)\n\t//You can provide further options look up ReportDemoController to see more examples\n\t//def queue = queueReportService.buildReport(reportName,userId , locale, params,Priority.HIGH,ReportsQueue.PRIORITYBLOCKING)\n\tflash.message = g.message(code: 'queuekit.reportQueued.label', args: [reportName, queue?.id])\n}\n</code></pre>\n<p>Then we create <code>XlsExampleReportingService</code></p>\n<pre><code class=\"language-groovy\">package org.grails.plugin.queuekit.examples.reports\n\nimport org.grails.plugin.queuekit.ReportsQueue\nimport org.grails.plugin.queuekit.reports.QueuekitBaseReportsService\n\n\nclass XlsExampleReportingService extends QueuekitBaseReportsService {\n\n\n\t\n\tdef tsvService\n\t\n\t/*\n\t * We must define the report type file extension\n\t * default is tsv this being XLS needs to be defined\n\t * \n\t */\n\tString getReportExension() {\n\t\treturn 'xls'\n\t}\n\t\n\t\n\t/**\n \t * This overrides the default priority of the report set by\n \t * QueuekitBaseReportsService\n \t *\n \t * By default it is either as per configuration or if not by default\n \t * LOW priority.\n \t *\n \t * At this point you can parse through your params and decide if in this example\n \t * that the given range fromDate/toDate provided is within a day make report\n \t * HIGHEST\n \t * if within a week HIGH and so on\n \t *\n \t * This priority check takes place if you are using\n \t * standard standardRunnable = false if your report default type is\n \t * EnhancedBlocking\n \t * if disableUserServicePriorityCheck=false and standardRunnable = true\n \t * then it should use the priority method very similar to this in\n \t *\n \t * queuekitUserService. This is the service you are supposed to extend\n \t * and declare as a bean back as queuekitUserService.\n \t *\n \t * Then you can control priority through this service call and a more\n \t * centralised control can be configured/setup.\n \t *\n \t */\n \tPriority getQueuePriority(ReportsQueue queue, Map params) {\n \t\tPriority priority = queue.priority ?: queue.defaultPriority\n \t\tif (params.fromDate && params.toDate) {\n \t\t\tDate toDate = parseDate(params.toDate)\n \t\t\tDate fromDate = parseDate(params.fromDate)\n \t\t\tint difference = toDate && fromDate ? (toDate - fromDate) : null\n \t\t\tif (difference||difference==0) {\n \t\t\t\tif (difference <= 1) {\n \t\t\t\t\t// 1 day everything becomes HIGH priority\n \t\t\t\t\tpriority = Priority.HIGH\n \t\t\t\t} else if (difference >= 1 && difference <= 8) {\n \t\t\t\t\tif (priority == Priority.HIGHEST) {\n \t\t\t\t\t\tpriority = Priority.HIGH\n \t\t\t\t\t} else if (priority >= Priority.MEDIUM) {\n \t\t\t\t\t\tpriority = priority.value.previous()\n \t\t\t\t\t}\n \t\t\t\t} else if (difference >= 8 && difference <= 31) {\n \t\t\t\t\tif (priority <= Priority.HIGH) {\n \t\t\t\t\t\tpriority = Priority.MEDIUM\n \t\t\t\t\t} else if (priority >= Priority.LOW) {\n \t\t\t\t\t\tpriority = priority.next()\n \t\t\t\t\t}\n \t\t\t\t} else if (difference >= 31 && difference <= 186) {\n \t\t\t\t\tif (priority >= Priority.MEDIUM && priority <= Priority.HIGHEST) {\n \t\t\t\t\t\tpriority = priority.next()\n \t\t\t\t\t} else if (priority >= Priority.LOW) {\n \t\t\t\t\t\tpriority = priority.previous()\n \t\t\t\t\t}\n \t\t\t\t} else if (difference >= 186) {\n \t\t\t\t\tif (priority <= Priority.LOWEST) {\n \t\t\t\t\t\tpriority = priority.previous()\n \t\t\t\t\t} else if (priority >= Priority.LOW) {\n \t\t\t\t\t\tpriority = priority.next()\n \t\t\t\t\t}\n \t\t\t\t}\n \t\t\t}\n \t\t\tlog.debug "priority is now ${priority} was previously ${priority} difference of date : ${difference}"\n \t\t}\n \t\treturn priority\n \t}\n\t\n\t/*\n\t * \n\t * Overriding how QueuekitBaseReportsService names it here\n\t * Take a look at CsvExampleReportingService where a more \n\t * complex example is provided that defines filename based on \n\t * a value within bean - the report was used\n\t * for multiple different reports - each doing something slightly \n\t * different but using same input bean ..\n\t */\n\tString getReportName(ReportsQueue queue,bean) {\n\t\treturn "MyLovelyReport-${queue.id}.${reportExension}"\n\t}\n\n\n \n\tdef runReport(ReportsQueue queue,Map params) {\n\t\tdef queryResults = tsvService.runParams(params)\n\t\trunReport(queue,queryResults,params)\n\t}\n\n\tdef actionInternal(ReportsQueue queue,out,bean, queryResults,Locale locale) {\n\t\tactionReport1Report(out,bean,queryResults)\n\t}\n\n\tprivate void actionReport1Report(out,bean,queryResults) {\n\t\tHSSFWorkbook wb = new HSSFWorkbook()\n\t\tHSSFSheet sheet = wb.createSheet()\n\t\t//Do your stuff you are doing with out\n\t\tHSSFRow row=sheet.createRow(counter)\n\t\tCell cell1 = row.createCell(i)\n\t\t\tcell1.setCellValue("")\n\t\t\tcell1.setCellStyle(headingStyle)\n\t\t...\n\t\t// finally the above block you had above becomes much simpler\n\t\t// like this:\n\t\t// out is then taken care of by plugin\n\t\ttry {\n\t\t\twb.write(out)\n\t\t\tout.close()\n\t\t} catch (Exception e) {\n\t\t}\n\t\t\t\n\t\t\n\t}\n}\n</code></pre>\n<h3>Beans that bind to other objects</h3>\n<p>Take a look at\n<a href=\"https://github.com/vahidhedayati/grails-queuekit-plugin/tree/master/src/main/groovy/org/grails/plugin/queuekit/examples/ComplexBindedBean.groovy\">org.grails.plugin.queuekit.examples.ComplexBindedBean</a> and read through it to understand how to bypass it</p>\n<h3>Other useful information</h3>\n<blockquote>\n<h3>queuekitUserService <code>def userId = queuekitUserService.currentuser</code></h3>\n</blockquote>\n<p>This is a userService that exists within this plugin, you should override this as per example site and feed in your\nreal user/userId/userLocale/permission values in from your own site.</p>\n<blockquote>\n<h3>reportName <code>String reportName = 'tsvExample1'</code></h3>\n</blockquote>\n<p>This is really as important as it gets, ensure you use proper class naming convention so no +_&*^!\ufffd\ufffd\ufffd\ufffd$%^ characters no\nspace etc just normal alphabet as if you were naming a domain class.\nCreate a new service called</p>\n<blockquote>\n<h5>${name}ReportingService <a href=\"https://github.com/vahidhedayati/grails-queuekit-plugin/tree/master/grails-app/services/org/grails/plugin/queuekit/examples/reports/TsvExample1ReportingService.groovy\">TsvExample1ReportingService</a></h5>\n</blockquote>\n<p>This service must <a href=\"https://github.com/vahidhedayati/grails-queuekit-plugin/tree/master/grails-app/services/org/grails/plugin/queuekit/reports/QueuekitBaseReportsService.groovy\">extend QueuekitBaseReportsService</a>.</p>\n<h1>Binding application security with the plugin</h1>\n<p>Under the <a href=\"https://github.com/vahidhedayati/test-queuekit3/\">grails 3 demo site</a>, spring security got installed a new\nservice called MyUserService which extends QueuekitUserService and overrides the default actions of the plugin to return\nuserId if user is a super user and so forth.</p>\n<p>The service then takes over QueuekitUserService the test site's grails-app/init/test.queuekit3/Application.groovy</p>\n<pre><code class=\"language-groovy\">class Application extends GrailsAutoConfiguration {\n Closure doWithSpring() {\n { ->\n queuekitUserService(test.MyUserService)\n }\n }\n ///....\n</code></pre>\n<h1>Quartz scheduling clean up</h1>\n<p>If you are running quartz, create a task probably running daily that calls</p>\n<pre><code class=\"language-groovy\">def queueReportService\n...\n\nqueueReportService.deleteReportFiles()\n</code></pre>\n<h1>Bootstrap task to re-schedule old queued task pre-application shutdown</h1>\n<p>In your Bootstrap.groovy declare</p>\n<pre><code class=\"language-grooy\">//Inject the service\ndef queuekitExecutorBaseService\n\n//Run this \nqueuekitExecutorBaseService.rescheduleRequeue()\n\n//Also ensure you have enabled in your Config.groovy/application.groovy\nqueuekit.checkQueueOnStart=true\n</code></pre>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "queuemail", |
| "repo": "maven", |
| "owner": "vahid", |
| "desc": "Queuemail plugin is a centralised email queueing system configurable for many providers all centrally controlled and limited to either daily limit or failures exceeding failureTolerance limit (in a row). By default all email's passing through are priority driven and configured by overall customService name. Two methods of priority queueing are provided BASIC and ENHANCED (default). Enhanced launches an additional thread for each running task and will attempt to kill any running process considered as stuck (if time taken exceeds killLongRunningTasks configuration period). ", |
| "labels": [ |
| "mail", |
| "queue" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/vahidhedayati/grails-queuemail-plugin/issues", |
| "latestVersion": "1.3", |
| "updated": "2016-12-07T09:29:32.413Z", |
| "systemIds": [ |
| "org.grails.plugins:queuemail" |
| ], |
| "vcsUrl": "https://github.com/vahidhedayati/grails-queuemail-plugin" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails QueueMail plugin</h1>\n<h3>Side note - similar / related projects</h3>\n<ul>\n<li>\n<p><a href=\"https://github.com/vahidhedayati/grails-queuekit-plugin\">grails-queuekit-plugin</a></p>\n</li>\n<li>\n<p><a href=\"https://github.com/vahidhedayati/grails-queuemail-plugin\">grails-queuemail-plugin (this)</a></p>\n</li>\n</ul>\n<p>Queuemail plugin is a centralised email queueing system configurable for many providers all centrally controlled and limited to either daily limit or failures exceeding failureTolerance limit (in a row). By default all email's passing through are priority driven and configured by overall customService name. Two methods of priority queueing are provided <code>BASIC</code> and <code>ENHANCED (default)</code>. Enhanced launches an additional thread for each running task and will attempt to kill any running process considered as stuck (if time taken exceeds <code>killLongRunningTasks</code> configuration period).</p>\n<p>Email's that arrive in queue are processed through priority rules, please refer to example configuration, each new service you create can be configured to have a specific priority. Higher ones run in preference of lower ones.</p>\n<p>Configure how many active concurrent email threads can run at any one time and how many\ncan wait in the queue to be served. Each email is then bound to the <code>emailService</code> that you create and within it you define\nthe <code>configNames</code> and <code>limit</code>. The configName will then need to be created in your applications Config.groovy/application.groovy\nand essentially contains the SMTP configuration required to connect through and send email's.</p>\n<p>The queueing system will use the first provided configuration for every email requested. If this first <code>configName</code> goes offline or\nwas configured incorrectly it will hit a threshold and plugin will mark configuration as <code>inactive</code></p>\n<p>If an email send attempt fails the sole email is re-attempted until it reaches\n<code>failuresTolerated</code> level. Once this happens current <code>configName</code> is marked as <code>inactive</code> and the next <code>configName</code> is attempted to deliver this email.\nAll new email's will now be going through second <code>configName</code>. The <code>configName</code> that was made <code>inactive</code> will automatically re-join active pool after either setPeriod of time or amount of queueId's passing through. Please refer to notes/configuration and specific segment on message exceptions below.</p>\n<p>Please check with your SMTP provider to ensure you are not violating any TOC's whilst attempting to keep within their set limits/boundaries and consequently/possibly having to switch accounts/providers.</p>\n<h1>Please use this plugin responsibly</h1>\n<h2>1. Installation/Configuration:</h2>\n<h3>Grails 3: <a href=\"https://github.com/vahidhedayati/grails-queuemail-plugin/\">source</a> <a href=\"https://github.com/vahidhedayati/grails-queuemail-plugin/tree/master/grails-app/conf/SampleConfig.groovy\">configuration</a></h3>\n<pre><code class=\"language-groovy\">compile "org.grails.plugins:queuemail:1.3"\n</code></pre>\n<h3>Grails 2: <a href=\"https://github.com/vahidhedayati/grails-queuemail-plugin/tree/grails2\">source</a> <a href=\"https://github.com/vahidhedayati/grails-queuemail-plugin/tree/grails2/grails-app/conf/SampleConfig.groovy\">configuration</a></h3>\n<pre><code class=\"language-groovy\">compile ":queuemail:1.0"\n</code></pre>\n<h2>Basic service the defines SMTP configurations (that are binded to Config objects and limitations per day)</h2>\n<pre><code class=\"language-groovy\">class QueueMailExampleService extends QueueMailBaseService {\n\n\tdef configureMail(executor,EmailQueue queue) {\n\t\t/**\n\t\t * Contains a list of configuration names : daily limit for account\n\t\t * So mailConfigExample1 will bind to Config.groovy SMTP configuration\n\t\t * assuming it is google it may have 3000 daily limit \n\t\t * A listing is provided so it can fall over between list elements starting from top\n\t\t * working it's way down and when limit exceeds it will use the next element\n\t\t */\n\t\tdef jobConfigurations = [\n\t\t\t\t'mailConfigExample1': 2,\n\t\t\t\t'mailConfigExample2': 2,\t\t\t\t\n\t\t\t]\n sendMail(executor,queue,jobConfigurations,QueueMailExampleService.class)\n\t}\n}\n</code></pre>\n<p>Please configure <code>{configName}.fromAddress</code> as shown below. Please note when this is set the actual <code>from</code> address you\nprovide will become <code>replyTo</code> and from will be set as <code>{configName}.fromAddress</code>. If you do not provide this then\nnothing is changed.</p>\n<p>Now with queueMailExample service created, refer to <code>SampleConfig.groovy</code> add the relevant accounts to the\nconfiguration as shown to match with above names. In the most basic form if you add the following to your\nConfig.groovy or application.groovy</p>\n<h2>Example configuration for grails 2</h2>\n<pre><code class=\"language-groovy\">\nqueuemail {\n\n\tmailConfigExample1 {\n\t\thost = "smtp.internal.com"\n\t\tport = 465\n\t\tusername = "USERA@internal.com"\n\t\tpassword = "PASSWORDA"\n\t\tprops = ["mail.debug":"true",\n\t\t\t"mail.smtp.auth":"true",\n\t\t\t"mail.smtp.socketFactory.port":"465",\n\t\t\t"mail.smtp.socketFactory.class":"javax.net.ssl.SSLSocketFactory",\n\t\t\t"mail.smtp.socketFactory.fallback":"false"]\n\t}\n\tmailConfigExample1.fromAddress="USERA@internal.com"\n\t\n\tmailConfigExample2 {\t\t\n\t host = "external.smtp.com"\n\t port = 465\n\t username = "USERB@smtp.com"\n\t password = "PASSWORDB"\n\t props = ["mail.debug":"true",\n\t\t\t"mail.smtp.auth":"true",\n\t\t\t"mail.smtp.socketFactory.port":"465",\n\t\t\t"mail.smtp.socketFactory.class":"javax.net.ssl.SSLSocketFactory",\n\t\t\t"mail.smtp.socketFactory.fallback":"false"]\n\t}\n\tmailConfigExample2.fromAddress="USERB@smtp.com"\n}\t\n</code></pre>\n<h2>Example configuration for application.groovy on grails 3</h2>\n<p>All the additional smtp configuration required whilst testing gmail (only under grails 3):</p>\n<pre><code class=\"language-groovy\">import org.grails.plugin.queuemail.enums.QueueTypes\n\nqueuemail {\n\n\t//standardRunnable = true\n\temailPriorities = [\n\t\t\t\t\tdefaultExample:org.grails.plugin.queuemail.enums.Priority.REALLYSLOW\n\t]\n\n\t// This is an override of grails { mail { configuration method allowing many mail senders\n\n\t// The configuration for DefaultExampleMailingService has set this to be 2 email's\n\t// Meaning after 2 it will fall over to 2nd Configuration\n\n\texampleFrom="usera <userA@gmail.com>"\n\texampleTo="userA_ReplyTo <userA@gmail.com>"\n\n\tmailConfigExample1 {\n\t\thost = "smtp.internal.com"\n\t\tport = 587\n\t\tusername = "userA@internal.com"\n\t\tpassword = 'PASSWORD'\n\t\tprops = ["mail.debug":"true",\n\t\t\t\t "mail.smtp.user":"userA@internal.com",\n\t\t\t\t "mail.smtp.host": "smtp.internal.com",\n\t\t\t\t "mail.smtp.port": "587",\n\t\t\t\t "mail.smtp.auth": "true",\n\t\t\t\t "mail.smtp.starttls.enable":"true",\n\t\t\t\t "mail.smtp.EnableSSL.enable":"true",\n\t\t\t\t "mail.smtp.socketFactory.class":"javax.net.ssl.SSLSocketFactory",\n\t\t\t\t "mail.smtp.socketFactory.fallback":"false",\n\t\t\t\t "mail.smtp.socketFactory.port":"465"\n\t\t]\n\t}\n\tmailConfigExample1.fromAddress="USERAAA <userA@internal.com>"\n\n\tmailConfigExample2 {\n\t\thost = "smtp.gmail.com"\n\t\tport =587\n\t\tusername = "userB@gmail.com"\n\t\tpassword = 'PASSWORD'\n\t\tprops = ["mail.debug":"true",\n\t\t\t\t "mail.smtp.user":"userB@gmail.com",\n\t\t\t\t "mail.smtp.host": "smtp.gmail.com",\n\t\t\t\t "mail.smtp.port": "587",\n\t\t\t\t "mail.smtp.auth": "true",\n\t\t\t\t "mail.smtp.starttls.enable":"true",\n\t\t\t\t "mail.smtp.EnableSSL.enable":"true",\n\t\t\t\t "mail.smtp.socketFactory.class":"javax.net.ssl.SSLSocketFactory",\n\t\t\t\t "mail.smtp.socketFactory.fallback":"false",\n\t\t\t\t "mail.smtp.socketFactory.port":"465"\n\t\t]\n\t}\n\tmailConfigExample2.fromAddress="userBB<userB@gmail.com>"\n\n}\n</code></pre>\n<p><a href=\"https://github.com/vahidhedayati/grails-queuemail-plugin/blob/master/grails-app/controllers/org/grails/plugin/queuemail/QueueTestController.groovy\">QueueTestController</a> used to show some of the examples below:</p>\n<pre><code class=\"language-groovy\">\n //BASIC TEXT\n\t\t\tLong userId = queueMailUserService.currentuser\n\t\t\tdef locale = RequestContextUtils.getLocale(request)\n\t\t\tEmail message = new Email(\n\t\t\t\t\tfrom: config.exampleFrom,\n\t\t\t\t\tto: [config.exampleTo],\n\t\t\t\t\tsubject: 'Subject',\n\t\t\t\t\ttext: 'Testing text message being sent via plugin'\n\t\t\t\t\t//html: params\n\t\t\t).save(flush: true)\n\t\t\tdef queue = queueMailApiService.buildEmail('queueMailExample', userId, locale, message)\n\n\n //HTML TEMPLATE\n\t\t\t//This loads in a template and provides model which is the instance list for template\n\t\t\tdef paramsMap = [:]\n\t\t\tparamsMap.view = "/examples/testTemplate"\n\t\t\tparamsMap.model = [var1: "hello", var2: "there"]\n\t\t\t// Or Like this\n\t\t\t//Map paramsMap = [view:"/examples/testTemplate",model:[var1:"hello", var2:"there"]]\n\n\t\t\tEmail message = new Email(\n\t\t\t\t\tfrom: config.exampleFrom,\n\t\t\t\t\tto: [config.exampleTo],\n\t\t\t\t\tsubject: 'Subject',\n\t\t\t\t\thtml: paramsMap\n\t\t\t)\n\t\t\tif (!message.save(flush: true)) {\n\t\t\t\tlog.error message.errors\n\t\t\t}\n\t\t\tdef queue = queueMailApiService.buildEmail('queueMailExample', userId, locale, message)\n\n\t\t\t//To Many recipients:\n\t\t\tLong userId = queueMailUserService.currentuser\n def locale = RequestContextUtils.getLocale(request)\n List\n Email message = new Email(\n from: config.exampleFrom,\n //EITHER TO CC OR BCC\n to: [config.exampleTo, config.exampleTo, config.exampleTo, config.exampleTo],\n //FOR CC\n //cc:[config.exampleTo, config.exampleTo, config.exampleTo, config.exampleTo],\n //FOR BCC:\n //bcc: [config.exampleTo, config.exampleTo, config.exampleTo, config.exampleTo],\n subject: 'Subject',\n body: "<html>HTML text ${new Date()}</html>"\n )\n /**\n * Above methods will fail to save, if you prefer you can use cleanTo cleanCc or cleanBcc\n * same rules as above you must define one.\n *\n * If this method is used, the bad addresses are silently removed so object will save and\n * only those with a good email address with be emailed (the last 2) in this example\n *\n *\n * if you have port 25 open to make outgoing SMTP connections you could try enabling\n *\n * queuemail.smtpValidation=true\n *\n * This will attempt to check the email address of the recipient from the first MX bound\n * to their email address. If valid then the email address is silently added.\n *\n * This is a pre-delivery confirmation (Experimental)\n */\n\n //message.cleanTo(['aa <aa@aa>','bb','cc','dd <dd@example.com>','ee <ee@example.com>'])\n //message.cleanBcc(['aa <aa@aa>','bb','cc','dd <dd@example.com>','ee <ee@example.com>'])\n //message.cleanCc(['aa <aa@aa>','bb','cc','dd <dd@example.com>','ee <ee@example.com>'])\n if (!message.save(flush:true)) {\n log.error message.errors\n }\n def queue = queueMailApiService.buildEmail(EXAMPLE_SERVICE,userId, locale, message)\n\n</code></pre>\n<p>You store an <code>Email</code> in it's domain class. Then you call <code>buildEmail</code> which</p>\n<p><code>buildEmail(EXAMPLE_SERVICE, userId, locale, message)</code></p>\n<pre><code>queueMailExample=maps up to QueueMailExampleMailingService (you create this) \nuserId=current userId\nlocale=current locale/user locale\nmessage=That email above you just saved\n</code></pre>\n<h2>Configuration for unreliable SMTP services</h2>\n<p>Please visit above configuration links and read through the comments provided. At the very bottom it covers\nhost failures and how to limit / restrict host failures.</p>\n<h2>Binding plugin with your application userbase</h2>\n<p>Feel free to refer to <a href=\"https://github.com/vahidhedayati/grails-queuekit-plugin\">queuekit plugin</a> which may give more\ninsight into some of the additional values not covered such as binding your application with the plugin.\nThis way each user can only view their own email queue and admin or super users can view all as per default screen.\nThe queuekit plugin discusses <code>queuekitUserService</code> change that to <code>queueMailUserService</code> and any reference to how you\noverride it for this plugin.</p>\n<h2>Many services for a given scenario</h2>\n<p>You could have multiple services that have totally different sets of email configurations to pickup and depending on\nyour scenario then traffic the email to use serviceA or serviceB.</p>\n<h2>Interface to queueing system</h2>\n<p>The plugin also provides <code>queueMail/listQueue</code> controller / action that gives you an overview of how your\nemail's are being processed. It provides detailed information as to each emailService triggered and their underlying\nconfiguration status/health.</p>\n<h2>Message errors / Exceptions and configuration activation</h2>\n<p>1.3 introduced <code>enums.MessageExceptions</code> and <code>monitor.ServiceConfigs</code>.\nSMTP providers that trigger an exception depending on exception type can trigger actual provider(itself)\nto become inactive. The most obvious example used is when there is an authentication failure. There is no point\nin giving this provider a 2nd chance to join the pool since it is obviously incorrectly configured.\nAn override feature has been added to the web interface which provides you with option to change a specific configuration limit, active status and MessageException status.\nIf it has failed and you wish to re-activate it - you should remove Message Exception and set active to true.\nThese are dynamic values that are over-written upon application restart.</p>\n<h2>Configuring sendgrid or other API's/mail plugins to work with queuemail plugin</h2>\n<p>Please note this is an example tested and working, whilst this covers sendGrid, this theory could be expanded\nover other mail plugin's or mail api's.</p>\n<p>Added the plugin to test site:</p>\n<pre><code class=\"language-groovy\"> compile 'desirableobjects.grails.plugins:grails-sendgrid:2.0.1'\n</code></pre>\n<p>Configured application.yml</p>\n<pre><code class=\"language-groovy\">sendgrid:\n username: 'myUsername'\n password: 'bigSecret'\n</code></pre>\n<p>A new controller action:</p>\n<pre><code class=\"language-groovy\"> def testSendGrid() {\n String myService='myExample'\n Long userId = queueMailUserService.currentuser\n def locale = RequestContextUtils.getLocale(request)\n Email message = new Email(\n from: "userA <userA@myDomain.com>",\n to: ['userB <userB@gmail.com>'],\n subject: 'Subject-------------------------',\n text: 'Testing text message being sent via plugin'\n //html: params\n ).save(flush: true)\n def queue = queueMailApiService.buildEmail(myService, userId, locale, message)\n flash.message = g.message(code: 'queuemail.reportQueued.label', args: ['TestTextEmail', queue?.id])\n render "all done"\n return\n }\n</code></pre>\n<p><code>MyExampleMailingService</code> enhances or modifies the behaviour of <code>sendMail</code> function\nthat resides in <code>QueueMailBaseService</code> and is what this service extends from.</p>\n<p>My first configured job is <code>'sendGrid': 2,</code>. If you look within <code>sendMail</code> segment below you will notice\n<code>if (sendAccount=='sendGrid') {</code>.\nWhilst it is within the limitation of 2 jobs it will the if statement and use <code>sendGridService.sendMail</code>.\nFeel free to add other if statements and expand on the idea to other third party\nemail plugin's or custom mail api's.\nThe final else should be left as it is since it will return only when it hits a job that no longer matches your defined if statements.\nSo in this example <code>'mailConfigExample2'</code> will hit the else block after 2 email's was sent via <code>sendGrid</code> because\n<code>executor.getSenderCount</code> would mark <code>sendGrid</code> down and return <code>mailConfigExample2</code> for the next email's.</p>\n<pre><code class=\"language-groovy\">\nimport org.grails.plugin.queuemail.EmailQueue\nimport org.grails.plugin.queuemail.QueueMailBaseService\nimport org.grails.plugin.queuemail.enums.MessageExceptions\n\nclass MyExampleMailingService extends QueueMailBaseService {\n\n\tdef sendGridService\n\n\tdef configureMail(executor,EmailQueue queue) {\n\t\tdef jobConfigurations = [\n\t\t\t\t'sendGrid': 2,\n\t\t\t\t'mailConfigExample2': 100,\n\t\t\t]\n\n\t\tsendMail(executor,queue,jobConfigurations,MyExampleMailingService.class)\n\t}\n\t\n\t@Override\n def sendMail(executor,queue,jobConfigurations,Class clazz,MessageExceptions currentException=null) {\n \t\tboolean failed=true\n \t\tboolean resend=false\n \t\tString sendAccount\n \t\tString error=''\n \t\tString code\n \t\tList args\n \t\ttry {\n \t\t\tif (jobConfigurations) {\n \t\t\t\tsendAccount = executor.getSenderCount(clazz, jobConfigurations, queue.id,currentException)\n \t\t\t\tif (sendAccount) {\n \t\t\t\t\tif (sendAccount=='sendGrid') {\n \t\t\t\t\t\tprintln "Sending via sendGrid"\n \t\t\t\t\t\ttry {\n \t\t\t\t\t\t\tsendGridService.sendMail {\n \t\t\t\t\t\t\t\tfrom "${queue.email.from}"\n \t\t\t\t\t\t\t\tqueue.email?.to?.each { t ->\n \t\t\t\t\t\t\t\t\tprintln "sending to ${t}"\n \t\t\t\t\t\t\t\t\tto "${t}"\n \t\t\t\t\t\t\t\t}\n \t\t\t\t\t\t\t\tsubject queue.email.subject+"-- from sendgrid"\n \t\t\t\t\t\t\t\tbody " from sendGrid"\n \t\t\t\t\t\t\t}\n \t\t\t\t\t\t} catch (Exception e) {\n \t\t\t\t\t\t\tprintln "SendGrid had error E: ${e}"\n \t\t\t\t\t\t\tfailed=true\n \t\t\t\t\t\t\tcode='sendgrid.failed'\n \t\t\t\t\t\t}\n \t\t\t\t\t} else {\n \t\t\t\t\t\tprintln "Returning it back to how plugin was doing things"\n \t\t\t\t\t\tqueueMailService.sendEmail(sendAccount,queue)\n \t\t\t\t\t\tfailed=false\n \t\t\t\t\t}\n \t\t\t\t} else {\n \t\t\t\t\tcode = 'queuemail.dailyLimit.label'\n \t\t\t\t\targs = [jobConfigurations]\n \t\t\t\t}\n \t\t\t} else {\n \t\t\t\tcode = 'queuemail.noConfig.label'\n \t\t\t}\n \t\t}catch (e) {\n \t\t\tfailed=true\n \t\t\tString currentError = e.getClass().simpleName\n \t\t\tif (MessageExceptions.values().any{it.toString() == currentError}) {\n \t\t\t\tcurrentException=currentError\n \t\t\t\tdef errors = MessageExceptions.verifyStatus(currentException)\n \t\t\t\tif (errors) {\n \t\t\t\t\tresend=errors.resend\n \t\t\t\t}\n \t\t\t}\n \t\t} finally {\n \t\t\tif (failed) {\n \t\t\t\tactionFailed(executor, queue, jobConfigurations, clazz, sendAccount, error, code, args,resend,currentException)\n \t\t\t}\n \t\t}\n \t}\n}\n</code></pre>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "rabbitmq", |
| "repo": "plugins", |
| "owner": "puneetbehl", |
| "desc": "The RabbitMQ plugin provides integration with the RabbitMQ Messaging System.", |
| "labels": [ |
| "messaging", |
| "rabbitmq" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/grails-rabbitmq/issues", |
| "latestVersion": "2.0.0", |
| "updated": "2016-03-31T13:31:54.773Z", |
| "systemIds": [ |
| "org.grails.plugins:rabbitmq" |
| ], |
| "vcsUrl": "https://github.com/grails-plugins/grails-rabbitmq" |
| }, |
| "documentationUrl": "https://grails-plugins.github.io/grails-rabbitmq/", |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"http://travis-ci.org/grails-plugins/grails-rabbitmq\"><img src=\"https://travis-ci.org/grails-plugins/grails-rabbitmq.svg?branch=master\" alt=\"Build Status\" /></a></p>\n<h1>grails-rabbitmq</h1>\n<p>Grails RabbitMQ Plugin</p>\n<p><a href=\"https://github.com/puneetbehl/rabbitmqDemo.git\">Sample Applicatoin</a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "rabbitmq-native", |
| "repo": "grails-plugins", |
| "owner": "budjb", |
| "desc": "A messaging plugin for Grails using RabbitMQ.\r\n\r\nThis plugin gives application authors a powerful framework to quickly get a scalable messaging solution running quickly.", |
| "labels": [ |
| "messaging", |
| "rabbitmq" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/budjb/grails-rabbitmq-native/issues", |
| "latestVersion": "4.0.0", |
| "updated": "2019-09-18T14:54:18.779Z", |
| "systemIds": [ |
| "org.grails.plugins:rabbitmq-native" |
| ], |
| "vcsUrl": "https://github.com/budjb/grails-rabbitmq-native" |
| }, |
| "documentationUrl": "https://budjb.github.io/grails-rabbitmq-native/", |
| "mavenMetadataUrl": null, |
| "readme": "<div class=\"paragraph\">\n<p>RabbitMQ Native plugin for Grails</p>\n</div>\n<div class=\"paragraph\">\n<p><a href=\"http://budjb.github.io/grails-rabbitmq-native/4.x/latest\">Documentation</a></p>\n</div>" |
| }, |
| { |
| "deprecated": "Source repository is archived.", |
| "bintrayPackage": { |
| "name": "recaptcha", |
| "repo": "plugins", |
| "owner": "iamthechad", |
| "desc": "Grails 3 ReCaptcha and MailHide plugin", |
| "labels": [ |
| "mailhide", |
| "captcha" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/iamthechad/grails3-recaptcha/issues", |
| "latestVersion": "3.2.0", |
| "updated": "2018-05-06T00:50:59.682Z", |
| "systemIds": [ |
| "org.grails.plugins:recaptcha" |
| ], |
| "vcsUrl": "https://github.com/iamthechad/grails3-recaptcha" |
| }, |
| "documentationUrl": "https://iamthechad.github.io/grails3-recaptcha/", |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://bintray.com/iamthechad/plugins/recaptcha/3.2.0/link\"><img src=\"https://api.bintray.com/packages/iamthechad/plugins/recaptcha/images/download.svg?version=3.2.0\" alt=\"Download\" /></a>\n<a href=\"https://travis-ci.org/iamthechad/grails3-recaptcha\"><img src=\"https://travis-ci.org/iamthechad/grails3-recaptcha.svg\" alt=\"Build Status\" /></a>\n<a href=\"https://coveralls.io/github/iamthechad/grails3-recaptcha\"><img src=\"https://coveralls.io/repos/iamthechad/grails3-recaptcha/badge.svg?service=github\" alt=\"Coverage Status\" /></a>\n<a href=\"https://snyk.io/test/github/iamthechad/grails3-recaptcha\"><img src=\"https://snyk.io/test/github/iamthechad/grails3-recaptcha/badge.svg\" alt=\"Known Vulnerabilities\" /></a>\n<a href=\"http://www.apache.org/licenses/LICENSE-2.0.html\"><img src=\"http://img.shields.io/:license-apache-blue.svg\" alt=\"License\" /></a>\n<img src=\"https://img.shields.io/maintenance/yes/2019\" alt=\"Maintenance\" />\n<a href=\"https://github.com/badges/badgerbadgerbadger\"><img src=\"http://img.shields.io/:badges-7/7-ff6799.svg\" alt=\"Badges\" /></a></p>\n<!-- START doctoc generated TOC please keep comment here to allow auto update -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n<p><strong>Table of Contents</strong> <em>generated with <a href=\"https://github.com/thlorenz/doctoc\">DocToc</a></em></p>\n<ul>\n<li><a href=\"#introduction\">Introduction</a></li>\n<li><a href=\"#installation\">Installation</a>\n<ul>\n<li><a href=\"#configuration\">Configuration</a></li>\n<li><a href=\"#externalized-configuration\">Externalized Configuration</a></li>\n</ul>\n</li>\n<li><a href=\"#usage---recaptcha\">Usage - ReCaptcha</a>\n<ul>\n<li><a href=\"#edit-the-configuration\">Edit the Configuration</a>\n<ul>\n<li><a href=\"#proxy-server-configuration\">Proxy Server Configuration</a></li>\n<li><a href=\"#timeout-configuration\">Timeout Configuration</a></li>\n</ul>\n</li>\n<li><a href=\"#use-the-tag-library\">Use the Tag Library</a>\n<ul>\n<li><a href=\"#recaptchaifenabled\"><code><recaptcha:ifEnabled></code></a></li>\n<li><a href=\"#recaptchaifdisabled\"><code><recaptcha:ifDisabled></code></a></li>\n<li><a href=\"#recaptcharecaptcha\"><code><recaptcha:recaptcha></code></a></li>\n<li><a href=\"#recaptchascript\"><code><recaptcha:script></code></a></li>\n<li><a href=\"#recaptcharecaptchaexplicit\"><code><recaptcha:recaptchaExplicit></code></a></li>\n<li><a href=\"#recaptcharenderparameters\"><code><recaptcha:renderParameters></code></a></li>\n<li><a href=\"#recaptchaiffailed\"><code><recaptcha:ifFailed></code></a></li>\n</ul>\n</li>\n<li><a href=\"#verify-the-captcha\">Verify the Captcha</a></li>\n<li><a href=\"#examples\">Examples</a>\n<ul>\n<li><a href=\"#tag-usage-for-automatic-rendering\">Tag Usage for Automatic Rendering</a></li>\n<li><a href=\"#tag-usage-for-explicit-rendering\">Tag Usage for Explicit Rendering</a></li>\n<li><a href=\"#tag-usage-with-separate-script\">Tag Usage with Separate Script</a></li>\n<li><a href=\"#customizing-the-language\">Customizing the Language</a></li>\n<li><a href=\"#verify-user-input\">Verify User Input</a></li>\n<li><a href=\"#testing\">Testing</a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li><a href=\"#contributing\">Contributing</a></li>\n<li><a href=\"#suggestions-or-comments\">Suggestions or Comments</a></li>\n</ul>\n<!-- END doctoc generated TOC please keep comment here to allow auto update -->\n<h1>Introduction</h1>\n<p>This plugin is designed to make using the ReCaptcha service within Grails 3 easy. In order to use this plugin, you must have a ReCaptcha account, available from <a href=\"http://www.google.com/recaptcha\">http://www.google.com/recaptcha</a>.</p>\n<h1>Installation</h1>\n<p>Add the following to your <code>build.gradle</code></p>\n<pre><code>compile "org.grails.plugins:recaptcha:3.2.0"\n</code></pre>\n<h2>Configuration</h2>\n<p>Add the following to your application's <code>application.yml</code> file:</p>\n<pre><code>recaptcha:\n publicKey: "your public key"\n privateKey: "your private key"\n includeScript: true\n includeNoScript: true\n</code></pre>\n<p>These configurations can also be placed at environment-specific locations in the configuration:</p>\n<pre><code>environments:\n development:\n recaptcha:\n enabled: false\n production:\n recaptcha:\n enabled: true\n</code></pre>\n<h2>Externalized Configuration</h2>\n<p>See the Grails docs for examples of using externalized configuration files. The ReCaptcha config can be externalized as\nthe <code>.groovy</code> file (easiest), or it can be converted into a Java <code>.properties</code> file.</p>\n<h1>Usage - ReCaptcha</h1>\n<p>The plugin is simple to use. In order to use it, there are four basic steps:</p>\n<h2>Edit the Configuration</h2>\n<p>The configuration values are pretty self-explanatory, and match with values used by the ReCaptcha service. You must enter your public and private ReCaptcha keys, or errors will be thrown when trying to display a captcha.</p>\n<h3>Proxy Server Configuration</h3>\n<p>If your server needs to connect through a proxy to the ReCaptcha service, add the following to the ReCaptcha configuration.</p>\n<pre><code>recaptcha:\n\tproxy:\n \tserver: "" // IP or hostname of proxy server\n \tport: "" // Proxy server port, defaults to 80\n \tusername: "" // Optional username if proxy requires authentication\n \tpassword: "" // Optional password if proxy requires authentication\n</code></pre>\n<p>Only the <code>server</code> property is required. The <code>port</code> will default to <code>80</code> if not specified. The <code>username</code> and <code>password</code> properties need to be specified only when the proxy requires authentication.</p>\n<p>Like other configurations, this can be placed at the top-level <code>recaptcha</code> entry, or it can be specified on a per-environment basis.</p>\n<h3>Timeout Configuration</h3>\n<p>If there are issues connecting to Google for verifying the captcha, some of the network timeouts can be changed.</p>\n<pre><code>recaptcha:\n timeoutConfig:\n connectTimeout: 10000 // Timeout for making the network connection in millis. Defaults to 10000\n readTimeout: 1000 // Timeout for waiting on the network response in millis. Defaults to 1000\n</code></pre>\n<p><code>connectTimeout</code> and <code>readTimeout</code> can be specified together or independently of each other.</p>\n<p>Like other configurations, this can be placed at the top-level <code>recaptcha</code> entry, or it can be specified on a per-environment basis.</p>\n<h2>Use the Tag Library</h2>\n<h3><code><recaptcha:ifEnabled></code></h3>\n<p>This tag is a simple utility that will render its contents if the captcha is enabled in the configuration.</p>\n<h3><code><recaptcha:ifDisabled></code></h3>\n<p>This tag is a simple utility that will render its contents if the captcha is disabled in the configuration.</p>\n<h3><code><recaptcha:recaptcha></code></h3>\n<p>This tag is responsible for generating the correct HTML output to display the captcha. It supports the following attributes:</p>\n<ul>\n<li><code>theme</code> - Can be one of <code>dark</code> or <code>light</code>. Defaults to <code>light</code>.</li>\n<li><code>size</code> - Can be one of <code>compact</code> or <code>normal</code>. Defaults to <code>normal</code>.</li>\n<li><code>lang</code> - Can be any one of the supported ReCaptcha language codes. See the <a href=\"https://developers.google.com/recaptcha/docs/language\">list of supported language codes</a>.</li>\n<li><code>tabindex</code> - Optional tabindex of the widget.</li>\n<li><code>type</code> - Type of captcha to display if the checkbox is not sufficient. Can be one of <code>image</code> or <code>audio</code>. Defaults to <code>image</code>.</li>\n<li><code>successCallback</code> - Optional function to be called when the user submits a successful response.</li>\n<li><code>expiredCallback</code> - Optional function to be called when the successful response has expired.</li>\n<li><code>includeScript</code> - If <code>includeScript</code> is set to <code>false</code> at either the global or tag level, the <code><script></code> tag required by ReCaptcha will not be included in the generated HTML. The <code><recaptcha:script></code> tag is also required in this scenario.</li>\n</ul>\n<p>See the <a href=\"https://developers.google.com/recaptcha/docs/display#config\">ReCaptcha Client Guide</a> for more details.</p>\n<h3><code><recaptcha:script></code></h3>\n<p>This tag will render the required <code><script></code> tag. Combine this with the global or tag-level <code>includeScript=false</code> setting to allow putting the <code><script></code> tag elsewhere in your markup. This tag also supports the "lang" attribute. <strong>This does not work in the <code><head></code> section of the page</strong></p>\n<h3><code><recaptcha:recaptchaExplicit></code></h3>\n<p>This tag is responsible for generating the correct HTML output to support explicit display and usage of the captcha. It supports the following attributes:</p>\n<ul>\n<li><code>lang</code> - Can be any one of the supported ReCaptcha language codes. See the <a href=\"https://developers.google.com/recaptcha/docs/language\">list of supported language codes</a>.</li>\n<li><code>loadCallback</code> - The JavaScript function to be called when all dependencies have loaded. This function is usually responsible for rendering the captcha.</li>\n</ul>\n<p>For more information about explicit mode captchas, see <a href=\"https://developers.google.com/recaptcha/docs/display#explicit_render\">the ReCaptcha documentation</a>.</p>\n<h3><code><recaptcha:renderParameters></code></h3>\n<p>This utility tag will generate the JSON string used as a parameter to the <code>grecaptcha.render()</code> function. It supports the following attributes:</p>\n<ul>\n<li><code>theme</code> - Can be one of <code>dark</code> or <code>light</code>. Defaults to <code>light</code>.</li>\n<li><code>size</code> - Can be one of <code>compact</code> or <code>normal</code>. Defaults to <code>normal</code>.</li>\n<li><code>tabindex</code> - Optional tabindex of the widget.</li>\n<li><code>type</code> - Type of captcha to display if the checkbox is not sufficient. Can be one of <code>image</code> or <code>audio</code>. Defaults to <code>image</code>.</li>\n<li><code>successCallback</code> - Optional function to be called when the user submits a successful response.</li>\n<li><code>expiredCallback</code> - Optional function to be called when the successful response has expired.</li>\n</ul>\n<p>See the <a href=\"https://developers.google.com/recaptcha/docs/display#config\">ReCaptcha Client Guide</a> for more details.</p>\n<h3><code><recaptcha:ifFailed></code></h3>\n<p>This tag will render its contents if the previous validation failed.</p>\n<h2>Verify the Captcha</h2>\n<p>In your controller, call <code>recaptchaService.verifyAnswer(session, request.getRemoteAddr(), params)</code> to verify the answer provided by the user. This method will return true or false. Also note that <code>verifyAnswer</code> will return <code>true</code> if the plugin has been disabled in the configuration - this means you won't have to change your controller.</p>\n<h2>Examples</h2>\n<p>Here's a simple example pulled from an account creation application.</p>\n<h3>Tag Usage for Automatic Rendering</h3>\n<p>This is the most common usage scenario.</p>\n<p>In our GSP, we add the code to show the captcha:</p>\n<pre><code><recaptcha:ifEnabled>\n <recaptcha:recaptcha theme="dark"/>\n</recaptcha:ifEnabled>\n</code></pre>\n<p>In this example, we're using ReCaptcha's <code>dark</code> theme. Leaving out the <code>theme</code> attribute will default the captcha to the <code>light</code> theme.</p>\n<h3>Tag Usage for Explicit Rendering</h3>\n<p>In our GSP, we add code like the following:</p>\n<pre><code><script type="text/javascript">\n var onloadCallback = function() {\n grecaptcha.render('html_element', <recaptcha:renderParameters theme="dark" type="audio" tabindex="2"/>);\n };\n</script>\n<g:form action="myAction" method="post">\n <recaptcha:ifEnabled>\n <recaptcha:recaptchaExplicit loadCallback="onloadCallback"/>\n <div id="html_element"></div>\n </recaptcha:ifEnabled>\n <br/>\n <g:submitButton name="submit"/>\n</g:form>\n</code></pre>\n<p>In this example, we're using ReCaptcha's <code>dark</code> theme, with an <code>audio</code> captcha and a <code>tabindex</code> of 2.</p>\n<p>For more information about explicit mode captchas, see <a href=\"https://developers.google.com/recaptcha/docs/display#explicit_render\">the ReCaptcha documentation</a>.</p>\n<h3>Tag Usage with Separate Script</h3>\n<p>Set the <code>includeScript</code> value to <code>false</code> either at the tag level (below), or in the global ReCaptcha settings.</p>\n<pre><code><body>\n <g:form action="validateNormal" method="post" >\n <recaptcha:ifEnabled>\n <recaptcha:recaptcha includeScript="false"/>\n </recaptcha:ifEnabled>\n <br/>\n <g:submitButton name="submit"/>\n </g:form>\n <recaptcha:script/>\n</body>\n</code></pre>\n<p>This will cause the <code><script src="https://www.google.com/recaptcha/api.js?" async="" defer=""></script></code> tag to be output separately at the bottom of the document instead of just before the <code><div></code> containing the captcha.</p>\n<h3>Customizing the Language</h3>\n<p>If you want to change the language your captcha uses, set <code>lang = "someLang"</code> in the <code><recaptcha:recaptcha></code> or <code><recaptcha:recaptchaExplcit></code> tags.</p>\n<p>See <a href=\"https://developers.google.com/recaptcha/docs/language\">ReCaptcha Language Codes</a> for available languages.</p>\n<h3>Verify User Input</h3>\n<p>Here's an abbreviated controller class that verifies the captcha value when a new user is saved:</p>\n<pre><code>import com.megatome.grails.RecaptchaService\nclass UserController {\n\tRecaptchaService recaptchaService\n\n\tdef save = {\n\t\tdef user = new User(params)\n\t\t...other validation...\n\t\tdef recaptchaOK = true\n\t\tif (!recaptchaService.verifyAnswer(session, request.getRemoteAddr(), params)) {\n\t\t\trecaptchaOK = false\n\t\t}\n\t\tif(!user.hasErrors() && recaptchaOK && user.save()) {\n\t\t\trecaptchaService.cleanUp(session)\n\t\t\t...other account creation acivities...\n\t\t\trender(view:'showConfirmation',model:[user:user])\n\t\t}\n\t\telse {\n\t\t\trender(view:'create',model:[user:user])\n\t\t}\n\t}\n}\n</code></pre>\n<h3>Testing</h3>\n<p>You can look at the test cases in the plugin itself, or you can implement something similar to:</p>\n<pre><code>private void buildAndCheckAnswer(String postText, boolean expectedValid) {\n def stub = new StubFor(Post.class)\n stub.demand.hasProperty(3..3) { true }\n stub.demand.setUrl() {}\n stub.demand.setProxy() {}\n stub.demand.getQueryParams(3..3) { new QueryParams(null) }\n stub.demand.getResponse() { postText == null ? null : new JsonSlurper().parseText(postText) }\n\n stub.use {\n def response = r.checkAnswer("123.123.123.123", "response")\n\n assert response == expectedValid\n }\n}\n</code></pre>\n<p>The <code>postText</code> parameter represents the response from the ReCaptcha server. Here are examples of simulating success and failure results:</p>\n<pre><code>when:"A successful response message"\ndef answer = """{ "success": true }"""\n\nthen:\nbuildAndCheckAnswer(answer, true)\n\nwhen:"A failure response message"\nanswer = """{ "success": false }"""\n\nthen:\nbuildAndCheckAnswer(answer, false)\n</code></pre>\n<h1>Contributing</h1>\n<p>See the <a href=\"./CONTRIBUTING.md\">contribution guidelines</a>.</p>\n<h1>Suggestions or Comments</h1>\n<p>Feel free to submit questions through GitHub or to StackOverflow.</p>\n<p>Alternatively you can contact me directly - cjohnston at megatome dot com</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "recaptcha-spring-security", |
| "repo": "grails-plugins", |
| "owner": "snimavat", |
| "desc": "Recaptcha support for Spring security", |
| "labels": [ |
| "security", |
| "spring-security", |
| "captcha" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/snimavat/recaptcha-spring-security/issues", |
| "latestVersion": "3.0.1", |
| "updated": "2017-03-02T10:11:50.103Z", |
| "systemIds": [ |
| "org.grails.plugins:recaptcha-spring-security" |
| ], |
| "vcsUrl": "https://github.com/snimavat/recaptcha-spring-security" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>recaptcha-spring-security</h1>\n<p>Grails: Using recaptcha with spring security core for brute force defender</p>\n<p>based in: <a href=\"https://github.com/grygoriy/bruteforcedefender\">Brute Force Defender</a></p>\n<h1>Requirements</h1>\n<ol>\n<li>Grails 2.3.2+</li>\n<li><a href=\"http://grails.org/plugin/spring-security-core\">Spring Security Core Plugin</a> (2.0-RC3+)</li>\n<li><a href=\"http://grails.org/plugin/recaptcha\">ReCaptcha Plugin</a> (0.6.9+)</li>\n</ol>\n<h1>Installation</h1>\n<ol>\n<li>\n<p>clone the repository: git clone https://github.com/rpalcolea/recaptcha-spring-security.git</p>\n</li>\n<li>\n<p>Enter to the repository via command line.</p>\n</li>\n<li>\n<p>package the plugin: grails package-plugin</p>\n</li>\n</ol>\n<h1>Configuration</h1>\n<h2>Config.groovy</h2>\n<p>Configure <a href=\"http://plugins.grails.org/plugin/iamthechad/recaptcha#configuration\">recaptcha plugin</a></p>\n<p>And then Add the following lines to your Grails Config.groovy file:</p>\n<pre><code>bruteforcedefender {\n\ttime = 5\n\tallowedNumberOfAttempts = 3\n}\n</code></pre>\n<p>time = minutes mantaining failed attempts allowed\nNumberOfAttempts = number of failed attempts before showing the recaptcha widget.</p>\n<h1>Adding the recaptcha to your auth view</h1>\n<p>Open your auth.gsp (/grails-app/views/login/auth.gsp) and add the next line wherever you want to render the recaptcha after the attempts.</p>\n<pre><code> <g:recaptchaLogin/>\n</code></pre>\n<p>Note: The plugin depends on spring security authentication events and so it sets grails.plugin.springsecurity.useSecurityEventListener = true</p>\n<h1>Extras</h1>\n<p>Thanks to <a href=\"http://www.vincoorbis.com\">Vinco Orbis</a> and <a href=\"https://github.com/burtbeckwith\">Burt Beckwith</a></p>\n<p>Thanks to JetBrains for Awesome IntelliJ Idea</p>\n<img src=\"https://cdn.rawgit.com/snimavat/repo-bin/master/assets/jetbrains/icon_IntelliJIDEA.svg\" width=\"48\">\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "grails-redis", |
| "repo": "grails", |
| "owner": "grails", |
| "desc": "Grails Redis plugin", |
| "labels": [ |
| "redis" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/grails-redis/issues", |
| "latestVersion": "4.0.1", |
| "updated": "2023-12-20T15:58:07.000Z", |
| "systemIds": [ |
| "org.grails.plugins:grails-redis" |
| ], |
| "vcsUrl": "https://github.com/grails/grails-redis" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/grails/plugins/grails-redis/maven-metadata.xml", |
| "readme": "<p><a href=\"https://travis-ci.org/grails-plugins/grails-redis\"><img src=\"https://travis-ci.org/grails-plugins/grails-redis.svg\" alt=\"Build Status\" /></a></p>\n<h1>Grails 3</h1>\n<p>The <a href=\"https://bintray.com/ctoestreich/grails-plugins/redis\">2.X version of the plugin</a> is compatible only with grails 3.</p>\n<h1>Grails Redis Plugin</h1>\n<p>For integration between <a href=\"http://redis.io\">Redis</a> and Grails GORM layer, see the <a href=\"http://grails.github.com/inconsequential/redis/\">Redis GORM plugin</a>.</p>\n<p>That plugin was originally called "redis" (the name of this plugin), but it has since been refactored to "redis-gorm" and now relies on this plugin for connectivity.</p>\n<h2>What is Redis?</h2>\n<p>The best definition of Redis that I've heard is that it is a "collection of data structures exposed over the network".</p>\n<p>Redis is an <a href=\"http://redis.io/topics/benchmarks\">insanely fast</a> key/value store, in some ways similar to <a href=\"http://memcached.org/\">memcached</a>, but the values it stores aren't just dumb blobs of data. Redis values are data structures like <a href=\"http://redis.io/commands#string\">strings</a>, <a href=\"http://redis.io/commands#list\">lists</a>, <a href=\"http://redis.io/commands#hash\">hash maps</a>, <a href=\"http://redis.io/commands#set\">sets</a>, and <a href=\"http://redis.io/commands#sorted_set\">sorted sets</a>. Redis also can act as a lightweight pub/sub or message queueing system.</p>\n<p>Redis is used in production today by a <a href=\"http://redis.io/topics/whos-using-redis\">number of very popular</a> websites including Craigslist, StackOverflow, GitHub, The Guardian, and Digg.</p>\n<p>It's commonly lumped in with other NoSQL technologies and is commonly used as a caching layer. It has some similarities to Memcached or Tokyo Tyrant. Because Redis provides network-available data structures, it's very flexible and it's able to solve all kinds of problems. The creator of Redis, Salvatore Sanfilippo, has a nice post on his blog showing <a href=\"http://antirez.com/post/take-advantage-of-redis-adding-it-to-your-stack.html\">how to take advantage of Redis by just adding it to your stack</a>. With the Grails Redis plugin, adding Redis to your grails app is very easy.</p>\n<p>I've created an <a href=\"http://naleid.com/blog/2010/12/28/intro-to-using-redis-with-groovy/\">introduction to Redis using groovy</a> that shows you how to install redis and use some basic groovy commands. There is also a <a href=\"http://naleid.com/blog/2011/06/27/redis-groovy-and-grails-presentation-at-gr8conf-2011-and-gum/\">presentation that I gave at gr8conf 2011</a>.</p>\n<p>The official <a href=\"http://redis.io\">Redis documentation</a> is fantastic and includes a comprensive <a href=\"http://redis.io/commands\">list of Redis commands</a>, each command web page also has an embedded REPL that lets you test out the command against a live Redis server.</p>\n<h1>What is Jedis?</h1>\n<p><a href=\"https://github.com/xetorthio/jedis/wiki\">Jedis</a> is the Java Redis connection library that the Grails Redis plugin uses. It's actively maintained, very fast, and doesn't try to do anything too clever. One of the nice things about it is that it doesn't try to munge around with the Redis command names, but follows them as closely as possible. This means that for almost all commands, the <a href=\"http://redis.io/commands\">Redis command</a> documentation can also be used to understand how to use the Jedis connection objects. You don't need to worry about translating the Redis documentation into Jedis commands.</p>\n<h2>Installation</h2>\n<pre><code>grails install-plugin redis\n</code></pre>\n<p>Out of the box, the plugin expects that Redis is running on <code>localhost:6379</code>. You can modify this (as well as any other pool config options) by adding a stanza like this to your <code>grails-app/conf/Config.groovy</code> file:</p>\n<pre><code>grails {\n redis {\n poolConfig {\n // jedis pool specific tweaks here, see jedis docs & src\n // ex: testWhileIdle = true\n }\n timeout = 2000 //default in milliseconds\n password = "somepassword" //defaults to no password\n useSSL = false //or true to use SSL\n\n // requires either host & port combo, or a sentinels and masterName combo\n\n // use a single redis server (use only if nore using sentinel cluster)\n port = 6379\n host = "localhost"\n database = 5 // set default database to 5\n\n // use redis-sentinel cluster as opposed to a single redis server (use only if not use host/port)\n sentinels = [ "host1:6379", "host2:6379", "host3:6379" ] // list of sentinel instance host/ports\n masterName = "mymaster" // the name of a master the sentinel cluster is configured to monitor\n }\n\n}\n</code></pre>\n<p>The poolConfig section will let you tweak any of the <a href=\"https://github.com/xetorthio/jedis/blob/master/src/main/java/redis/clients/jedis/JedisPoolConfig.java\">setter values made available by the JedisPoolConfig</a>. It implements the Apache Commons <a href=\"http://commons.apache.org/pool/apidocs/org/apache/commons/pool/impl/GenericObjectPool.html\">GenericObjectPool</a>.</p>\n<p>NOTE: Please see <a href=\"http://redis.io/topics/sentinel\">Redis Sentinel - Documentation</a> for more info on using redis-sentinel for high availability</p>\n<h2>Plugin Usage</h2>\n<h3>RedisService Bean</h3>\n<pre><code>def redisService\n</code></pre>\n<p>The <code>redisService</code> bean wraps the pool connection. It has a number of caching/memoization helper functions, template methods, and basic Redis commands, it will be your primary interface to Redis.</p>\n<p>The service overrides <code>propertyMissing</code> and <code>methodMissing</code> to delegate any missing requests to a Redis connection object. This means that any method that you'd normally call on a Redis connection object can be called directly on <code>redisService</code>.</p>\n<pre><code>// overrides propertyMissing and methodMissing to delegate to redis\ndef redisService\n\nredisService.foo = "bar"\nassert "bar" == redisService.foo\n\nredisService.sadd("months", "february")\nassert true == redisService.sismember("months", "february")\n</code></pre>\n<p>It also provides a template method called <code>withRedis</code> that takes a closure as a parameter. It passes a Jedis connection object to Redis into the closure. The template method automatically gets an object out of the pool and ensures that it gets returned to the pool after the closure finishes (even if there's an error).</p>\n<pre><code>redisService.withRedis { Jedis redis ->\n redis.set("foo", "bar")\n}\n</code></pre>\n<p>The advantage to calling <code>withRedis</code> rather than just calling methods directly on <code>redisService</code> is that multiple commands will only use a single connection instance, rather than one per command.</p>\n<p>Redis also allows you to pipeline commands. Pipelining allows you to quickly send commands to Redis without waiting for a response. When the pipeline is executed, it returns a Result object, which works like a <code>Future</code> to give you the results of the pipeline. See the <a href=\"https://github.com/xetorthio/jedis/wiki\">Jedis</a> documentation on pipelining for more details. It works pretty much like the <code>withRedis</code> template does:</p>\n<pre><code>redisService.withPipeline { Pipeline pipeline ->\n pipeline.set("foo", "bar")\n}\n</code></pre>\n<p>Redis has the notion of transactions, but it's not exactly the same as a database transaction. Redis transactions guarantee that all of the commands in the transaction will be executed as an atomic unit. Because Redis is single threaded, you're guaranteed to execute atomically and have a known state throughout the transaction. Redis does not support rolling back modifications that happen during a transaction.</p>\n<p>The <code>withTransaction</code> template method automatically opens and closes the transaction for you. If the closure doesn't throw and exception, it will tell Redis to execute the transaction</p>\n<pre><code>redisService.withTransaction { Transaction transaction ->\n transaction.set("foo", "bar")\n}\n</code></pre>\n<h3>Memoization</h3>\n<p>Memoization is a write-through caching technique. The plugin gives a number of methods that take a key name, and a closure as parameters. These methods first check Redis to see if the key exists. If it does, it returns the value of the key and does not execute the closure. If it does not exist in Redis, it executes the closure and saves the result in Redis under the key. Subsequent calls will then be served the cached value from Redis rather than recalculating.</p>\n<p>This technique is very useful for caching values that are frequently requested but expensive to calculate.</p>\n<p>As of version 1.2 you may also use the new memoize annotations. See the Memoization Annotation section for usage and examples.</p>\n<p>There are methods for the basic Redis data types:</p>\n<h3>String Memoization</h3>\n<pre><code>redisService.memoize("user:$userId:helloMessage") {\n // expensive to calculate method that returns a String\n "Hello ${security.currentLoggedInUser().firstName}"\n}\n</code></pre>\n<p>By default, the key/value will be cached forever in Redis, you can ensure that the key is refreshed either by deleting the key from Redis, making the key include a date or timestamp, or by using the optional <code>expire</code> parameter, the value is the number of seconds before Redis should expire the key:</p>\n<pre><code>def ONE_HOUR = 3600\nredisService.memoize("user:$userId:helloMessage", [expire: ONE_HOUR]) {\n """\n Hello ${security.currentLoggedInUser().firstName.\n The temperature this hour is ${currentTemperature()}\n """\n}\n</code></pre>\n<h3>Domain Object Memoization</h3>\n<p>You can memoize a single domain object with redis. It will cache the ID of the domain object returned from the closure and on subsequent cache hits will return a proxy domain object using grails <code>DomainObject.load(cachedId)</code>.</p>\n<pre><code>String key = "user:42:favorite:author"\nAuthor author = redisService.memoizeDomainObject(Author, key) {\n Author author = ... // expensive method to calculate user 42's favorite author...\n return author\n}\n</code></pre>\n<p>Now that you have the proxy object for the Author, you can do queries with it without actually having to hydrate the object (and anything it eagerly loads):</p>\n<pre><code>def recommendedBooks = Book.findByAuthor(author)\n</code></pre>\n<p>The object has the id field populated, but the remaining fields are lazily loaded only if their values are requested, so you can still do:</p>\n<pre><code>println author.name\n</code></pre>\n<p>To actually print out the name of the author.</p>\n<h3>Domain List Memoization</h3>\n<p>You can also memoize a list of domain object identifiers. It doesn't cache the entire domain object, just the database IDs of the domain objects in a returned list.</p>\n<p>This allows you to still grab the freshest objects from the database, but not repeatedly create an expensive list. This could be a big database query that joins a bunch of tables. Or some other process that does additional filtering based on selections the user has made in the UI. Something ephemeral for that session or user, that you don't want to persist, but need to be able to react to.</p>\n<pre><code>def key = "user:$id:friends-books-user-does-not-own"\n\nredisService.memoizeDomainList(Book, key, ONE_HOUR) { redis ->\n // expensive process to calculate all friend\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffds books and filter out books\n // that the user already owns, this stores the list of determined Book IDs\n // in Redis, but hydrates the Book objects from the DB\n}\n</code></pre>\n<h3>Other Memoization Methods</h3>\n<p>There are other memoization methods that the plugin provides, check out the <a href=\"https://github.com/grails-plugins/grails-redis/blob/master/grails-app/services/grails/plugin/redis/RedisService.groovy\">RedisService.groovy</a> and the plugin tests for the exhaustive list.</p>\n<pre><code>// Redis Hash memoize methods\n\nredisService.memoizeHash("saved-hash") { return [foo: "bar"] }\n\nredisService.memoizeHashField("saved-hash", "foo") { return "bar" }\n\n// Redis List memoize method\nredisService.memoizeList("saved-list") { return ["foo", "bar", "baz"] }\n\n// Redis Set memoize method\nredisService.memoizeSet("saved-set") { return ["foo", "bar", "baz"] as Set }\n\n// Redis Sorted Set memoize method\nredisService.memoizeScore("saved-sorted-set", "set-item") { return score }\n</code></pre>\n<h3>Other Methods</h3>\n<p>The plugin also provides a few utility methods such as:</p>\n<pre><code>redisService.flushDB() // dangerous!!!! should probably only be used for test cleanup\n\n// deletes all keys in the database matching a pattern, this is fairly expensive\n// as it uses the <code>keys</code> operation. If you're doing this a lot and\n// have many keys in redis, you should be aggregating your own set of keys that\n// you'll later want to delete\nredisService.deleteKeysWithPattern("key:pattern:*")\n</code></pre>\n<h3>Redis Pool Bean</h3>\n<p>You can have direct access to the pool of Redis connection objects by injecting <code>redisPool</code> into your code. Normally, you won't want to directly work with the pool, and instead interact with the <code>redisService</code> bean, but you have the option to manually work with the pool if desired.</p>\n<pre><code>def redisPool\n</code></pre>\n<h3>Redis Taglib</h3>\n<p>The <code>redis:memoize</code> TagLib lets you leverage memoization within your GSP files. Wrap it around any expensive to generate text and it will cache it and quickly serve it from Redis.</p>\n<pre><code><redis:memoize key="mykey" expire="3600">\n <!--\n insert expensive to generate GSP content here\n\n taglib body will be executed once, subsequent calls\n will pull from redis till the key expires\n -->\n <div id='header'>\n ... expensive header stuff here that can be cached ...\n </div>\n</redis:memoize>\n</code></pre>\n<h3>Multiple Redis Servers</h3>\n<p>If you are using multiple redis servers in your environment which are NOT clustered and would like to perform discrete operations on them seperately from a single application, you can accomplish that by by adding some configuration to your application.</p>\n<p>The configuration block for redis accepts the following connections block parameters.</p>\n<p>Config.groovy</p>\n<pre><code class=\"language-groovy\">grails {\n redis {\n poolConfig {\n // pool specific tweaks here\n // for parms see https://github.com/xetorthio/jedis/blob/master/src/main/java/redis/clients/jedis/JedisPoolConfig.java\n // numTestsPerEvictionRun = 4\n }\n\n // requires either host & port combo, or a sentinels and masterName combo\n\n // use a single redis server (use only if nore using sentinel cluster)\n port = 6379\n host = "localhost"\n\n // use redis-sentinel cluster as opposed to a single redis server (use only if not use host/port)\n sentinels = [ "host1:6379", "host2:6379", "host3:6379" ] // list of sentinel instance host/ports\n masterName = "mymaster" // the name of a master the sentinel cluster is configured to monitor\n\n connections {\n cache {\n poolConfig {\n // pool specific tweaks here\n // for parms see https://github.com/xetorthio/jedis/blob/master/src/main/java/redis/clients/jedis/JedisPoolConfig.java\n // numTestsPerEvictionRun = 4\n }\n\n // requires either host & port combo, or a sentinels and masterName combo\n\n // use a single redis server (use only if nore using sentinel cluster)\n port = 6380\n host = "localhost"\n\n // use redis-sentinel cluster as opposed to a single redis server (use only if not use host/port)\n sentinels = [ "host1:6380", "host2:6380", "host3:6380" ] // list of sentinel instance host/ports\n masterName = "cache" // the name of a master the sentinel cluster is configured to monitor\n }\n search {\n poolConfig {\n // pool specific tweaks here\n // for parms see https://github.com/xetorthio/jedis/blob/master/src/main/java/redis/clients/jedis/JedisPoolConfig.java\n // numTestsPerEvictionRun = 4\n }\n\n // requires either host & port combo, or a sentinels and masterName combo\n\n // use a single redis server (use only if nore using sentinel cluster)\n port = 6381\n host = "localhost"\n\n // use redis-sentinel cluster as opposed to a single redis server (use only if not use host/port)\n sentinels = [ "host1:6381", "host2:6381", "host3:6381" ] // list of sentinel instance host/ports\n masterName = "search" // the name of a master the sentinel cluster is configured to monitor\n }\n }\n }\n}\n</code></pre>\n<p>The standard config block for the default connection has not changed. The new configuration is under the <code>connections</code> block. You will need to name your connections ('cache' and 'search' in the above block). The names must be unique.</p>\n<p>A new service bean will be wired in addition to the default <code>redisService</code> bean with the capitalized connection name appended to it. For example the above two connections would create a <code>redisServiceCache</code> and <code>redisServiceSearch</code> bean you can reference from your application code. If desired, you can also access the connection-specific <code>redisPool</code> beans that are created using the same naming convention, in this example they would be <code>redisPoolCache</code> and <code>redisPoolSearch</code>.</p>\n<p>In addition to the newly wired beans, you may also choose to continue using the standard <code>redisService</code> bean and simply refer to the connections by name when invoking targets on the service via <code>redisService.withConnection('cache').withRedis{...}</code> or <code>redisService.withConnection('search').memoize(key){...}</code>.</p>\n<p><em>Note: It is up to you if you prefer using the main <code>redisService</code> bean and the <code>withConnection</code> method or if you want to inject the additional service beans. The end result is the same and the withConnection is simply a pass through to the newly created beans.</em></p>\n<pre><code class=\"language-groovy\">class FooService {\n\n def redisService\n // custom created beans for each connection, you can use these or just use the `withConnection` method\n // both methods are demonstrated below for example purposes, but you'd like choose one method or the other\n def redisServiceCache\n def redisServiceSearch\n\n def doWork(){\n redisService.withRedis { Jedis redis ->\n redis.set("foo", "bar")\n }\n\n redisService.withConnection('cache').withTransaction { Jedis redis ->\n redis.set("foo", "bar")\n }\n\n redisServiceSearch.withPipeline { Jedis redis ->\n redis.set("foo", "bar")\n }\n\n redisServiceCache.memoize("somecachekey") {Jedis redis ->\n return cacheData\n }\n\n redisService.withConnection('search').memoizeDomainList(Book, "domainkey"){\n return Book.findAllByTitleInList(["book1", "book3"])\n }\n\n redisService.memoizeDomainIdList(Book, "domainkey"){\n return Book.findAllByTitleInList(["book1", "book3"])\n }\n\n redisServiceCache.memoizeDomainObject(Book, "domainkey"){\n return Book.get(book1.id)\n }\n\n redisServiceSearch.memoizeHash("domainkey"){\n return [foo: "bar"]\n }\n }\n}\n</code></pre>\n<h2>Memoization Annotations</h2>\n<h3>Memoization Annotations</h3>\n<h4>These currently do not work with grails 3.0+ and domain classes. Please only used these on service classes for grails 3.0+ until we can fix this</h4>\n<p>In addition to using the concrete and finite redisService.memoize* methods, as of version 1.2 you may now also annotate a method with an appropriate @Memoize* annotation. This will perform an AST transformation at compile time and wrap the entire body of the method with the corresponding memoization method. The parameters such as key and expire are passed into the annotation and used in the redisService memoize method calls.</p>\n<p>The following are available as annotations:</p>\n<table width=\"100%\">\n <tr><td><b>Annotation</b></td><td><b>Description</b></td></tr>\n <tr><td>@Memoize</td><td>Used to memoize methods that return a \"string\" - redisService.memoize</td></tr>\n <tr><td>@MemoizeObject</td><td>Used to memoize methods that return an object - redisService.memoize</td></tr>\n <tr><td>@MemoizeDomainObject</td><td>Used to memoize methods that return a domain object - redisService.memoizeDomain</td></tr>\n <tr><td>@MemoizeDomainList</td><td>Used to memoize methods that return a domain object list - redisService.memoizeDomainList</td></tr>\n <tr><td>@MemoizeHash</td><td>Used to memoize methods that return a hash - redisService.memoizeHash</td></tr>\n <tr><td>@MemoizeHashField</td><td>Used to memoize methods that return a hash field - redisService.memoizeHashField</td></tr>\n <tr><td>@MemoizeList</td><td>Used to memoize methods that return a list - redisService.memoizeList</td></tr>\n <tr><td>@MemoizeSet</td><td>Used to memoize methods that return a set - redisService.memoizeSet</td></tr>\n <tr><td>@MemoizeScore</td><td>Used to memoize methods that returns a score from a hash - redisService.memoizeScore</td></tr>\n</table>\n<p>There are integration usage tests written in spock for services at <a href=\"https://github.com/grails-plugins/grails-redis/blob/master/test/projects/default/test/integration/grails/plugin/redis/RedisMemoizeServiceSpec.groovy\">RedisMemoizeServiceSpec.groovy</a> and for domains at <a href=\"https://github.com/grails-plugins/grails-redis/blob/master/test/projects/default/test/integration/grails/plugin/redis/RedisMemoizeDomainSpec.groovy\">RedisMemoizeDomainSpec.groovy</a></p>\n<h3>Memoization Annotation Keys</h3>\n<p>Since the value of the key must be passed in but will also be transformed by AST, we can not use the <code>$</code> style gstring values in the keys. Instead you will use the <code>#</code> sign to represent a gstring value such as <code>@Memoize(key = "#{book.title}:#{book.id}")</code>.</p>\n<p>During the AST tranformation these will be replaced with the <code>$</code> character and will evaluate correctly during runtime as <code>redisService.memoize("${book.title}:${book.id}"){...}</code>.</p>\n<p>Anything that is not in the format <code>key='#text'</code> or <code>key="${text}"</code> will be treated as a string literal. Meaning that <code>key="text"</code> would be the same as using the literal string <code>"text"</code> as the memoize key <code>redisService.memoize("text"){...}</code> instead of the variable <code>$text</code>.</p>\n<p>Any variable that you use in the key property of the annotation will need to be in scope for this to work correctly. You will only get a RUNTIME error if you use a variable reference that is out of scope.</p>\n<p>This also applies to the <code>expire</code> field.</p>\n<h3>Memoization Annotation Notes</h3>\n<p>You are not required to import the <code>import grails.plugin.redis.RedisService</code> namespace or declare the service <code>def redisService</code> on any objects you wish to use this annotation with as the AST transform will detect whether this field is on your object and add it for you. You may certainly have either the import or def statements if you would like, but they are not required if you use the @Memoize* annotations.</p>\n<p>The user should be aware that any annotated method will be completely wrapped in the redis service call so any calculations that are contained within will also be wrapped and not executed of the key is in scope and not expired.</p>\n<p>If the compile succeeds but runtime fails or throws an exception, make sure the following are valid:\n* Your key OR value is configured correctly.\n* The key uses a #{} for all variables you want referenced.</p>\n<p>If the compile does NOT succeed make sure check the stack trace as some validation is done on the AST transform for each annotation type:\n* Required annotation properties are provided.\n* When using <code>expire</code> it is a valid Integer type variable.\n* When using <code>value</code> it is a valid closure.\n* When using <code>key</code> it is a valid String.</p>\n<h3>@Memoize</h3>\n<p>The @Memoize annotation is to be used when dealing with objects that are stored in Redis as strings. This annotation takes the following parameters:</p>\n<pre><code>value - A closure in the following format. (key OR value required)\nkey - A unique key for the data cache. (key OR value required)\nexpire - Expire time in seconds. Will default to never so only pass a value like 3600 if you want value to expire.\n</code></pre>\n<p><em>You can either specify a closure OR a key and expire. When using the closure style key <code>@Memoize({"#{text}"})</code> you may not pass a key or expire to the annotation as the closure will be evaluated directly and used as the key value. This is due to a limitation on how Java deals with closure annotation parameters.</em></p>\n<p>Here is an example of usage:</p>\n<pre><code>@Memoize({"#{text}"})\ndef getAnnotatedTextUsingClosure(String text, Date date) {\n println 'cache miss getAnnotatedTextUsingClosure'\n return "$text $date"\n}\n\n@Memoize(key = '#{text}')\ndef getAnnotatedTextUsingKey(String text, Date date) {\n println 'cache miss getAnnotatedTextUsingKey'\n return "$text $date"\n}\n\n//expire this extremely fast\n@Memoize(key = '#{text}', expire = '1')\ndef getAnnotatedTextUsingKeyAndExpire(String text, Date date) {\n println 'cache miss getAnnotatedTextUsingKeyAndExpire'\n return "$text $date"\n}\n\n//configurable expire time to live\n@Memoize(key = '#{text}', expire = '#{grailsApplication.config.cache.ttl}')\ndef getAnnotatedTextUsingKeyAndExpire(String text, Date date) {\n println 'cache miss getAnnotatedTextUsingKeyAndExpire'\n return "$text $date"\n}\n\n@Memoize(key = "#{book.title}:#{book.id}")\ndef getAnnotatedBook(Book book) {\n println 'cache miss getAnnotatedBook'\n return book.toString()\n}\n</code></pre>\n<h3>@MemoizeObject</h3>\n<p>The @MemoizeObject annotation is to be used when dealing with simple (non-domain) objects that are to have their contents stored in Redis in JSON form. The simple object being returned by the return statement will be converted to JSON, stored in Redis, then converted from JSON back to the object. It is important to ensure that the object class you're using is able to be converted to and from JSON for this annotation to work. This annotation takes the following parameters:</p>\n<pre><code>key - A unique key for the data cache. (required)\nexpire - Expire time in seconds. Will default to never so only pass a value like 3600 if you want value to expire.\nclazz - The class of the object to be memoizing. (required)\n</code></pre>\n<p>Here is an example of usage:</p>\n<pre><code>@MemoizeObject(key = "#{title}", expire = "#{grailsApplication.config.cache.ttl}", clazz = Book.class)\ndef createObject(String title, Date date) {\n println 'cache miss createObject'\n new Book(title: title, createDate: date)\n}\n</code></pre>\n<p>This method is also available from the <code>RedisService</code>:</p>\n<pre><code>redisService.memoizeObject(Book.class, title, grailsApplication.config.cache.ttl) {\n println 'cache miss createObject'\n new Book(title: title, createDate: date)\n}\n</code></pre>\n<h3>@MemoizeDomainObject</h3>\n<p>The @MemoizeDomainObject annotation is to be used when dealing with domain objects that are to have their id's stored in Redis. See the documentation on Domain Object Memoization above for more details. This annotation takes the following parameters:</p>\n<pre><code>key - A unique key for the data cache. (required)\nexpire - Expire time in seconds. Will default to never so only pass a value like 3600 if you want value to expire.\nclazz - The class of the object to be memoizing. (required)\n</code></pre>\n<p>Here is an example of usage:</p>\n<pre><code>@MemoizeDomainObject(key = "#{title}", clazz = Book.class)\ndef createDomainObject(String title, Date date) {\n println 'cache miss createDomainObject'\n Book.build(title: title, createDate: date)\n}\n</code></pre>\n<h3>@MemoizeDomainList</h3>\n<p>The @MemoizeDomainList annotation is to be used when dealing with lists of domain objects that are to have their id's stored in Redis. See the documentation on Domain List Memoization above for more details. This annotation takes the following parameters:</p>\n<pre><code>key - A unique key for the data cache. (required)\nexpire - Expire time in seconds. Will default to never so only pass a value like 3600 if you want value to expire.\nclazz - The class of the object to be memizing. (required)\n</code></pre>\n<p>Here is an example of usage:</p>\n<pre><code>@MemoizeDomainList(key = "getDomainListWithKeyClass:#{title}", clazz = Book.class)\ndef getDomainListWithKeyClass(String title, Date date) {\n println 'cache miss getDomainListWithKeyClass'\n Book.findAllByTitle(title)\n}\n</code></pre>\n<h3>@MemoizeList</h3>\n<p>The @MemoizeList annotation is to be used when dealing with list type objects. This annotation takes the following parameters:</p>\n<pre><code>value - A closure in the following format. (key OR value required)\nkey - A unique key for the data cache. (key OR value required)\nexpire - Expire time in seconds. Will default to never so only pass a value like 3600 if you want value to expire.\n</code></pre>\n<p><em>You can either specify a closure OR a key and expire. When using the closure style key <code>@Memoize({"#{text}"})</code> you may not pass a key or expire to the annotation as the closure will be evaluated directly and used as the key value. This is due to a limitation on how Java deals with closure annotation parameters.</em></p>\n<p>Here is an example of usage:</p>\n<pre><code>@MemoizeList(key = "#{list[0]}")\ndef getAnnotatedList(List list) {\n println 'cache miss getAnnotatedList'\n return list\n}\n</code></pre>\n<h3>@MemoizeScore</h3>\n<p>The @MemoizeScore annotation is to be used when dealing with scores in hashes. This annotation takes the following parameters:</p>\n<pre><code>key - A unique key for the data cache. (required)\nexpire - Expire time in seconds. Will default to never so only pass a value like 3600 if you want value to expire.\nmember - The hash property to store. (required)\n</code></pre>\n<p>Here is an example of usage:</p>\n<pre><code>@MemoizeScore(key = "#{map.key}", member="foo")\ndef getAnnotatedScore(Map map) {\n println 'cache miss getAnnotatedScore'\n return map.foo\n}\n</code></pre>\n<h3>@MemoizeHash</h3>\n<p>The @MemoizeHash annotation is to be used when dealing with maps/hash type objects. This annotation takes the following parameters:</p>\n<pre><code>value - A closure in the following format. (key OR value required)\nkey - A unique key for the data cache. (key OR value required)\nexpire - Expire time in seconds. Will default to never so only pass a value like 3600 (one hour) if you want value to expire.\n</code></pre>\n<p><em>You can either specify a closure OR a key and expire. When using the closure style key <code>@Memoize({"#{text}"})</code> you may not pass a key or expire to the annotation as the closure will be evaluated directly and used as the key value. This is due to a limitation on how Java deals with closure annotation parameters.</em></p>\n<p>Here is an example of usage:</p>\n<pre><code>@MemoizeHash(key = "#{map.foo}")\ndef getAnnotatedHash(Map map) {\n println 'cache miss getAnnotatedHash'\n return map\n}\n</code></pre>\n<h2>Grails 3.0</h2>\n<p>Most things remain the same except configuration in the <code>application.yml</code> file will be done not in dsl closure but YAML style.</p>\n<pre><code class=\"language-yml\">---\ngrails:\n redis:\n poolConfig:\n maxIdle: 10\n doesnotexist: true\n</code></pre>\n<p>The package namespace has changed to <code>grails.plugins.redis</code>. Note the addition of the s in plugin[s].</p>\n<p>@Memoize annotations currently do NOT work with domain objects and classes. We are working to fix this.</p>\n<p>Previously the @Memoize annotations would inject the redisService into your classes, due to changes in how beans are wired in grails 3.0.0+ it is recommended that you\ndefine the service in your classes like the following:</p>\n<pre><code class=\"language-groovy\">class MyService {\n \n RedisService redisService\n \n @Memoize()\n def doFoo(){\n ...\n }\n \n}\n</code></pre>\n<h1>Release Notes Grails 3.x</h1>\n<ul>\n<li>2.0.5 - released 12/08/2016 - Upgrading to Jedis 2.9.0. Putting close on the resource in withRedis block.</li>\n<li>2.0.4 - released 02/26/2016 - Upgrading to Jedis 2.8.0 and Gson 2.6.1. Official name for package to <code>org.grails.plugins:redis</code>. Moved bintray location. <em>Breaking Change</em></li>\n<li>2.0.3 - released 02/01/2016 - Attempting to cleaup the code and naming for plugin/package</li>\n<li>2.0.2 - released 06/25/2015 - Adding support for external configuration of sentinels</li>\n<li>2.0.1 - released 05/04/2015 - web-inf directory removed from plugin</li>\n<li>2.0.0 - released 03/18/2015 - Grails 3.0.0 Support! You can install <a href=\"https://bintray.com/tednaleid/grails-plugins/org.grails.plugins%3Agrails-redis/2.0.0/view\">from bintray</a>. There is a known issue where <code>@Memoize</code> annotations don't work on domain classes, most everything else works.</li>\n</ul>\n<h1>Release Notes Grails 2.x</h1>\n<ul>\n<li>1.0.0.M7 - released 8/5/2011 - this is actually the first released revision of the plugin. As it's replacing the old "redis" plugin (now "redis-gorm"), we needed to start with a number higher than the last released revision of that. If you want the old redis-gorm plugin (which hasn't been released as of 8/5/2011), you can use "grails install-plugin 1.0.0.M6"</li>\n<li>1.0.0.M8 - released 8/15/2011 - bugfix release mostly around the JedisTemplate that was ported from redis-gorm</li>\n<li>1.0.0.M9 - released 8/16/2011 - removal of the Jedis/RedisTemplate stuff from redis-gorm as it's needed by things that can't rely on grails plugins, minor bugfixes for tests.</li>\n<li>1.1 - released 12/10/2011 - removed hibernate & tomcat plugin dependency, added memoizeSet, memoizeList, memoizeDomainObject, and deleteKeysWithPattern methods, significantly reduced amount of time redis connections were used by plugin during memoization, BREAKING CHANGE: memoize methods no longer pass a Jedis connection object into the closure, they must be created on demand within the closure code.</li>\n<li>1.2 - released 2/1/2012 - added memoize annotations to support spring-cache like support on domain, service, and controller classes.</li>\n<li>1.3 - released 4/28/2012 - added support for additional redis server endpoint wiring via config block.</li>\n<li>1.3.1 - released 5/20/2012 - adds support for Jedis 2.1 and a <code>database</code> parameter in the config to pick a redis database</li>\n<li>1.3.2 - released 7/6/2012 - marks erroring pool connections as invalid so the pool knows to discard and recreate them</li>\n<li>1.3.3 - released 2/27/2013 - bugfix for transactions</li>\n<li>1.4.0 - released 9/29/2013 - support for Redis Sentinel and Jedis 2.2</li>\n<li>1.4.1 - released 9/29/2013 - bug fixes for <code>memoizeDomainObject</code> and checking logging level before calling logging method</li>\n<li>1.4.3 - released 1/17/2014 - made the memoize methods not throw a JCE when redis is down, just log a warning and pass through the value retrieved live</li>\n<li>1.4.4 - released 2/16/2014 - Allow for the 'expire' field to optionally be a variable in annotations instead of a constant string only, just like the 'key' works</li>\n<li>1.5.0 - released 2/24/2014 - addition of <code>@MemoizeObject</code> annotation which allows for JSON representation to be stored in redis, moved log level of "optional" redis connections down to info, better handling/transformation of config values</li>\n<li>1.5.1 - released 3/16/2014 - updated to Jedis 2.4.2</li>\n<li>1.5.2 - released 4/18/2014 - Do not fail hard on bad poolConfig parameters</li>\n<li>1.5.3 - released 4/23/2014 - Fix the implementation on soft setting the poolConfig parameters</li>\n<li>1.5.5 - released 5/28/2014 - Added <code>redisService.memoizeObject</code> method (#34) with optional <code>[cacheNull: false]</code> flag (#35)</li>\n<li>1.6.0 - released 11/04/2014 - Changed how <code>RedisService</code> is spring injected so that it's easier to mock out for tests by clients. Upgraded to Jedis 2.6.0.</li>\n<li>1.6.2 - released 02/06/2015 - Port and timeout properties injected by external properties file are now converted to Integer. If not integer, then defaults used.</li>\n</ul>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "redis-gorm", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "GORM - Grails Data Access Framework", |
| "labels": [ |
| "gorm", |
| "nosql", |
| "redis" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/gorm-redis/issues", |
| "latestVersion": "6.0.4", |
| "updated": "2016-11-07T00:17:00.000Z", |
| "systemIds": [ |
| "org.grails.plugins:redis-gorm" |
| ], |
| "vcsUrl": "https://github.com/grails/gorm-redis" |
| }, |
| "documentationUrl": "https://gorm.grails.org/latest/redis/manual/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>GORM for Redis</h1>\n<p>This project implements <a href=\"http://gorm.grails.org/latest/\">GORM</a> for the Redis Key/Value Database.</p>\n<p>For more information see the following links:</p>\n<ul>\n<li><a href=\"http://gorm.grails.org/latest/redis/manual\">Documentation</a></li>\n<li><a href=\"http://gorm.grails.org/latest/redis/api\">API</a></li>\n<li><a href=\"https://grails.org/plugins.html#plugin/redis\">Grails Plugin</a></li>\n<li><a href=\"https://travis-ci.org/grails/gorm-redis\"><img src=\"https://travis-ci.org/grails/gorm-redis.svg?branch=master\" alt=\"Build Status\" /></a></li>\n</ul>\n<p>For the current development version see the following links:</p>\n<ul>\n<li><a href=\"http://gorm.grails.org/snapshot/redis/manual\">Beta Documentation</a></li>\n<li><a href=\"http://gorm.grails.org/snapshot/redis/api\">Beta API</a></li>\n</ul>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "remora", |
| "repo": "plugins", |
| "owner": "neilab", |
| "desc": "Remora is a Grails Image / File Upload Plugin formally based on Selfie plugin. Use Remora to attach files to your domain models, upload to a CDN, validate content, produce thumbnails.", |
| "labels": [ |
| "image", |
| "file", |
| "upload" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/neilabdev/remora/issues", |
| "latestVersion": "1.0.1", |
| "updated": "2016-09-15T14:13:10.459Z", |
| "systemIds": [ |
| "com.neilab.plugins.remora:remora" |
| ], |
| "vcsUrl": "https://github.com/neilabdev/remora" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Remora</h1>\n<p>Remora is a Grails Image / File Upload / Attachment Plugin. It was initially based on the excellent Selfie plugin by bertramlabs, which at the time was limited to grails 2 and implemented using grails column embedding feature to incorporate attachments into the domain model, which was not ideal for my specific project and thus a fork was created to resolve these issues with additional features.</p>\n<p>You may use Remora to attach files to your domain models, upload to a CDN, validate content, and produce thumbnails.</p>\n<ul>\n<li>Domain Attachment</li>\n<li>CDN Storage Providers (via Karman)</li>\n<li>Image Resizing (imgscalr)</li>\n<li>Content Type Validation</li>\n<li>GORM Bindings / Hibernate User Types Support</li>\n</ul>\n<h2>Installation</h2>\n<p>Add The Following to your <code>build.gradle</code>:</p>\n<pre><code class=\"language-groovy\">dependencies {\n compile ':remora:1.0.1'\n}\n</code></pre>\n<h2>Configuration</h2>\n<p>Remora utilizes karman for dealing with asset storage. Karman is a standardized interface for sending files up to CDN's as well as local file stores. It is also capable of serving local files.\nIn order to upload files, we must first designate a storage provider for these files. This can be done in the <code>remora</code> static map in each GORM domain with which you have an Attachment,\nor this can be defined in your <code>application.groovy</code> or 'application.yml'.</p>\n<pre><code class=\"language-groovy\">\nimport com.neilab.plugins.remora.Attachment\nimport com.neilab.plugins.remora.AttachmentUserType\n\ngrails.gorm.default.mapping = {\n "user-type" type: AttachmentUserType, class: Attachment // useful to only require specifying class type in domain\n}\n\nremora {\n storage {\n bucket = 'uploads'\n providerOptions {\n provider = 'local' // // Switch to s3 if you wish to use s3 and install the karman-aws plugin\n basePath = 'storage'\n baseUrl = 'http://localhost:8080/image-test/storage'\n }\n\n provider { // corresponds to provider in providerOptions\n local {\n basePath = 'storage'\n baseUrl = 'http://localhost:8080/image-test/storage'\n }\n\n s3 {\n basePath = 'storage'\n baseUrl = 'http://localhost:8080/image-test/storage'\n //accessKey = "KEY" //Used for S3 Provider\n //secretKey = "KEY" //Used for S3 Provider\n }\n }\n }\n}\n\n</code></pre>\n<p>The <code>providerOptions</code> section will pass straight through to karmans <code>StorageProvider.create()</code> factory. The <code>provider</code> specifies the storage provider to use while the other options are specific to each provider.</p>\n<p>In the above example we are using the karman local storage provider. This is all well and good, but we also need to be able to serve these files from a URL. Depending on your environment this can get a bit tricky.\nOne option is to use nginx to serve the directory and point the <code>baseUrl</code> to the appropriate endpoint. Another option is to use the built in endpoint provided by the karman plugin:</p>\n<p><strong>NOTE</strong>:</p>\n<p>You can also configure which bucket or karman storage provider is used on a per domain level as well as per property level basis in your application config. For example the <code>Book</code> domain class could be configured as follows:</p>\n<pre><code class=\"language-groovy\">\nremora {\n domain {\n book {\n storage {\n path = 'uploads/:class/:id/:propertyName/' //This configures the storage path of the files being uploaded by domain class name and property name and identifier in GORM\n bucket = 'uploads'\n providerOptions {\n provider = 'local' // Switch to s3 if you wish to use s3 and install the karman-aws plugin\n basePath = 'storage'\n baseUrl = 'http://localhost:8080/image-test/storage'\n //accessKey = "KEY" //Used for S3 Provider\n //secretKey = "KEY" //Used for S3 Provider\n }\n }\n }\n }\n}\n \n\n</code></pre>\n<h2>Usage</h2>\n<p>Unlike its worthy predecessor Selfie, the Remora plugin does not use an embedded GORM domain class to provide an elegant DSL for uploading and attaching files to your domains. You merely only need to add the Attachment class as the type for your storage file. Instead of embedding, aforesaid type becomes a single text field column which is serialized to JSON, instead of multiple columns that would be added if it were embedded.</p>\n<p>Example DSL:</p>\n<pre><code class=\"language-groovy\">import com.neilab.plugins.remora.Attachment\nimport com.neilab.plugins.remora.AttachmentUserType\n\nclass Book {\n String name\n Integer size\n Attachment photo // only this is require, everything else is optional\n\n static remora = [\n photo: [ // if a key is the name of a property and not reserved (see below), can be used to configure attachments properties\n styles: [\n thumb: [width: 50, height: 50, mode: 'fit'],\n medium: [width: 250, height: 250, mode: 'scale']\n ]\n ],\n \n storage: [ // reserved key which allows overriding application configs for this domain.\n bucket:'book_bucket',\n //:url & :path are interpolated using variables :class,:domainName,:style,:propertyName,:id and :type\n url: "/:id/:type/:style/:propertyName/", \n path: "attachment/:domainName/:propertyName/:id"\n ],\n \n assign: [ // reserved key which allows you to assign the attachment properties to additional model database columns.\n originalFilename:'name', // assigns filename of original attachment to property :name\n fileSize:'size' // assigns size of original attachment to property :size\n ]\n ]\n \n static constraints = {\n photo contentType: [\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdpng\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd,\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdjpg\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd], fileSize:1024*1024 // 1mb\n }\n}\n</code></pre>\n<p>Uploading Files could not be simpler. Simply use a multipart form and upload a file:</p>\n<pre><code class=\"language-gsp\"><g:uploadForm name="upload" url="[action:'upload',controller:'photo']">\n <input type="file" name="photo" /><br/>\n <g:submitButton name="update" value="Update" /><br/>\n</g:uploadForm>\n</code></pre>\n<p>When you bind your params object to your GORM model, the file will automatically be uploaded upon save and processed:</p>\n<pre><code class=\"language-groovy\">class PhotoController {\n def upload() {\n def photo = new Photo(params)\n if(!photo.save()) {\n println "Error Saving! ${photo.errors.allErrors}"\n }\n redirect view: "index"\n }\n}\n</code></pre>\n<h2>Things to be Done</h2>\n<ul>\n<li>Better documentation</li>\n</ul>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "remote-pagination", |
| "repo": "plugins", |
| "owner": "amitjain", |
| "desc": "Grails remote-pagination plugin", |
| "labels": [ |
| "pagination" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/amitjain1982/remote-pagination/issues", |
| "latestVersion": "0.5.0", |
| "updated": "2016-03-31T13:31:55.155Z", |
| "systemIds": [ |
| "org.grails.plugins:remote-pagination" |
| ], |
| "vcsUrl": "https://github.com/amitjain1982/remote-pagination" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Installation</h1>\n<p>Just execute following from your application directory:</p>\n<p><code>grails install-plugin remote-pagination</code></p>\n<h1>Using</h1>\n<p>If you have used paginate and sortableColumn tag, then you will find its usage very similar to them. The tags needs to reside inside the template, which renders the list of records. Checkout the <a href=\"https://github.com/IntelliGrape/Grails-Remote-Pagination-SampleApp/\">Sample Application</a> here.</p>\n<h1>Config</h1>\n<p>We can provide default max elements to be displayed for all remote-paginate tags via following configuration. However, it defaults to 10.\n<code><pre>\n//In Config.groovy\ngrails.plugins.remotepagination.max=20\n//EnableBootstrap here when using twitter bootstrap, default is set to false.\ngrails.plugins.remotepagination.enableBootstrap=true\n</pre></code></p>\n<h1>Tags</h1>\n<p>The remote-pagination plugin currently provides the following tags:</p>\n<ul>\n<li>remotePaginate</li>\n<li>remoteSortableColumn</li>\n<li>remotePageScroll</li>\n<li>remoteNonStopPageScroll</li>\n</ul>\n<h2>util:remotePaginate</h2>\n<h3>Purpose</h3>\n<p>Creates next/previous buttons and a breadcrumb trail to allow pagination of results, without a page refresh using ajax calls.</p>\n<code>\n <pre>\n //Example domain class\n class Book {\n String title\n String author\n }\n //Example controller used for all tags:\n class BookController {\n def list = {\n [books: Book.list(params)]\n }\n def filter ={\n render(template:\"listTemplate\" ,model:[ bookInstanceList: Book.list(params )])\n } \n }\n </pre>\n</code><br/>\nremotePaginate code written inside _listTemplate.gsp:\n<code><pre>\n<util:remotePaginate controller=\"book\" action=\"filter\" total=\"${Book.count()}\"\n update=\"listTemplateDivId\" max=\"20\" pageSizes=\"[10, 20, 50,100]\"/>\n<util:remotePaginate controller=\"book\" action=\"filter\" total=\"${Book.count()}\" update=\"listTemplateDivId\"\n max=\"20\" pageSizes=\"[10:'10 Per Page', 20: '20 Per Page', 50:'50 Per Page',100:'100 Per Page']\"/>\n</pre></code>\n### Description\nAttributes update, action and total are required. \n### Attributes\n* total (required) - The total number of results to paginate \n* action (required) - The name of the action to use in the link\n* update (required) - The id of the div/span which contains the tag to render the template, which displays the list.\n* controller (optional) - The name of the controller to use in the link, if not specified the current controller will be linked \n* id (optional) - The id to use in the link \n* params (optional) - A map containing request parameters \n* prev (optional) - The text to display for the previous link (defaults to \"Previous\" as defined by default.paginate.prev property in I18n messages.properties) \n* next (optional) - The text to display for the next link (defaults to \"Next\" as defined by default.paginate.next property in I18n messages.properties) \n* max (optional) - The number of records displayed per page (defaults to 10). Used ONLY if params.max is empty \n* maxsteps (optional) - The number of steps displayed for pagination (defaults to 10). Used ONLY if params.maxsteps is empty \n* offset (optional) - Used ONLY if params.offset is empty\n* pageSizes(optional) - The list containing different page sizes user can select from(defaults to max attribute or the first value given in the list). Provide Map instead of list to display text other than pageSize in a select box.\n* alwaysShowPageSizes(optional) - A boolean value, either to show pageSizes select box irrespective of total records (defaults to false). Use only when pageSizes list or map is provided.\n<h4>Events</h4>\n<ul>\n<li>onSuccess (optional) - The javascript function to call if successful</li>\n<li>onFailure (optional) - The javascript function to call if the call failed</li>\n<li>on_ERROR_CODE (optional) - The javascript function to call to handle specified error codes (eg on404="alert('not found!')"). With Prototype, this prevents execution of onSuccess and onFailure.</li>\n<li>onUninitialized (optional) - The javascript function to call the a ajax engine failed to initialise</li>\n<li>onLoading (optional) - The javascript function to call when the remote function is loading the response</li>\n<li>onLoaded (optional) - The javascript function to call when the remote function is completed loading the response</li>\n<li>onComplete (optional) - The javascript function to call when the remote function is complete, including any updates</li>\n</ul>\n<h2>util:remoteSortableColumn</h2>\n<h3>Purpose</h3>\n<p>Renders a remote sortable column to support sorting in tables , without a page refresh using ajax calls.</p>\n<p>Examples\n<code><pre>\n<util:remoteSortableColumn property="title" title="Title" update="listTemplateDivId"/>\n<util:remoteSortableColumn property="title" title="Title" style="width: 200px" update="listTemplateDivId"/>\n<util:remoteSortableColumn property="author" defaultOrder="desc" title="author"\ntitleKey="book.author" update="listTemplateDivId"/>\n</pre></code></p>\n<h3>Description</h3>\n<p>Attributes update, action and either title or titleKey are required. When title or titleKey attributes are specified then titleKey takes precedence, resulting in the title caption to be resolved against the message source. In case when the message could not be resolved, the title will be used as title caption.</p>\n<h3>Attributes</h3>\n<ul>\n<li>property - name of the property relating to the field</li>\n<li>defaultOrder (optional) - default order for the property; choose between asc (default if not provided) and desc</li>\n<li>title (optional) - title caption for the column</li>\n<li>titleKey (optional) - title key to use for the column, resolved against the message source</li>\n<li>params (optional) - a map containing request parameters. For ex. To set max number of records displayed as params="[max: 10]"</li>\n<li>action (required) - the name of the action to use in the link</li>\n<li>update (required) \ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd the id of the div/span which contains the tag to render the template, which displays the list.</li>\n<li>controller (optional) - the name of the controller to use in the link, if not specified the current controller will be linked</li>\n</ul>\n<h3>Events</h3>\n<ul>\n<li>onSuccess (optional) - The javascript function to call if successful</li>\n<li>onFailure (optional) - The javascript function to call if the call failed</li>\n<li>on_ERROR_CODE (optional) - The javascript function to call to handle specified error codes (eg on404="alert('not found!')"). With Prototype, this prevents execution of onSuccess and onFailure.</li>\n<li>onUninitialized (optional) - The javascript function to call the a ajax engine failed to initialise</li>\n<li>onLoading (optional) - The javascript function to call when the remote function is loading the response</li>\n<li>onLoaded (optional) - The javascript function to call when the remote function is completed loading the response</li>\n<li>onComplete (optional) - The javascript function to call when the remote function is complete, including any updates</li>\n</ul>\n<h2>util:remotePageScroll</h2>\n<h3>Purpose</h3>\n<p>Renders more records lazily on a click of link, appends them to the existing list of records without a page refresh using ajax calls. This tag needs to be inside a template for example "_listTemplate.gsp".\n<br/>Examples\n<code><pre>\n//This tag is supported only if application's grails javascript library is set to 'jQuery'.\n<util:remotePageScroll action="filter" total="${total}" update="listTemplateDivId"/>\n<util:remotePageScroll action="filter" total="${total}" update="listTemplateDivId"\ntitle="Show More Records..." max="5" class="anyCSSClass"/>\n</pre></code></p>\n<h3>Description</h3>\n<p>Attributes update, action and total are required. This should reside in a template, which loop through the records to be displayed iteratively.</p>\n<h3>Attributes</h3>\n<ul>\n<li>total (required) - The total number of results to paginate</li>\n<li>action (required) - The name of the action to use in the link</li>\n<li>update (required) - The id of the div/span which contains the tag to render the template, which displays the list.</li>\n<li>controller (optional) - the name of the controller to use in the link, if not specified the current controller will be linked</li>\n<li>id (optional) - The id to use in the link</li>\n<li>params (optional) - A map containing request parameters</li>\n<li>title (optional) - The text to display for the link (defaults to "Show more...", precedence is given to 'paginate.more.title' property if found in I18n messages.properties).</li>\n<li>max (optional) - The number of records displayed per page (defaults to 10). Used ONLY if params.max is empty</li>\n<li>offset (optional) - Used ONLY if params.offset is empty</li>\n</ul>\n<h3>Events</h3>\n<ul>\n<li>onSuccess (optional) - The javascript function to call if successful</li>\n<li>onFailure (optional) - The javascript function to call if the call failed</li>\n<li>on_ERROR_CODE (optional) - The javascript function to call to handle specified error codes (eg on404="alert('not found!')"). With Prototype, this prevents execution of onSuccess and onFailure.</li>\n<li>onUninitialized (optional) - The javascript function to call the a ajax engine failed to initialise</li>\n<li>onLoading (optional) - The javascript function to call when the remote function is loading the response</li>\n<li>onLoaded (optional) - The javascript function to call when the remote function is completed loading the response</li>\n<li>onComplete (optional) - The javascript function to call when the remote function is complete, including any updates</li>\n</ul>\n<h2>util:remoteNonStopPageScroll</h2>\n<h3>Purpose</h3>\n<p>Renders more records lazily on page scroll, appends them to the existing list of records without a page refresh using ajax calls. This tag needs to be inside a template for example "_listTemplate.gsp".</p>\n<p>Examples\n<code><pre>\n//This tag is supported only if application's grails javascript library is set to 'jQuery'.\n//We need to include remoteNonStopPageScroll.js file provided by the plugin for this tag to work.\n<g:javascript plugin="remote-pagination" library="remoteNonStopPageScroll"/><br/>\n<util:remoteNonStopPageScroll action='filter' total="${total}" update="listTemplateDivId" />\n<util:remoteNonStopPageScroll action='filter' controller="book" total="${total}"\nupdate="listTemplateDivId" heightOffset="10" loadingHtml="loadingGifDivId" />\n</pre></code></p>\n<h3>Description</h3>\n<p>Attributes update, action and total are required. This tag should reside in a template for example "_listTemplate.gsp", which loops through the records to be displayed iteratively.</p>\n<h3>Attributes</h3>\n<ul>\n<li>total (required) - The total number of results to paginate</li>\n<li>action (required) - The name of the action to use in the link</li>\n<li>update (required) - The id of the div/span which contains the tag to render the template, which displays the list.</li>\n<li>controller (optional) - the name of the controller to use in the link, if not specified the current controller will be linked</li>\n<li>id (optional) - The id to use in the link</li>\n<li>params (optional) - A map containing request parameters</li>\n<li>max (optional) - The number of records displayed per page (defaults to 10). Used ONLY if params.max is empty</li>\n<li>offset (optional) - Used ONLY if params.offset is empty</li>\n<li>loadingHTML (optional) - The id of div/span to be displayed while waiting for response from the server.</li>\n<li>heightOffset (optional) : Request for more records when scroll is <heightOffset> pixels before the page ends. Defaults to 10.</li>\n</ul>\n<h3>Events</h3>\n<ul>\n<li>onSuccess (optional) - The javascript function to call if successful</li>\n<li>onFailure (optional) - The javascript function to call if the call failed</li>\n<li>onLoading (optional) - The javascript function to call when the remote function is loading the response</li>\n<li>onComplete (optional) -The javascript function to call when the remote function is complete, including any updates</li>\n</ul>\n<h2>Version History</h2>\n<ul>\n<li>0.4.8 : Fixes <a href=\"https://github.com/amitjain1982/remote-pagination/issues/14\">PageNonStopScroll issue with window resize</a></li>\n<li>0.4.7 : Fixes <a href=\"https://github.com/amitjain1982/remote-pagination/issues/10\">issue</a>,<a href=\"https://github.com/amitjain1982/remote-pagination/issues/11\">issue</a> & <a href=\"https://github.com/amitjain1982/remote-pagination/issues/13\">issue</a>,</li>\n<li>0.4.6 : Fix UI issues to work with Twitter Bootstrap 3.0 and above. <a href=\"http://jira.grails.org/browse/GPREMOTEPAGINATION-15/\">issue</a></li>\n<li>0.4.5 : Fix UI issues to work with Twitter bootstrap.</li>\n<li>0.4.4 : Fixed javascript error on page load.</li>\n<li>0.4.2 : Fixed bug with remoteNonStopPageScroll of loading all data at once in certain scenario. rer#2</li>\n<li>0.4.1 : Added loadingHTML property to remoteNonStopPageScroll tag.</li>\n<li>0.4 :- Added remoteNonStopPageScroll tag. Also the default max elements for all remote pagination tags can be provided in the config.groovy. This plugin has been upgraded to work with grails versions >= 2.0.3.</li>\n<li>0.3 :- Added remotePageScroll tag, In remotePaginateTag, pageSizes now accept both Map & List and also added new option alwaysShowPageSizes.</li>\n<li>0.2.8 :- Fixed jira <a href=\"http://jira.grails.org/browse/GPREMOTEPAGINATION-9/\">issue</a></li>\n<li>0.2.7 :- Fixed two jira issues i.e <a href=\"http://jira.grails.org/browse/GPREMOTEPAGINATION-7/\">bug</a> and <a href=\"http://jira.grails.org/browse/GPREMOTEPAGINATION-8/\">improvement</a></li>\n</ul>\n<h3>Roadmap</h3>\n<p>Issues and improvements for this plugin are <a href=\"http://jira.codehaus.org/browse/GRAILSPLUGINS/component/14053/\">maintained here</a> on Codehaus JIRA.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "remotessh", |
| "repo": "maven", |
| "owner": "vahid", |
| "desc": "Grails RemoteSSH Plugin", |
| "labels": [ |
| "ssh" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/vahidhedayati/RemoteSSH/issues", |
| "latestVersion": "3.0.9", |
| "updated": "2019-04-08T20:09:14.111Z", |
| "systemIds": [ |
| "org.grails.plugins:remotessh" |
| ], |
| "vcsUrl": "https://github.com/vahidhedayati/RemoteSSH" |
| }, |
| "documentationUrl": "https://vahidhedayati.github.io/RemoteSSH/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>RemoteSSH</h1>\n<p>Grails RemoteSSH Plugin based on Ganymed SSH-2 library</p>\n<h3>Side note - similar / related projects</h3>\n<ul>\n<li>\n<p><a href=\"https://github.com/vahidhedayati/RemoteSSH\">RemoteSSH (this)</a></p>\n</li>\n<li>\n<p><a href=\"https://github.com/vahidhedayati/jssh\">jssh</a></p>\n</li>\n</ul>\n<p>Dependency Grails 2:</p>\n<pre><code class=\"language-groovy\">\tcompile ":remote-ssh:0.14"\n</code></pre>\n<p><a href=\"https://github.com/vahidhedayati/RemoteSSH/tree/grails2\">Grails 2 source</a></p>\n<p>Dependency Grails 3 (build.gradle):</p>\n<pre><code class=\"language-groovy\">\tcompile "org.grails.plugins:remotessh:3.0.9"\n</code></pre>\n<p><a href=\"https://github.com/vahidhedayati/RemoteSSH\">Grails 3 source</a></p>\n<h2>Documentation</h2>\n<p><a href=\"https://github.com/vahidhedayati/RemoteSSH/blob/master/docs/revisions/release-0.14.md\">How to use latest revision</a></p>\n<p><a href=\"https://github.com/vahidhedayati/RemoteSSH/docs/config.md\">Configuration variables</a></p>\n<p><a href=\"http://vahidhedayati.github.io/RemoteSSH/gapi/grails/plugin/remotessh/SSHUtil.html\">SSHUtil methods and how to use</a></p>\n<p><a href=\"http://vahidhedayati.github.io/RemoteSSH/gapi/grails/plugin/remotessh/SshUtilService.html\">SshUtilService methods and how to use</a></p>\n<p><a href=\"http://vahidhedayati.github.io/RemoteSSH/gapi/index.html\">Groovy Docs for classes within plugin: methods/usage</a></p>\n<p><a href=\"http://vahidhedayati.github.io/RemoteSSH/api/index.html\">Java Docs for classes within plugin: methods/usage</a></p>\n<h3><a href=\"https://www.youtube.com/watch?v=-Cjpj1LLI4k\">Youtube video walking through 0.14+</a></h3>\n<h2><a href=\"https://github.com/vahidhedayati/test-rssh\">Demo site grails 2.4.4 remote-ssh:0.14</a></h2>\n<h2><a href=\"https://github.com/vahidhedayati/testrssh\">Demo site grails 3.0.1 remote-ssh:3.0.1</a></h2>\n<p><a href=\"https://github.com/vahidhedayati/RemoteSSH/docs/revisions/index.md\">How to use older revisions</a></p>\n<h4>For websocket live ssh connection / interaction:</h4>\n<p>Check out : <a href=\"https://github.com/vahidhedayati/jssh\">jssh</a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "rendering", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Grails rendering plugin", |
| "labels": [ |
| "rendering", |
| "image", |
| "pdf" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/gpc/rendering/issues", |
| "latestVersion": "2.0.3", |
| "updated": "2017-01-26T14:00:59.747Z", |
| "systemIds": [ |
| "org.grails.plugins:rendering" |
| ], |
| "vcsUrl": "https://github.com/gpc/rendering" |
| }, |
| "documentationUrl": "https://gpc.github.io/rendering/", |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/gpc/rendering\"><img src=\"https://travis-ci.org/gpc/rendering.svg?branch=master\" alt=\"Build Status\" /></a></p>\n<h1>Rendering Grails Plugin</h1>\n<p>This plugin adds PDF, GIF, PNG and JPEG rendering facilities to Grails applications via the <a href=\"https://xhtmlrenderer.dev.java.net/\">XHTML Renderer</a> library.</p>\n<p>Rendering is either done directly via one of the <code>\ufffd\ufffd\ufffd\ufffdformat\ufffd\ufffd\ufffd\ufffdRenderingService</code> services \ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd</p>\n<pre><code>ByteArrayOutputStream bytes = pdfRenderingService.render(template: "/pdfs/report", model: [data: data])\n</code></pre>\n<p>Or via one of the <code>render\ufffd\ufffd\ufffd\ufffdformat\ufffd\ufffd\ufffd\ufffd()</code> methods added to controllers \ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd</p>\n<pre><code>renderPdf(template: "/pdfs/report", model: [report: reportObject], filename: reportObject.name)\n</code></pre>\n<p>Please see the <a href=\"http://gpc.github.io/rendering/\" title=\"Grails Rendering Plugin @ GitHub\">User Guide</a> for more information.</p>\n<p>The plugin is released under the <a href=\"http://www.apache.org/licenses/LICENSE-2.0.html\" title=\"Apache License, Version 2.0 - The Apache Software Foundation\">Apache License 2.0</a> and is produced under the <a href=\"http://gpc.github.com/\">Grails Plugin Collective</a>.\nHowever, it does <a href=\"http://www.gnu.org/licenses/lgpl.html\">LGPL</a> libraries: <a href=\"https://code.google.com/p/flying-saucer/\">XhtmlRenderer</a> and <a href=\"http://sourceforge.net/projects/itext/\">iText</a>.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "request-tracelog", |
| "repo": "plugins", |
| "owner": "nobeans", |
| "desc": "Grails request-tracelog plugin", |
| "labels": [ |
| "logging" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/nobeans/grails-request-tracelog/issues", |
| "latestVersion": "1.3.0", |
| "updated": "2017-06-14T07:06:41.756Z", |
| "systemIds": [ |
| "org.grails.plugins:request-tracelog" |
| ], |
| "vcsUrl": "https://github.com/nobeans/grails-request-tracelog" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Request Tracelog Plugin for Grails 3</h1>\n<p>This is a Grails 3 plugin to get info logs of request.</p>\n<h2>Installation</h2>\n<p>In build.gradle:</p>\n<pre><code>dependencies {\n compile "org.grails.plugins:request-tracelog:1.2.0"\n}\n</code></pre>\n<h2>Usage</h2>\n<p>All you have to do is to install the plugin.\nOnly in the <code>development</code> environment, three request logs emit as follows:</p>\n<pre><code>Before Action\n Request ID: ServletWebRequest: uri=/myapp/sample/index;client=0:0:0:0:0:0:0:1;session=FBDC27659D49A5EB8C257F25922DA45B\n Request attributes:\n applicationContextIdFilter.FILTERED: true\n characterEncodingFilter.FILTERED: true\n grailsWebRequestFilter.FILTERED: true\n hiddenHttpMethodFilter.FILTERED: true\n metricFilter.FILTERED: true\n org.grails.ACTION_NAME_ATTRIBUTE: index\n org.grails.CONTROLLER_NAME_ATTRIBUTE: sample\n org.grails.RESPONSE_FORMATS: [MimeType { name=*/*,extension=all,parameters=[q:1.0] }]\n org.grails.WEB_REQUEST: ServletWebRequest: uri=/myapp/sample/index;client=0:0:0:0:0:0:0:1;session=FBDC27659D49A5EB8C257F25922DA45B\n org.grails.url.match.info: org.grails.web.mapping.mvc.GrailsControllerUrlMappingInfo@4989bb9a\n org.springframework.web.context.request.async.WebAsyncManager.WEB_ASYNC_MANAGER: org.springframework.web.context.request.async.WebAsyncManager@34ecd5c7\n org.springframework.web.servlet.DispatcherServlet.CONTEXT: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@9cd25ff: startup date [Fri Apr 17 17:12:42 JST 2015]; root of context hierarchy\n org.springframework.web.servlet.DispatcherServlet.FLASH_MAP_MANAGER: org.springframework.web.servlet.support.SessionFlashMapManager@57be88bf\n org.springframework.web.servlet.DispatcherServlet.LOCALE_RESOLVER: org.springframework.web.servlet.i18n.SessionLocaleResolver@3999a99f\n org.springframework.web.servlet.DispatcherServlet.OUTPUT_FLASH_MAP: [:]\n org.springframework.web.servlet.DispatcherServlet.THEME_RESOLVER: org.springframework.web.servlet.theme.FixedThemeResolver@454ef3ee\n org.springframework.web.servlet.DispatcherServlet.THEME_SOURCE: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@9cd25ff: startup date [Fri Apr 17 17:12:42 JST 2015]; root of context hierarchy\n webRequestLoggingFilter.FILTERED: true\n Request parameters:\n action: index\n controller: sample\n Session attributes:\n org.grails.FLASH_SCOPE: [:]\n Cookies:\n JSESSIONID: FBDC27659D49A5EB8C257F25922DA45B (domain=null, path=null, maxAge=-1, secure=false, comment=null)\n\nAfter Action (time: 0.009[sec])\n Request ID: ServletWebRequest: uri=/myapp/sample/index;client=0:0:0:0:0:0:0:1;session=FBDC27659D49A5EB8C257F25922DA45B\n Request parameters:\n action: index\n controller: sample\n Session attributes:\n org.grails.FLASH_SCOPE: [:]\n Cookies:\n JSESSIONID: FBDC27659D49A5EB8C257F25922DA45B (domain=null, path=null, maxAge=-1, secure=false, comment=null)\n\nAfter View (time: 0.011[sec])\n Request ID: ServletWebRequest: uri=/myapp/sample/index;client=0:0:0:0:0:0:0:1;session=FBDC27659D49A5EB8C257F25922DA45B\n Request parameters:\n action: index\n controller: sample\n Session attributes:\n org.grails.FLASH_SCOPE: [:]\n Cookies:\n JSESSIONID: FBDC27659D49A5EB8C257F25922DA45B (domain=null, path=null, maxAge=-1, secure=false, comment=null)\n</code></pre>\n<h2>Configuration</h2>\n<h3>Logging</h3>\n<p>You can configure log settings (e.g. log level) by using the following FQCN of the interceptor.</p>\n<pre><code>grails.app.controllers.request.tracelog.RequestTracelogInterceptor\n</code></pre>\n<h2>Code Status</h2>\n<p><a href=\"https://travis-ci.org/nobeans/grails-request-tracelog\"><img src=\"https://travis-ci.org/nobeans/grails-request-tracelog.svg?branch=master\" alt=\"Build Status\" /></a></p>\n<h2>License</h2>\n<p>This is released under the <a href=\"http://www.apache.org/licenses/LICENSE-2.0\">Apache 2.0 License</a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "rest-awesome", |
| "repo": "plugins", |
| "owner": "troutbird", |
| "desc": null, |
| "labels": [ |
| "pagination", |
| "rest", |
| "json" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/ejaz-ahmed/grails-rest-awesome-plugin/issues", |
| "latestVersion": "0.2.0", |
| "updated": "2016-03-31T13:31:54.825Z", |
| "systemIds": [ |
| "org.grails.plugins:rest-awesome" |
| ], |
| "vcsUrl": "https://github.com/ejaz-ahmed/grails-rest-awesome-plugin" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>grails-rest-awesome-plugin - Sponsored by SaaSMax</h1>\n<p>This plugin adds pagination support to the default REST response of grails applications.\nI've plan to add search and include/exclude fields in future.</p>\n<h2>Installation</h2>\n<pre><code>compile 'org.grails.plugins:rest-awesome:0.2.0'\n</code></pre>\n<h2>Using this plugin</h2>\n<p>This plugin includes a sample application to which can also be referred.</p>\n<p>In order to use this plugin, you will have to first register the custom marshaller provided by this plugin.\nIf you have a domain class such as Book as shown below:</p>\n<pre><code>class Book {\n String title\n Double price\n\n static constraints = {\n }\n}\n</code></pre>\n<p>You have to register two marshallers for this class (one for collection and one for individual item)</p>\n<p>To do so, add following lines to your grails/app/conf/spring/resources.groovy file</p>\n<pre><code>import demo.Book\nimport org.grails.plugins.restawesome.renderer.ApiCollectionRendererJson\nimport org.grails.plugins.restawesome.renderer.ApiRendererJson\n\nbeans = {\n bookRenderer(ApiRendererJson, Book) {\n label = "book"\n }\n\n bookCollectionRenderer(ApiCollectionRendererJson, Book) {\n label = "books"\n }\n}\n\n</code></pre>\n<p>label is optional. If you provide, it will use the provided label otherwise it has a fallback value which\nis "entity" for individual item and "entities" for collection.</p>\n<p>After registering marshallers, you will have to extend "AwesomeRestfulController" provided by this plugin.</p>\n<p>Our sample BookController should look like this.</p>\n<pre><code>package demo\n\nimport org.grails.plugins.restawesome.AwesomeRestfulController\n\nclass BookController extends AwesomeRestfulController {\n\n static responseFormats = ['json']\n\n BookController(){\n super(Book)\n }\n}\n</code></pre>\n<h2>What will you get?</h2>\n<p>Here is sample output of curl request to this plugin.</p>\n<pre><code>curl http://localhost:8080/book\n{"books":[\n{"class":"demo.Book","id":1,"price":33.2,"title":"Grails in Action"},\n{"class":"demo.Book","id":2,"price":20.2,"title":"Groovy in Action"}],\n"paging":{"totalCount":2,"currentMax":10,"curentOffset":0}}\n</code></pre>\n<p>You can also sort this response with any of the attributes of Book class. To sort with price,</p>\n<pre><code>curl http://localhost:8080/book?sort=price\n{"books":[\n{"class":"demo.Book","id":2,"price":20.2,"title":"Groovy in Action"},\n{"class":"demo.Book","id":1,"price":33.2,"title":"Grails in Action"}],\n"paging":{"totalCount":2,"currentMax":10,"curentOffset":0}}\n</code></pre>\n<p>We can also change the order of sort like "desc" or "asc".</p>\n<p>Sorted by price in descending order:</p>\n<pre><code>curl "http://localhost:8080/book?sort=price&order=desc"\n{"books":[\n{"class":"demo.Book","id":1,"price":33.2,"title":"Grails in Action"},\n{"class":"demo.Book","id":2,"price":20.2,"title":"Groovy in Action"}],\n"paging":{"totalCount":2,"currentMax":10,"curentOffset":0}}\n</code></pre>\n<p>Sorted by price in ascending order:</p>\n<pre><code>curl "http://localhost:8080/book?sort=price&order=asc"\n{"books":[\n{"class":"demo.Book","id":2,"price":20.2,"title":"Groovy in Action"},\n{"class":"demo.Book","id":1,"price":33.2,"title":"Grails in Action"}],\n"paging":{"totalCount":2,"currentMax":10,"curentOffset":0}}\n</code></pre>\n<h1>About SaaSMax</h1>\n<p><a href=\"https://saasmax.com\">SaaSMAX</a> is the growth engine for SaaS companies and their resellers. Our mission is all about recurring SaaS commissions.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "retina-tag", |
| "repo": "grails3-plugins", |
| "owner": "bertramlabs", |
| "desc": "Adds retina resolution image tag support for asset-pipeline.", |
| "labels": [ |
| "image", |
| "retina" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/bertramdev/retina-tag-grails/issues", |
| "latestVersion": "3.0.0", |
| "updated": "2017-11-07T07:34:50.354Z", |
| "systemIds": [ |
| "com.bertramlabs.plugins:retina-tag" |
| ], |
| "vcsUrl": "https://github.com/bertramdev/retina-tag-grails" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>RetinaTag</h1>\n<p>The Grails Retina Tag plugin adds retina tag image support to the asset pipeline <code><asset:image/></code> taglib.\nRetinaTag resolves this by extending <code><asset:image/></code> to create a <code>hidpi_src</code> attribute with the retina image path if it exists.</p>\n<h2>Installation</h2>\n<p>Add retina tag to your build config</p>\n<pre><code>plugins {\n\tcompile ':retina-tag:1.1.0'\n}\n</code></pre>\n<h3>Grals 3</h3>\n<pre><code>dependencies {\n\tcompile 'com.bertramlabs.plugins:retina-tag:3.0.0'\n}\n</code></pre>\n<h2>Usage</h2>\n<p>Add <code>retina_tag.js</code> to your application.js file after including jQuery:</p>\n<pre><code>//=require retina_tag\n</code></pre>\n<p>Add double pixel resolution images in your assets directory with the @2x modifier</p>\n<pre><code>logo.png\nlogo@2x.png\n</code></pre>\n<p>Be sure to also specify the base dimensions in your <code>image_tag</code> calls:</p>\n<pre><code><asset:image src='logo.png' height=50/>\n</code></pre>\n<p>Awesome right?</p>\n<h3>Forcing Refresh after loading dynamic content</h3>\n<p>Retina tag listens to the global event on document called <code>retina_tag:refresh</code>. Firing this event will force retina_tag to rescan the dom for images and update their image src if necessary. Useful if loading content dynamically. <strong>Note:</strong> retina_tag automatically supports turbolinks.</p>\n<h3>Override Hidpi src attribute</h3>\n<p>In some cases it becomes necessary to override the data-hidpi-src attribute and skip asset pipeline. A good example of this might be to load a users profile picture which is stored elsewhere.</p>\n<pre><code>\t<asset:image src="${user.photo.url('medium')}" data-hidpi-src="${user.photo.url('medium_2x')" height="75%" width="75"/>\n</code></pre>\n<h2>Contributing</h2>\n<ol>\n<li>Fork it</li>\n<li>Create your feature branch (<code>git checkout -b my-new-feature</code>)</li>\n<li>Commit your changes (<code>git commit -am 'Added some feature'</code>)</li>\n<li>Push to the branch (<code>git push origin my-new-feature</code>)</li>\n<li>Create new Pull Request</li>\n</ol>\n<p>##License\nThis project is licensed under the APACHE License.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "rx-gorm-rest-client", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Provides a RxGORM Object Mapping implementation for communication with REST web services", |
| "labels": [ |
| "gorm", |
| "json", |
| "rest", |
| "rxjava" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/gorm-rest-client/issues", |
| "latestVersion": "1.1.0.RELEASE", |
| "updated": "2017-03-27T14:02:29.543Z", |
| "systemIds": [ |
| "org.grails.plugins:rx-gorm-rest-client" |
| ], |
| "vcsUrl": "https://github.com/grails/gorm-rest-client" |
| }, |
| "documentationUrl": "http://gorm.grails.org/latest/rx/rest-client/manual/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>RxGORM REST Client</h1>\n<p>This project implements <a href=\"http://gorm.grails.org/latest/rx\">RxGORM</a> for REST web services.</p>\n<ul>\n<li><a href=\"http://gorm.grails.org/latest/rx/rest-client/manual/\">Latest Documentation</a></li>\n<li><a href=\"http://gorm.grails.org/latest/rx/rest-client/api/\">Latest API</a></li>\n</ul>\n<p>The snapshot documentation is available here:</p>\n<ul>\n<li><a href=\"http://gorm.grails.org/snapshot/rx/rest-client/manual/\">Snapshot Documentation</a></li>\n<li><a href=\"http://gorm.grails.org/snapshot/rx/rest-client/api/\">Snapshot API</a></li>\n<li><a href=\"https://travis-ci.org/grails/gorm-rest-client\"><img src=\"https://travis-ci.org/grails/gorm-rest-client.svg?branch=master\" alt=\"Build Status\" /></a></li>\n</ul>\n" |
| }, |
| { |
| "comment": "Hard to tell versions to use here. According to https://gorm.grails.org/latest/rx/manual/ it is 7.3.2 but the latest release of this plugin is 6.1.7", |
| "bintrayPackage": { |
| "name": "rx-mongodb", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "GORM - Grails Data Access Framework", |
| "labels": [ |
| "gorm", |
| "mongodb", |
| "rxjava" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/gorm-mongodb/issues", |
| "latestVersion": "6.1.7", |
| "updated": "2020-07-06T19:52:37.703Z", |
| "systemIds": [ |
| "org.grails.plugins:rx-mongodb" |
| ], |
| "vcsUrl": "https://github.com/grails/gorm-mongodb" |
| }, |
| "documentationUrl": "https://gorm.grails.org/latest/rx/manual/", |
| "mavenMetadataUrl": null, |
| "readme": "<p><img src=\"https://github.com/grails/gorm-mongodb/workflows/Java%20CI/badge.svg?branch=master\" alt=\"Java CI\" />\n<img src=\"https://github.com/grails/gorm-mongodb/workflows/Release/badge.svg?branch=master\" alt=\"Release\" /></p>\n<h1>GORM for MongoDB</h1>\n<p>This project implements <a href=\"http://gorm.grails.org/latest/\">GORM</a> for the MongoDB Document Database.</p>\n<p>NOTE: This source code here is for version 6.x and above. For prevoius versions' source see the relevant branch on the <a href=\"https://github.com/grails/grails-data-mapping/tree/5.x/grails-datastore-gorm-mongodb\">Grails Data Mapping project</a>.</p>\n<p>For more information see the following links:</p>\n<ul>\n<li><a href=\"http://gorm.grails.org/latest/mongodb/manual\">Documentation</a></li>\n<li><a href=\"http://gorm.grails.org/latest/mongodb/api\">API</a></li>\n<li><a href=\"https://grails.org/plugins.html#plugin/mongodb\">Grails Plugin</a></li>\n</ul>\n<p>For the current development version see the following links:</p>\n<ul>\n<li><a href=\"http://gorm.grails.org/snapshot/mongodb/manual\">Beta Documentation</a></li>\n<li><a href=\"http://gorm.grails.org/snapshot/mongodb/api\">Beta API</a></li>\n</ul>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "rxjava", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "A plugin that integrates Grails with RxJava", |
| "labels": [ |
| "async", |
| "rxjava" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/grails-rxjava/issues", |
| "latestVersion": "1.1.1", |
| "updated": "2017-06-23T14:20:16.572Z", |
| "systemIds": [ |
| "org.grails.plugins:rxjava" |
| ], |
| "vcsUrl": "https://github.com/grails-plugins/grails-rxjava" |
| }, |
| "documentationUrl": "https://grails-plugins.github.io/grails-rxjava/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>RxJava for Grails</h1>\n<p><a href=\"https://github.com/ReactiveX/RxJava\">RxJava</a> is a popular library for composing asynchronous and event-based programs by using observable sequences.</p>\n<p>RxJava helps you build reactive applications and an increasing number of libraries take advantage of RxJava as the defacto standard for building Reactive applications.</p>\n<p>In <a href=\"http://gorm.grails.org/6.0.x\">GORM 6.0</a>, a new implementation of GORM called <a href=\"http://gorm.grails.org/6.0.x/rx/manual\">RxGORM</a> has been introduced that builds on RxJava helping you building reactive data access logic using the familiar GORM API combined with RxJava.</p>\n<p>This plugin helps integrate RxJava with the controller layer of Grails to complete the picture and enable complete end-to-end integration of RxJava with Grails.</p>\n<h2>Installation</h2>\n<p>To install the plugin declare a dependency in <code>build.gradle</code>:</p>\n<pre><code class=\"language-groovy\">dependencies {\n ...\n compile 'org.grails.plugins:rxjava:{version}'\n}\n</code></pre>\n<p>Where <code>{version}</code> is the version of the plugin.</p>\n<h2>Documentation</h2>\n<p>For further information see the the <a href=\"http://grails-plugins.github.io/grails-rxjava/latest/\">User guide</a>.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "rxjava2", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "A plugin that integrates Grails with RxJava", |
| "labels": [ |
| "async", |
| "rxjava2" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/grails-rxjava/issues", |
| "latestVersion": "2.0.0", |
| "updated": "2017-06-23T14:30:22.835Z", |
| "systemIds": [ |
| "org.grails.plugins:rxjava2" |
| ], |
| "vcsUrl": "https://github.com/grails-plugins/grails-rxjava" |
| }, |
| "documentationUrl": "https://grails-plugins.github.io/grails-rxjava/latest/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>RxJava for Grails</h1>\n<p><a href=\"https://github.com/ReactiveX/RxJava\">RxJava</a> is a popular library for composing asynchronous and event-based programs by using observable sequences.</p>\n<p>RxJava helps you build reactive applications and an increasing number of libraries take advantage of RxJava as the defacto standard for building Reactive applications.</p>\n<p>In <a href=\"http://gorm.grails.org/6.0.x\">GORM 6.0</a>, a new implementation of GORM called <a href=\"http://gorm.grails.org/6.0.x/rx/manual\">RxGORM</a> has been introduced that builds on RxJava helping you building reactive data access logic using the familiar GORM API combined with RxJava.</p>\n<p>This plugin helps integrate RxJava with the controller layer of Grails to complete the picture and enable complete end-to-end integration of RxJava with Grails.</p>\n<h2>Installation</h2>\n<p>To install the plugin declare a dependency in <code>build.gradle</code>:</p>\n<pre><code class=\"language-groovy\">dependencies {\n ...\n compile 'org.grails.plugins:rxjava:{version}'\n}\n</code></pre>\n<p>Where <code>{version}</code> is the version of the plugin.</p>\n<h2>Documentation</h2>\n<p>For further information see the the <a href=\"http://grails-plugins.github.io/grails-rxjava/latest/\">User guide</a>.</p>\n" |
| }, |
| { |
| "deprecated": "Duplicate entry of plugin with name 'csv' from the same author. This entry should probably be removed from the registry to avoid confusion.", |
| "bintrayPackage": { |
| "name": "sachinverma.plugins:csv", |
| "repo": "plugins", |
| "owner": "sachinverma", |
| "desc": "Grails csv plugin", |
| "labels": [ |
| "csv" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/vsachinv/grails-csv/issues", |
| "latestVersion": "1.0", |
| "updated": "2017-11-15T13:55:57.791Z", |
| "systemIds": [ |
| "org.grails.plugins:csv" |
| ], |
| "vcsUrl": "https://github.com/vsachinv/grails-csv" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>grails-csv</h1>\n<p>The csv plugin provides utility methods and also support for reading/writing to csv files. It uses <code>opencsv</code> library.</p>\n<h1>Installation</h1>\n<p>Add dependency to your build.gradle for Grails 3.x:</p>\n<pre><code>repositories {\n ...\n maven { url "http://dl.bintray.com/sachinverma/plugins" }\n}\n\ndependencies {\n compile 'org.grails.plugins:grails-csv:1.0.1'\n}\n</code></pre>\n<p>For further info: [https://github.com/vsachinv/grails-csv/wiki/Grails-CSV]</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "sass-asset-pipeline", |
| "repo": "asset-pipeline", |
| "owner": "bertramlabs", |
| "desc": "Provides fast and easy .sass and .scss file support for Transpiling to CSS. This plugin takes advantage of jsass and libsass for maximum performance.", |
| "labels": [ |
| "asset-pipeline", |
| "sass", |
| "css" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/bertramdev/asset-pipeline/issues", |
| "latestVersion": "5.0.9", |
| "updated": "2025-04-13T23:20:16.000Z", |
| "systemIds": [ |
| "com.bertramlabs.plugins:sass-asset-pipeline" |
| ], |
| "vcsUrl": "https://github.com/bertramdev/asset-pipeline" |
| }, |
| "documentationUrl": "https://bertramdev.github.io/asset-pipeline/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/com/bertramlabs/plugins/sass-asset-pipeline/maven-metadata.xml", |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "scaffolding", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "The Grails\u00ae framework Scaffolding plugin replicates much of the functionality from Grails 2, but uses the fields plugin instead.", |
| "labels": [ |
| "scaffolding" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/scaffolding/issues", |
| "latestVersion": "5.1.3", |
| "updated": "2024-11-20T12:41:42.000Z", |
| "systemIds": [ |
| "org.grails.plugins:scaffolding" |
| ], |
| "vcsUrl": "https://github.com/grails/scaffolding" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/grails/plugins/scaffolding/maven-metadata.xml", |
| "readme": null |
| }, |
| { |
| "deprecated": "Source repository is archived.", |
| "bintrayPackage": { |
| "name": "schwartz", |
| "repo": "grails-plugins", |
| "owner": "agileorbit", |
| "desc": "Quartz integration", |
| "labels": [ |
| "quartz", |
| "scheduling" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/agileorbit/grails-schwartz/issues", |
| "latestVersion": "2.0.0.RC1", |
| "updated": "2019-07-29T21:12:37.343Z", |
| "systemIds": [ |
| "com.agileorbit:schwartz" |
| ], |
| "vcsUrl": "https://github.com/agileorbit/grails-schwartz/" |
| }, |
| "documentationUrl": "https://agileorbit.github.io/grails-schwartz/", |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/agileorbit/grails-schwartz\"><img src=\"https://travis-ci.org/agileorbit/grails-schwartz.svg?branch=master\" alt=\"Build Status\" /></a></p>\n<h1>Grails Schwartz Plugin</h1>\n<p>The Schwartz plugin integrates the <a href=\"http://www.quartz-scheduler.org/\">Quartz Enterprise</a> Job Scheduler with Grails, making it easy to schedule and manage recurring and ad-hoc jobs for asynchronous and synchronous processing.</p>\n<p>The plugin is similar at a high level to the <a href=\"https://github.com/grails-plugins/grails-quartz\">Quartz plugin</a> in that it makes it easy to schedule Quartz Jobs and Triggers without having to deal directly with the Quartz API and mindset. But if you are used to working with Quartz directly you can continue to do so with this plugin - it provides convenience classes and Traits to make job scheduling easier, but you have a lot of flexibility in how you perform the various tasks.</p>\n<h2>Usage</h2>\n<pre><code>buildscript {\n repositories {\n ...\n }\n dependencies {\n classpath "org.grails:grails-gradle-plugin:$grailsVersion"\n ...\n classpath 'com.agileorbit:schwartz:1.0.1'\n }\n}\n\ndependencies {\n ...\n compile 'com.agileorbit:schwartz:1.0.1'\n ...\n}\n\n</code></pre>\n<h2>Documentation</h2>\n<p>http://agileorbit.github.io/grails-schwartz</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "schwartz-monitor", |
| "repo": "plugins", |
| "owner": "symentis", |
| "desc": "Grails Plugin to Monitor Schwartz- or Quartz Plugin Jobs", |
| "labels": [ |
| "quartz", |
| "scheduling" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/symentis/grails-schwartz-monitor/issues", |
| "latestVersion": "2.0.2", |
| "updated": "2019-03-01T11:53:11.524Z", |
| "systemIds": [ |
| "org.grails.plugins:schwartz-monitor" |
| ], |
| "vcsUrl": "https://github.com/symentis/grails-schwartz-monitor" |
| }, |
| "documentationUrl": "https://symentis.github.io/grails-schwartz-monitor/", |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/robertoschwald/grails-schwartz-monitor\"><img src=\"https://travis-ci.org/robertoschwald/grails-schwartz-monitor.svg?branch=master\" alt=\"Build Status\" /></a></p>\n<h1>Schwartz Monitor Plugin for Grails</h1>\n<p>This plugin is a fork of the <a href=\"https://grails.org/plugin/quartz-monitor\">quartz-monitor</a> plugin and supports\nthe Grails <a href=\"https://plugins.grails.org/plugin/quartz\">Quartz</a> and Grails <a href=\"https://plugins.grails.org/plugin/schwartz\">Schwartz</a> plugins.</p>\n<p>It allows you to view and administer all your Quartz job services in the web-ui.</p>\n<h2>Prerequisites</h2>\n<p>This plugin requires the <a href=\"http://plugins.grails.org/plugin/grails/quartz\">Grails Quartz</a>\nor <a href=\"http://plugins.grails.org/plugin/agileorbit/schwartz\">Grails Schwartz</a>\nand <a href=\"http://grails.org/plugin/asset-pipeline\">Asset Pipeline</a> plugins to run.</p>\n<h2>Installation</h2>\n<p>Add the plugin to your build.gradle dependencies:</p>\n<pre><code class=\"language-groovy\">dependencies {\n ...\n compile "org.grails.plugins:schwartz-monitor:2.0.1"\n}\n</code></pre>\n<h2>Usage</h2>\n<p>Once you have the schwartz-monitor plugin installed and have created some job services, start your application and access the URL:\nhttp://localhost:8080/yourapp/quartz and you will find a list of all the Quartz job services you have created.</p>\n<h2>Enhanced Experience</h2>\n<p>To have the page keep you constantly up to date requires <a href=\"http://grails.org/plugin/jquery\">jQuery</a>. It will still work without jQuery,\nbut it won't look as good.</p>\n<h2>Configuration</h2>\n<p>There are various configuration options, all start with <code>quartz.monitor</code>:</p>\n<h3>layout</h3>\n<p>Allows you to change the sitemesh layout that page will use. Defaults to 'main'.</p>\n<h3>showTriggerNames</h3>\n<p>If this is set to true, then the names of the triggers will be shown in the list - useful if you have multiple triggers for the same job.</p>\n<h3>showCountdown</h3>\n<p>Will add javascript to the page in order to show a countdown to when the job will fire next, unless this is set to 'false'.</p>\n<h3>showTickingClock</h3>\n<p>Will add javascript to the page in order to show a clock with the current time, unless this is set to 'false'.</p>\n<h2>URL Mapping the Controller</h2>\n<p>By default, the plugin does not set an URL-Mapping for the Schwartz Controller. Add a url-mapping to your URLMappings.groovy file:</p>\n<pre><code>"/quartz/$action?"(controller:"quartz")\n</code></pre>\n<h2>Securing the Controller</h2>\n<p>If you use a security plugin (Spring-Security-Core, etc), you must ensure the controller methods are secured. E.g. when using Spring-Security-Core, add a rule which is appropriate for your security needs:</p>\n<pre><code class=\"language-groovy\">[pattern:'/quartz/**', access:['ROLE_ADMIN']]\n</code></pre>\n<h2>Documentation</h2>\n<p>http://robertoschwald.github.io/grails-schwartz-monitor</p>\n<h2>Internals</h2>\n<p>Compared to the quartz-monitor plugin, this plugin is agnostic to the used quartz plugin, as it relies on Quartz itself and does not extend\nany quartz-plugin factories.\nIts implemented to register a org.quartz.JobListener, which listens to all Job tasks.\nThis listener updates Job metrics in the QuartzMonitorService, which also provides additional figures like the startTime of a Job.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "security-bridge", |
| "repo": "grails3-plugins", |
| "owner": "bertramlabs", |
| "desc": "Defines a standard corss-plugin security bridge implementation for better decoupling of authentication in plugin heavy applications.", |
| "labels": [ |
| "cors", |
| "security" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/bertramdev/grails-security-bridge/issues", |
| "latestVersion": "7.0.0", |
| "updated": "2024-12-30T16:59:22.000Z", |
| "systemIds": [ |
| "com.bertramlabs.plugins:grails-security-bridge", |
| "com.bertramlabs.plugins:security-bridge" |
| ], |
| "vcsUrl": "https://github.com/bertramdev/grails-security-bridge" |
| }, |
| "documentationUrl": "https://bertramdev.github.io/grails-security-bridge/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/com/bertramlabs/plugins/grails-security-bridge/maven-metadata.xml", |
| "readme": "<h1>Grails Security Bridge</h1>\n<p>The Grails Security Bridge plugin is used for providing a decoupled, cross-plugin security interface. This allows you to keep the majority of authentication logic in one plugin, while other plugins can reference a public API interface to retrieve the information needed.</p>\n<h2>Documentation</h2>\n<p>http://bertramdev.github.io/grails-security-bridge</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "seed-me", |
| "repo": "grails3-plugins", |
| "owner": "bertramlabs", |
| "desc": "Implements a standard convention for adding seed data to your application..", |
| "labels": [ |
| "seed" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/bertramdev/seed-me/issues", |
| "latestVersion": "7.0.0", |
| "updated": "2024-12-30T17:01:18.000Z", |
| "systemIds": [ |
| "com.bertramlabs.plugins:seed-me" |
| ], |
| "vcsUrl": "https://github.com/bertramdev/seed-me" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/com/bertramlabs/plugins/seed-me/maven-metadata.xml", |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "segment", |
| "repo": "plugins", |
| "owner": "agorapulse", |
| "desc": "Grails Segment plugin", |
| "labels": [ |
| "segment" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/agorapulse/grails-segmentio/issues", |
| "latestVersion": "3.0.0", |
| "updated": "2019-07-24T08:37:47.020Z", |
| "systemIds": [ |
| "org.grails.plugins:segment" |
| ], |
| "vcsUrl": "https://github.com/agorapulse/grails-segmentio" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Segment Grails Plugin</h1>\n<p><a href=\"https://travis-ci.org/agorapulse/grails-segment\"><img src=\"https://travis-ci.org/agorapulse/grails-segment.png\" alt=\"Build Status\" /></a>\n<a href=\"https://bintray.com/agorapulse/plugins/segment/_latestVersion\"><img src=\"https://api.bintray.com/packages/agorapulse/plugins/segment/images/download.svg\" alt=\"Download\" /></a></p>\n<h1>Introduction</h1>\n<p>The <strong>Segment Plugin</strong> allows you to integrate <a href=\"http://segment.com\">Segment</a> in your <a href=\"http://grails.org\">Grails</a> application.</p>\n<p>Segment lets you send your analytics data to any service you want, without you having to integrate with each one individually.</p>\n<p>It provides the following Grails artefacts:</p>\n<ul>\n<li><strong>SegmentService</strong> - A server side service client to call <a href=\"https://segment.com/docs/libraries/http/\">Segment APIs</a>, which is a wrapper around the official Segment <a href=\"https://segment.com/docs/libraries/java/\">Analytics for Java</a> library.</li>\n<li><strong>SegmentTagLib</strong> - A collection of tags to use <a href=\"https://segment.com/docs/libraries/analytics.js/\">Segment Analytics.js Library</a> in your GSPs.</li>\n</ul>\n<h1>Installation</h1>\n<p>Declare the plugin dependency in the <em>build.gradle</em> file, as shown here:</p>\n<pre><code class=\"language-groovy\">dependencies {\n ...\n compile "org.grails.plugins:segment:2.1.1"\n ...\n}\n</code></pre>\n<h1>Config</h1>\n<p>Create a <a href=\"http://segment.com\">Segment</a> account, in order to get your own <em>apiKey</em> (for client-side API calls).</p>\n<p>Add your Segment.io site <em>apiKey</em> to your <em>grails-app/conf/application.yml</em>:</p>\n<pre><code class=\"language-yml\">grails:\n plugin:\n segment:\n apiKey: {API_KEY} # Write key\n</code></pre>\n<p>By default, Segment integration will only be enabled for Production environments. If you need it to be enabled for other environments, make sure that it is explicitly enabled in your configs.</p>\n<pre><code class=\"language-yml\">grails:\n plugin:\n segment:\n enabled: true\n</code></pre>\n<p>If you're using Intercom, you can automatically enable Intercom secure mode (for <code>segment:identify</code>) by adding you Intercom secret key:</p>\n<pre><code class=\"language-yml\">grails:\n plugin:\n segment:\n intercomSecretKey: {INTERCOM_SECRET_KEY}\n</code></pre>\n<h1>Usage</h1>\n<h2>SegmentService</h2>\n<p>You can inject <em>segmentService</em> in any of your Grails artefacts (controllers, services...) in order to call <a href=\"https://segment.com/docs/libraries/\">Segment APIs</a>.</p>\n<pre><code class=\"language-groovy\">def segmentService\n\n// Identify and set traits\nsegmentService.identify('bob@bob.com', [gender: 'male'])\n\n// Identify and set traits with past date (JodaTime DateTime representing when the identify took place)\nsegmentService.identify(\n 'bob@bob.com',\n [gender: 'male'],\n new DateTime(2012, 3, 26, 12, 0, 0, 0)\n)\n\n// Identify and set traits with past date and context\nsegmentService.identify(\n 'bob@bob.com', [gender: 'male'],\n new DateTime(2012, 3, 26, 12, 0, 0, 0),\n [\n integrations: [\n 'All': false,\n 'Mixpanel': true,\n 'KISSmetrics': true\n ],\n ip: '192.168.0.10'\n ]\n)\n\n// Track an event\nsegmentService.track('bob@bob.com', 'Signed up')\n\n// Track an event and set properties\nsegmentService.track(\n 'bob@bob.com',\n 'Signed up',\n [plan: 'Pro', amount: 99.95]\n)\n\n// Track a past event and set properties with past date\nsegmentService.track(\n 'bob@bob.com', 'Signed up',\n [plan: 'Pro', amount: 99.95],\n new DateTime(2012, 3, 26, 12, 0, 0, 0)\n)\n\n// Track a past event and set properties with past date and context\nsegmentService.track(\n 'bob@bob.com',\n 'Signed up',\n [plan: 'Pro', amount: 99.95],\n new DateTime(2012, 3, 26, 12, 0, 0, 0),\n [\n integrations: [\n 'All': false,\n 'Mixpanel': true,\n 'KISSmetrics': true\n ],\n ip: '192.168.0.10'\n ]\n)\n\n// Group\nsegmentService.group('bob@bob.com', 'companyId', [\n name: 'The company name',\n website: 'http://www.company.com'\n])\n\n// Record page view\nsegmentService.page('bob@bob.com', 'Pricing')\n\n// Record page view with extra info\nsegmentService.page('bob@bob.com', 'Pricing', 'Business', [\n title: 'Segment.io Pricing',\n path: '/pricing'\n])\n\n// Record screen view\nsegmentService.screen('bob@bob.com', 'Register', 'Business', [\n type: 'facebook'\n])\n\n// Alias identity\nsegmentService.alias('bob@bob.com', 'bob')\n</code></pre>\n<h2>SegmentTagLib</h2>\n<p>To use <a href=\"https://segment.com/docs/libraries/analytics.js/\">Segment Analytics.js Library</a>, you must first initialize it in page header (most probably in you layout GSP).</p>\n<h1>JS Lib initialization</h1>\n<pre><code class=\"language-jsp\"><!DOCTYPE html>\n<html>\n<head>\n <segment:initJS/>\n</code></pre>\n<p>Or with default page view tracking disabled:</p>\n<pre><code class=\"language-jsp\"> <segment:initJS pageTracked="false"/>\n</code></pre>\n<h1>Identification and event recording</h1>\n<p>Once initialized, you can use <a href=\"https://segment.com/docs/libraries/analytics.js/\">Segment Analytics.js Library</a> in your GSP views.</p>\n<pre><code class=\"language-jsp\"><!-- Identify current user -->\n<segment:identify userId="bob@bob.com"/>\n\n<!-- Identify current user and set traits -->\n<segment:identify userId="bob@bob.com" traits="${[gender: 'male']}"/>\n\n<!-- Identify a group and set traits -->\n<segment:group groupId="power_users" traits="${[plan: 'silver']}"/>\n\n<!-- Identify current user with context -->\n<segment:identify\n userId="bob@bob.com"\n context="${[integrations: ['All': false, 'Mixpanel': true, 'KISSmetrics': true]]}"/>\n\n<!-- Track an event -->\n<segment:track event="Signed Up"/>\n\n<!-- Track an event and set properties -->\n<segment:track event="Signed Up" properties="${[plan: 'Pro', revenue: 99.95]}"/>\n\n<!-- Track an event with context -->\n<segment:track\n event="Signed Up"\n context="${[integrations: ['All': false, 'Google Analytics': true, 'Customer.io': true]]}"/>\n\n<!-- Track a link click -->\n<segment:trackLink\n event="Signed Up"\n link="\\$('a.signup-link')"\n properties="${[plan: 'Pro', revenue: 99.95]}"/>\n\n<!-- Track a form submission -->\n<segment:trackForm\n event="Signed Up"\n form="\\$('form.signup-form')"\n properties="${[plan: 'Pro', revenue: 99.95]}"/>\n\n<!-- Page view -->\n<segment:page category="Some category" name="Page title"/>\n\n<!-- Page view with name -->\n<segment:page name="Page title"/>\n\n<!-- Page view with category and name -->\n<segment:page category="Some category" name="Page title"/>\n\n<!-- Alias identity -->\n<segment:alias originalId="bob@bob.com" newId="bob"/>\n</code></pre>\n<h1>Bugs</h1>\n<p>To report any bug, please use the project <a href=\"http://github.com/agorapulse/grails-segment/issues\">Issues</a> section on GitHub.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "selfie", |
| "repo": "grails3-plugins", |
| "owner": "bertramlabs", |
| "desc": "Selfie is a Grails Image / File Upload Plugin. Use Selfie to attach files to your domain models, upload to a CDN, validate content, produce thumbnails.", |
| "labels": [ |
| "image", |
| "upload" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/bertramdev/selfie/issues", |
| "latestVersion": "7.0.0", |
| "updated": "2024-12-30T16:56:40.000Z", |
| "systemIds": [ |
| "com.bertramlabs.plugins:selfie" |
| ], |
| "vcsUrl": "https://github.com/bertramdev/selfie" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/com/bertramlabs/plugins/selfie/maven-metadata.xml", |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "sentry", |
| "repo": "plugins", |
| "owner": "agorapulse", |
| "desc": "Grails Sentry plugin", |
| "labels": [ |
| "sentry" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/agorapulse/grails-raven/issues", |
| "latestVersion": "11.7.25", |
| "updated": "2020-07-22T12:45:52.747Z", |
| "systemIds": [ |
| "org.grails.plugins:sentry" |
| ], |
| "vcsUrl": "https://github.com/agorapulse/grails-raven" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Sentry Grails Plugin</h1>\n<p><a href=\"https://travis-ci.org/agorapulse/grails-sentry\"><img src=\"https://secure.travis-ci.org/agorapulse/grails-sentry.png?branch=master\" alt=\"Build Status\" /></a>\n<a href=\"https://bintray.com/agorapulse/plugins/sentry/_latestVersion\"><img src=\"https://api.bintray.com/packages/agorapulse/plugins/sentry/images/download.svg\" alt=\"Download\" /></a></p>\n<h1>Introduction</h1>\n<p>Sentry plugin provides a Grails client for integrating apps with <a href=\"http://www.getsentry.com\">Sentry</a>.\n<a href=\"http://www.getsentry.com\">Sentry</a> is an event logging platform primarily focused on capturing and aggregating exceptions.</p>\n<p>It uses the official <a href=\"https://github.com/getsentry/sentry-java\">Sentry.io</a> client under the cover.</p>\n<h1>Installation</h1>\n<p>Declare the plugin dependency in the <em>build.gradle</em> file, as shown here:</p>\n<pre><code class=\"language-groovy\">dependencies {\n ...\n compile("org.grails.plugins:sentry:11.7.25")\n ...\n}\n</code></pre>\n<h1>Config</h1>\n<p>Add your Sentry DSN to your <em>grails-app/conf/application.yml</em>.</p>\n<pre><code class=\"language-yml\">grails:\n plugin:\n sentry:\n dsn: https://{PUBLIC_KEY}:{SECRET_KEY}@app.getsentry.com/{PATH}{PROJECT_ID}\n</code></pre>\n<p>The DSN can be found in project's <em>Settings</em> under <em>Client Keys (DSN)</em> section.</p>\n<p>The plugin will sent notifications to Sentry by default, if you want to disable notifications for an specific environment set the <code>active</code> option as false.</p>\n<pre><code class=\"language-yml\">environments:\n development:\n grails:\n plugin:\n sentry:\n active: false\n test:\n grails:\n plugin:\n sentry:\n active: false\n</code></pre>\n<p>You can also configure the multiple logger to which you want to append the sentry appender.\nYou can also set the server name, but it is recommended to don't set this configuration and let the plugin to resolve it.</p>\n<h2>Optional configurations</h2>\n<pre><code class=\"language-yml\"># Not tested on Grails 3 plugin...\ngrails:\n plugin:\n sentry:\n dsn: https://foo:bar@api.sentry.io/123\n loggers: [LOGGER1, LOGGER2, LOGGER3]\n environment: staging\n serverName: dev.server.com\n levels: [ERROR]\n tags: {tag1: val1, tag2: val2, tag3: val3}\n subsystems: \n MODULE1: [com.company.services.module1, com.company.controllers.module1]\n MODULE2: [com.company.services.module2, com.company.controllers.module2]\n MODULE3: [com.company.services.module3, com.company.controllers.module3]\n logClassName: true\n logHttpRequest: true\n disableMDCInsertingServletFilter: true\n springSecurityUser: true\n springSecurityUserProperties:\n id: 'id'\n email: 'emailAddress'\n username: 'login'\n data: # Additional properties to be retrieved from user details object and passed as extra properties to Sentry user interface.\n - 'authorities'\n priorities: \n HIGH: [java.lang, com.microsoft.sqlserver.jdbc.SQLServerException]\n MID: [com.company.exception]\n LOW: [java.io]\n</code></pre>\n<p>Check <a href=\"https://github.com/getsentry/sentry-java\">Sentry-java</a> documentation to configure connection, protocol and async options in your DSN. If you are sending extra tags from the plugin for the exceptions, make sure to enable the corresponding tag on sentry tag settings for the particular project to see the tag as a filter on the exception stream on sentry.</p>\n<h1>Usage</h1>\n<h2>Logback Appender</h2>\n<p>The Logback Appender is automatically configured by the plugin, you just have to set enabled environments as shown in Configuration section.</p>\n<p>All application exceptions will be logged on sentry by the appender.\nThe appender is configured to log just the <code>ERROR</code> and <code>WARN</code> levels.\nTo log manually just use the <code>log.error()</code> method.</p>\n<h2>sentryClient</h2>\n<p>You also can use <code>sentryClient</code> to sent info messages to Sentry:</p>\n<pre><code class=\"language-groovy\">import io.sentry.SentryClient\nimport io.sentry.event.Event\nimport io.sentry.event.EventBuilder\nimport io.sentry.event.interfaces.ExceptionInterface\n\nSentryClient sentryClient // To inject Spring bean raven client in your controllers or services\n\n// Send simple message\nsentryClient?.sendMessage("some message")\n\n// Send exception\nsentryClient?.sendException(new Exception("some exception"))\n\n// Custom event\nEventBuilder eventBuilder = new EventBuilder()\n .withMessage("This is a test")\n .withLevel(Event.Level.INFO)\n .withLogger(MyClass.class.name)\n\nsentryClient?.sendEvent(eventBuilder.build())\n</code></pre>\n<h1>Latest releases</h1>\n<ul>\n<li>2018-07-16 <strong>V11.7.25</strong> : upgrade Sentry java lib to 1.7.25 + stack trace sanitizer</li>\n<li>2018-07-16 <strong>V11.7.24</strong> : upgrade Sentry java lib to 1.7.24 + Grails 4 upgrade</li>\n<li>2018-05-18 <strong>V11.7.4</strong> : upgrade Sentry java lib to 1.7.4 + bug fixes</li>\n<li>2018-02-09 <strong>V11.6.5</strong> : upgrade Sentry java lib to 1.6.5 + bug fixes</li>\n<li>2017-11-09 <strong>V11.4.0.3</strong> : fixes</li>\n<li>2017-08-03 <strong>V11.4.0.2</strong> : fixes</li>\n<li>2017-08-03 <strong>V11.4.0</strong> : upgrade Sentry java lib to 1.4.0 + bug fix, thanks to <a href=\"https://github.com/donbeave\">donbeave</a> PR #37</li>\n<li>2017-07-17 <strong>V11.3.0</strong> : upgrade Sentry java lib to 1.3.0 + bug fix, thanks to <a href=\"https://github.com/donbeave\">donbeave</a> PR #34</li>\n<li>2017-07-04 <strong>V11.2.0</strong> : upgrade Sentry java lib to 1.2.0 (which replaces the deprecated Raven java lib)</li>\n<li>2017-06-06 <strong>V8.0.3</strong> : upgrade Raven java lib to 8.0.3</li>\n<li>2017-02-01 <strong>V7.8.1</strong> : upgrade Raven java lib to 7.8.1</li>\n<li>2016-11-22 <strong>V7.8.0.2</strong> : event environment support</li>\n<li>2016-10-29 <strong>V7.8.0.1</strong> : minor bug fix, thanks to <a href=\"https://github.com/donbeave\">donbeave</a> PR</li>\n<li>2016-10-19 <strong>V7.8.0</strong> : upgrade Raven java lib to 7.8.0</li>\n<li>2016-10-10 <strong>V7.7.1</strong> : upgrade Raven java lib to 7.7.1</li>\n<li>2016-09-27 <strong>V7.7.0.1</strong> : bug fix</li>\n<li>2016-09-26 <strong>V7.7.0</strong> : upgrade Raven java lib to 7.7.0, release support added to events</li>\n<li>2016-08-22 <strong>V7.6.0</strong> : upgrade Raven java lib to 7.6.0, Spring Security integration improvements, thanks to <a href=\"https://github.com/donbeave\">donbeave</a> PR</li>\n<li>2016-07-22 <strong>V7.4.0</strong> : upgrade Raven java lib to 7.4.0, better logging and support for Spring Security Core , thanks to <a href=\"https://github.com/donbeave\">donbeave</a> PR</li>\n<li>2016-06-22 <strong>V7.3.0</strong> : upgrade Raven java lib to 7.3.0</li>\n<li>2016-05-03 <strong>V7.2.1</strong> : upgrade Raven java lib to 7.2.1</li>\n<li>2016-04-12 <strong>V7.1.0.1</strong> : minor update</li>\n<li>2016-04-06 <strong>V7.1.0</strong> : upgrade Raven java lib to 7.1.0, thanks to <a href=\"https://github.com/donbeave\">donbeave</a> PR (WARNING: Raven package has been renamed from <code>net.kencochrane.raven</code> to <code>com.getsentry.raven</code>)</li>\n<li>2015-08-31 <strong>V6.0.0</strong> : initial release for Grails 3.x</li>\n</ul>\n<h2>Bugs</h2>\n<p>To report any bug, please use the project <a href=\"https://github.com/agorapulse/grails-raven/issues/new\">Issues</a> section on GitHub.</p>\n<h2>Contributing</h2>\n<p>Please contribute using <a href=\"https://guides.github.com/introduction/flow/\">Github Flow</a>. Create a branch, add commits, and <a href=\"https://github.com/agorapulse/grails-raven/compare/\">open a pull request</a>.</p>\n<h2>License</h2>\n<p>Copyright \ufffd\ufffd\ufffd\ufffd 2016 Alan Rafael Fachini, authors, and contributors. All rights reserved.</p>\n<p>This project is licensed under the Apache License, Version 2.0 - see the <a href=\"LICENSE\">LICENSE</a> file for details.</p>\n<h2>Maintained by</h2>\n<p><a href=\"https://www.agorapulse.com/\"><img src=\"https://cloud.githubusercontent.com/assets/139017/17053391/4a44735a-5034-11e6-8e72-9f4b7139d7e0.png\" alt=\"Agorapulse\" /></a> <strong>&</strong> <a href=\"https://www.scentbird.com/\"><img src=\"https://cloud.githubusercontent.com/assets/139017/17053392/4a4f343e-5034-11e6-95c9-f6371f7848f1.png\" alt=\"Scentbird\" /></a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "SimpleSuggestions3", |
| "repo": "plugins", |
| "owner": "nerderg", |
| "desc": "This is a simple, by convention, suggestion service to provide suggestions to auto complete controls.\nJust point the auto complete JS URL at suggest/[subject]?term=bla and you get a JSON list of suggestion strings back.\nYou can add suggestion handlers to the service as a closure, or just add a text file named [subject].txt with an itemper line to be searched for matches. The simple search returns a result if an item string contains the term anywhere.\nSee docs for details.", |
| "labels": [ |
| |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/nerdErg/simpleSuggestions3/issues", |
| "latestVersion": "1.1", |
| "updated": "2019-07-22T07:04:34.166Z", |
| "systemIds": [ |
| "com.nerderg.plugins:SimpleSuggestions3" |
| ], |
| "vcsUrl": "https://github.com/nerdErg/simpleSuggestions3" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<div class=\"paragraph\">\n<p>The Simple suggestions plugin provides a very simple service for providing suggestions to autocomplete widgets in your grails application.</p>\n</div>\n<div class=\"paragraph\">\n<p>It provides a suggest service that you can access at suggest/[subject]?term=blah, Where [subject] is the topic that needs a suggestion\n and the term \"blah\" is what has been entered by the user.</p>\n</div>\n<div class=\"paragraph\">\n<p>So if you have the jQuery and jQuery-UI plugins installed you could add Javascript code like this:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"title\">amazing.js</div>\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-javascript\" data-lang=\"javascript\"> $(\".suggest\").each(function () {\n var action = $(this).attr(\"class\").split(\" \")[1];\n var actionurl = baseContextPath + '/suggest/' + action;\n $(this).autocomplete({\n minLength:1,\n source:actionurl,\n select:function (event, ui) {\n $(this).val(ui.item.value);\n }\n });\n });</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>then just add a class to your input element like this:</p>\n</div>\n<div class=\"literalblock\">\n<div class=\"content\">\n<pre><input type=\"text\" class=\"suggest title\" size=\"40\"/></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>to get suggestions for a title.</p>\n</div>\n<div class=\"paragraph\">\n<p>The plugin provides a suggestService to provide the suggestions, all you need to do is place a directory in your project called\n\"suggestions\" which contains text files named after the subject with a .txt extension [subject].txt.</p>\n</div>\n<div class=\"paragraph\">\n<p>So for the title input above we’d put a title.txt file in the suggestions directory. that file would look something like this:</p>\n</div>\n<div class=\"literalblock\">\n<div class=\"content\">\n<pre>Mr\nMs\nMiss\nMrs\nMaster\nDr\nProfessor\nSir</pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>And that’s it, your input box will have suggestions served up.</p>\n</div>\n<div class=\"paragraph\">\n<p>You can configure where the suggestion files live by setting it in application.groovy like so:</p>\n</div>\n<div class=\"literalblock\">\n<div class=\"content\">\n<pre>suggest.data.directory = './mySuggestions'</pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>The directory is relative to the root directory of your app unless you make it an absolute path.</p>\n</div>\n<div class=\"paragraph\">\n<p>You can put the suggestion files in you Classpath if you like by setting the directory relative to your Classpath, and\nsetting the classpathResource option like this:</p>\n</div>\n<div class=\"literalblock\">\n<div class=\"content\">\n<pre>suggest.data.directory = 'mySuggestions'\nsuggest.data.classpathResource = true</pre>\n</div>\n</div>\n<div class=\"admonitionblock important\">\n<table>\n<tr>\n<td class=\"icon\">\n<div class=\"title\">Important</div>\n</td>\n<td class=\"content\">\nsuggestion files are loaded into memory once requested, and stay there for the life of the application, so bear that\n in mind with large data sets, you may want to provide a handler that accesses a database.\n</td>\n</tr>\n</table>\n</div>\n<div class=\"paragraph\">\n<p>If you need to provide more complex suggestions, perhaps using a database then just add a suggestion handler to the suggestService.\nFor example:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"title\">handler.groovy</div>\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-groovy\" data-lang=\"groovy\">def handler = { String term ->\n //do something interesting here, perhaps call another service\n //the handler has to return a list of things, normally Strings\n return [term, \"$term A\", \"$term B\"]\n}\nsuggestService.addSuggestionHandler('test', handler)</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>OR you can take both the subject and term in your handler like this:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"title\">handler.groovy</div>\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-groovy\" data-lang=\"groovy\">def handler = { String subject, String term ->\n //do something interesting here, perhaps call another service\n //the handler has to return a list of things, normally Strings\n return [term, \"$term A\", \"$term B\", subject]\n}\nsuggestService.addSuggestionHandler('test', handler)</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>You have to add the handler for all the subjects you expect…​ unless you replace the defaultSuggestionHandler\non the suggestService. To do that just set it in you bootstrap (or anywhere you like really) like this:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"title\">bootstrap.groovy</div>\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-groovy\" data-lang=\"groovy\">def suggestService\n\n...\n\nMyUBeautSuggestionHandler mubsh = MyUBeautSuggestionHandlerFactory.getMeOneOfThoseLittleBeauties(...)\n\nsuggestService.defaultSuggestionHandler = { String subject, String term ->\n mubsh(subject, term)\n}</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>The resultant list of things will be sent back as JSON, so if you send back a list of Maps or Objects they’ll be JSONified\nand sent to the caller, so you can do what you like with it.</p>\n</div>\n<div class=\"paragraph\">\n<p>If you are going to replace the defaultSuggestionHandler it’s best to log an error if you get a subject you don’t know about.\nJust sayin' :-)</p>\n</div>\n<div class=\"paragraph\">\n<p>That simple.</p>\n</div>" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "slack", |
| "repo": "grails-plugins", |
| "owner": "mathifonseca", |
| "desc": "Grails Slack Integration Plugin", |
| "labels": [ |
| "slack" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/mathifonseca/grails-slack/issues", |
| "latestVersion": "3.2.0", |
| "updated": "2017-08-20T18:12:02.476Z", |
| "systemIds": [ |
| "org.grails.plugins:slack", |
| "org.grails.plugins:grails-slack" |
| ], |
| "vcsUrl": "https://github.com/mathifonseca/grails-slack" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<p>#Grails Plugin for Slack integration using Webhooks</p>\n<p><a href=\"https://travis-ci.org/mathifonseca/grails-slack\"><img src=\"https://travis-ci.org/mathifonseca/grails-slack.svg?branch=master\" alt=\"Build Status\" /></a></p>\n<p>This plugin lets you send messages your Slack users or channels from a Grails application.</p>\n<p>##Installation</p>\n<p>Add this into your <code>build.gradle</code>:</p>\n<pre><code class=\"language-groovy\">repositories {\n\tmaven { url "http://dl.bintray.com/mathifonseca/grails-plugins" }\n}\ndependencies {\n\tcompile "org.grails.plugins:slack:3.0.0"\n}\n</code></pre>\n<p>##Configuration</p>\n<p>Before using the plugin, you need to create an Incoming Webhook in your Slack account. In summary, they are REST endpoints that you can send HTTP requests with a JSON payload containing the message data.</p>\n<p>Here is the documentation provided by Slack API page: https://api.slack.com/incoming-webhooks</p>\n<p>It will ask you to select a channel where it will post messages to. But don't worry, you can change that for each message you send later.</p>\n<p>After you've created the webhook, add this configuration to your <code>Config.groovy</code> (in your application):</p>\n<pre><code class=\"language-groovy\">slack {\n webhook = 'https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX'\n}\n</code></pre>\n<p>##Documentation</p>\n<p>###Slack API</p>\n<p>The idea behind the plugin is to create an easy to use and very straight forward DSL for the payload you need to send to the webhook. Basically, it's an adaptation of the Slack API documentation for message formatting and attachments. If you want to read about it and see more examples (and maybe make changes to the plugin), you can read the links that the plugin is based on:</p>\n<ul>\n<li>https://api.slack.com/docs/formatting</li>\n<li>https://api.slack.com/docs/attachments</li>\n<li>https://api.slack.com/docs/unfurling</li>\n</ul>\n<p>Please pay special attention to the URLs and Escaping section of the Formatting documentation, because the plugin can help you with the message structure but not with its content formatting.</p>\n<p>###Plugin DSL</p>\n<p>Your DSL will create an instance of the class <a href=\"src/groovy/grails/plugin/slack/SlackMessage.groovy\"><code>SlackMessage</code></a>, which will be encoded as JSON and posted to the Slack webhook. That class has a list of attachments, which are based on the class <a href=\"src/groovy/grails/plugin/slack/SlackMessageAttachment.groovy\"><code>SlackMessageAttachment</code></a>. And again, attachments have fields, which are based on the class <a href=\"src/groovy/grails/plugin/slack/SlackMessageAttachmentField.groovy\"><code>SlackMessageAttachmentField</code></a>. Check those classes to learn about the constraints for their fields.</p>\n<p>Some of the parameters you can send in the payload have a default value set in the plugin, as a kind of convention. Of course, if you don't like it, you can specify your own value in your message DSL. Here are the default values (check the links above to know what they mean):</p>\n<p>| argument | value |\n|---|---|\n| mrkdwn | true |\n| link_names | 1 |\n| parse | full |\n| unfurl_links | true |\n| unfurl_media | true |\n| short | false |</p>\n<p>##Usage</p>\n<p>The plugin provides a service called <a href=\"grails-app/services/grails/plugin/slack/SlackService.groovy\"><code>SlackService</code></a> (that was unexpected, right?). You can inject it in your services or controllers and use it's <code>send()</code> method to send your messages. This message receives a closure with the DSL you need to create your message.</p>\n<p>Here is an example that uses <strong>everything</strong> available for you. Most of the fields are optional or have default values, so this is kind of an exaggerated use case. Remember to check the constraints in the plugin classes and the documentation in Slack API to know what do each of these things mean and how they will look in your Slack client.</p>\n<pre><code class=\"language-groovy\">slackService.send {\n text 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras sit amet facilisis tortor. Proin dictum nibh urna, ac mattis magna semper sed.'\n username 'mathi'\n iconUrl 'https://s3.amazonaws.com/uifaces/faces/twitter/BillSKenney/128.jpg'\n iconEmoji ':hamburger:'\n channel '@mathi'\n markdown true\n linkNames 1\n parse 'full'\n unfurlLinks false\n unfurlMedia false\n attachment {\n fallback 'This is the fallback'\n color 'good'\n authorName 'Mathi Fonseca'\n authorLink 'https://github.com/mathifonseca'\n authorIcon 'https://avatars2.githubusercontent.com/u/4367808?v=3&s=460'\n title 'Some Title'\n titleLink 'http://example.com/title'\n text 'This is the attachment text'\n imageUrl 'http://wikitravel.org/upload/shared//thumb/f/fc/Montevideo.jpg/300px-Montevideo.jpg'\n markdownIn(['text','fields'])\n field {\n title 'Title1'\n value 'Some long attachment field value'\n isShort false\n }\n field {\n title 'Title2'\n value 'A short field'\n isShort true\n }\n field {\n title 'Title3'\n value 'Another short field'\n isShort true\n }\n }\n attachment {\n pretext 'This is the pretext'\n text 'This is another attachment'\n thumbUrl 'http://static1.squarespace.com/static/548a09b7e4b09cb7481d6e1d/t/5537e336e4b05a14c754b6d2/1429726013683/'\n }\n}\n</code></pre>\n<p>Note that the <code>attachment</code> and <code>field</code> closures are repeated. This will create a list of attachments for the message and a list of fields for the attachment respectively.</p>\n<p>This awfully long and complex example message will generate a message that will look like this in the Slack client for Mac:</p>\n<p><img src=\"slack.png\" alt=\"Slack Screenshot\" /></p>\n<p>###Exception throwing</p>\n<p>The <code>send()</code> method throws a <code>SlackMessageException</code>. You should catch it to get information about what went wrong with the message you tried to send. Here are some situations where that exception is thrown:</p>\n<ul>\n<li>The Slack webhook is not configured or invalid</li>\n<li>Constraint violation in any message field (specified in the exception message)</li>\n<li>Message couldn't be built by some strange reason (please post an <a href=\"https://github.com/mathifonseca/grails-slack/issues\">issue</a> if this happens, I will fix it right away)</li>\n<li>Any errors returned by Slack API when the message is posted (the message returned by them is contained in the exception message)</li>\n</ul>\n<p>###Unit tests</p>\n<p>There are many unit tests defined at <a href=\"test/unit/grails/plugin/slack/SlackServiceSpec.groovy\"><code>SlackServiceSpec</code></a>. It's hopefully passing :) It's focused on testing the DSL for message creation, so you can check it to compare with your code and maybe get some inspiration.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "soft-delete", |
| "repo": "plugins", |
| "owner": "danlobo", |
| "desc": "Provides Grails domain classes support for soft (or logical) deletes.", |
| "labels": [ |
| "delete" |
| ], |
| "licenses": [ |
| "MIT" |
| ], |
| "issueTrackerUrl": "https://github.com/danlobo/grails-soft-delete/issues", |
| "latestVersion": "0.5", |
| "updated": "2017-09-13T06:22:08.691Z", |
| "systemIds": [ |
| "org.grails.plugins:soft-delete" |
| ], |
| "vcsUrl": "https://github.com/danlobo/grails-soft-delete" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>grails-soft-delete</h1>\n<p>Provides Grails domain classes support for soft (or logical) deletes.</p>\n<h3>WARNING</h3>\n<p>This code is experimental. I can't garantee it will work, but I will improve it over time.</p>\n<h3>How to install</h3>\n<p>Slap the following code into <code>build.gradle</code>, dependencies part:</p>\n<p><code>compile 'org.grails.plugins:soft-delete:0.3'</code></p>\n<p>Alternatively you have to clone the repository, build the jar file and put it on a libs folder inside your application.</p>\n<h3>How it works</h3>\n<p>The plugin enhances all the domain classes using traits, overriding the common GORM methods.</p>\n<h3>What is supported</h3>\n<p>The following methods are supported:</p>\n<ul>\n<li>delete() (obvious, isn't it)</li>\n<li>get()</li>\n<li>load()</li>\n<li>getAll()</li>\n<li>list()</li>\n<li>first()</li>\n<li>last()</li>\n<li>findBy...(), findAllBy...(), countBy...()</li>\n<li>createCriteria()</li>\n</ul>\n<h3>What is not</h3>\n<p>Well, the world isn't perfect</p>\n<ul>\n<li>All methods that use string query</li>\n<li>find() (which uses closures)</li>\n</ul>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "spring-security-acl", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Grails spring-security-acl plugin", |
| "labels": [ |
| "security", |
| "spring-security", |
| "acl" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/grails-spring-security-acl/issues", |
| "latestVersion": "4.0.0.M2", |
| "updated": "2019-04-18T15:29:17.202Z", |
| "systemIds": [ |
| "org.grails.plugins:spring-security-acl" |
| ], |
| "vcsUrl": "https://github.com/grails-plugins/grails-spring-security-acl" |
| }, |
| "documentationUrl": "https://grails-plugins.github.io/grails-spring-security-acl/", |
| "mavenMetadataUrl": null, |
| "readme": "<p>[<img src=\"https://travis-ci.org/grails-plugins/grails-spring-security-acl.svg?branch=master\" alt=\"Build Status\" /></p>\n<h1>Grails Spring Security ACL Plugin</h1>\n<p>See <a href=\"https://grails-plugins.github.io/grails-spring-security-acl/\">documentation</a> for further information.</p>\n<h2>Developing this plugin</h2>\n<p>To run the tests exeucte:</p>\n<p><code>./gradlew -Dgeb.env=chromeHeadless check</code></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "spring-security-appinfo", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Grails spring-security-appinfo plugin", |
| "labels": [ |
| "spring-security" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/grails-spring-security-appinfo/issues", |
| "latestVersion": "3.0.1", |
| "updated": "2017-05-02T13:52:16.015Z", |
| "systemIds": [ |
| "org.grails.plugins:spring-security-appinfo" |
| ], |
| "vcsUrl": "https://github.com/grails-plugins/grails-spring-security-appinfo" |
| }, |
| "documentationUrl": "https://grails-plugins.github.io/grails-spring-security-appinfo/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails Spring Security AppInfo Plugin</h1>\n<p>See <a href=\"https://grails-plugins.github.io/grails-spring-security-appinfo/\">documentation</a> for further information.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "spring-security-cas", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "The CAS plugin adds CAS single sign-on support to a Grails application that uses Spring Security. It depends on the Spring Security Core plugin.", |
| "labels": [ |
| "security", |
| "spring-security", |
| "cas" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/grails-spring-security-cas/issues", |
| "latestVersion": "4.0.0", |
| "updated": "2024-01-26T07:29:57.000Z", |
| "systemIds": [ |
| "org.grails.plugins:spring-security-cas" |
| ], |
| "vcsUrl": "https://github.com/grails/grails-spring-security-cas" |
| }, |
| "documentationUrl": "https://grails.github.io/grails-spring-security-cas/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/grails/plugins/spring-security-cas/maven-metadata.xml", |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "spring-security-core", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Grails spring-security-core plugin", |
| "labels": [ |
| "security", |
| "spring-security" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/grails-spring-security-core/issues", |
| "latestVersion": "6.1.2", |
| "updated": "2024-12-06T22:10:14.000Z", |
| "systemIds": [ |
| "org.grails.plugins:spring-security-core" |
| ], |
| "vcsUrl": "https://github.com/grails/grails-spring-security-core" |
| }, |
| "documentationUrl": "https://grails.github.io/grails-spring-security-core/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/grails/plugins/spring-security-core/maven-metadata.xml", |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "spring-security-facebook", |
| "repo": "grails-plugins", |
| "owner": "splix", |
| "desc": "Grails spring-security-facebook plugin", |
| "labels": [ |
| "security", |
| "spring-security", |
| "facebook" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/splix/grails-spring-security-facebook/issues", |
| "latestVersion": "0.19.2", |
| "updated": "2017-11-07T07:29:37.704Z", |
| "systemIds": [ |
| "org.grails.plugins:spring-security-facebook" |
| ], |
| "vcsUrl": "https://github.com/splix/grails-spring-security-facebook" |
| }, |
| "documentationUrl": "http://splix.github.io/grails-spring-security-facebook/", |
| "mavenMetadataUrl": null, |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "spring-security-jaxrs", |
| "repo": "grails-plugins", |
| "owner": "budjb", |
| "desc": "A plugin that allows the use of Spring Security features with JAX-RS resources.", |
| "labels": [ |
| "security", |
| "spring-security", |
| "jax-rs" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/budjb/grails-spring-security-jaxrs/issues", |
| "latestVersion": "3.0.1", |
| "updated": "2017-03-09T15:01:25.269Z", |
| "systemIds": [ |
| "org.grails.plugins:spring-security-jaxrs" |
| ], |
| "vcsUrl": "https://github.com/budjb/grails-spring-security-jaxrs" |
| }, |
| "documentationUrl": "http://budjb.github.io/grails-spring-security-jaxrs/3.x/latest/", |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/budjb/grails-spring-security-jaxrs\"><img src=\"https://travis-ci.org/budjb/grails-spring-security-jaxrs.svg?branch=grails-3.x\" alt=\"Build Status\" /></a></p>\n<h2>Spring Security Jaxrs integration plugin for Grails</h2>\n<p>See the documentation at http://budjb.github.io/grails-spring-security-jaxrs/3.x/latest/.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "spring-security-kerberos", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Grails spring-security-kerberos plugin", |
| "labels": [ |
| "security", |
| "spring-security", |
| "kerberos" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/grails-spring-security-kerberos/issues", |
| "latestVersion": "3.0.1", |
| "updated": "2017-05-04T12:31:17.168Z", |
| "systemIds": [ |
| "org.grails.plugins:spring-security-kerberos" |
| ], |
| "vcsUrl": "https://github.com/grails-plugins/grails-spring-security-kerberos" |
| }, |
| "documentationUrl": "https://grails-plugins.github.io/grails-spring-security-kerberos/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails Spring Security Kerberos Plugin</h1>\n<p>See <a href=\"https://grails-plugins.github.io/grails-spring-security-kerberos/\">documentation</a> for further information.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "spring-security-ldap", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Grails spring-security-ldap plugin", |
| "labels": [ |
| "security", |
| "spring-security", |
| "ldap" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/grails-spring-security-ldap/issues", |
| "latestVersion": "4.0.0.M1", |
| "updated": "2020-03-24T10:30:31.547Z", |
| "systemIds": [ |
| "org.grails.plugins:spring-security-ldap" |
| ], |
| "vcsUrl": "https://github.com/grails-plugins/grails-spring-security-ldap" |
| }, |
| "documentationUrl": "https://grails-plugins.github.io/grails-spring-security-ldap/", |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://travis-ci.org/grails-plugins/grails-spring-security-ldap\"><img src=\"https://travis-ci.org/grails-plugins/grails-spring-security-ldap.svg\" alt=\"Build Status\" /></a></p>\n<h1>Grails Spring Security LDAP Plugin</h1>\n<p>See <a href=\"https://grails-plugins.github.io/grails-spring-security-ldap/\">documentation</a> for further information.</p>\n<h2>What is LDAP?</h2>\n<p><a href=\"https://www.youtube.com/watch?v=0Zl9NdumGK8#t=7.500125888\">Introduction to Lightweight Directory Services</a></p>\n<h2>Tools and Resources</h2>\n<ul>\n<li><a href=\"http://www.forumsys.com/tutorials/integration-how-to/ldap/online-ldap-test-server/\">Online LDAP Test Server</a></li>\n<li><a href=\"http://jxplorer.org/index.html\">JXplorer - Cross platform LDAP browser and editor</a></li>\n</ul>\n<h2>Repository Branch Structure</h2>\n<p>Branches:</p>\n<ul>\n<li><code>master</code> Grails 4 compatible versions.</li>\n<li><code>3.x</code> Grails 3 compatible versions.</li>\n</ul>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "spring-security-oauth2", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "This plugin provides the capability to authenticate via OAuth 2. Depends on Grails spring-security-core.", |
| "labels": [ |
| "security", |
| "oauth2", |
| "spring-security" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/grails-spring-security-oauth2/issues", |
| "latestVersion": "3.0.1", |
| "updated": "2024-01-23T14:30:36.000Z", |
| "systemIds": [ |
| "org.grails.plugins:spring-security-oauth2" |
| ], |
| "vcsUrl": "https://github.com/grails/grails-spring-security-oauth2" |
| }, |
| "documentationUrl": "https://grails.github.io/grails-spring-security-oauth2/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/grails/plugins/spring-security-oauth2/maven-metadata.xml", |
| "readme": null |
| }, |
| { |
| "deprecated": "Stale duplicate of the entry with the same name by author 'grails'. This entry should probably be removed from the registry to avoid confusion.", |
| "bintrayPackage": { |
| "name": "spring-security-oauth2", |
| "repo": "plugins", |
| "owner": "matrixcrawler", |
| "desc": "This plugin provides the capability to authenticate via oauth. Depends on grails-spring-security-core.", |
| "labels": [ |
| "security", |
| "spring-security", |
| "oauth2" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/MatrixCrawler/grails-spring-security-oauth2/issues", |
| "latestVersion": "1.1.0", |
| "updated": "2018-05-08T19:10:10.157Z", |
| "systemIds": [ |
| "org.grails.plugins:spring-security-oauth2" |
| ], |
| "vcsUrl": "https://github.com/MatrixCrawler/grails-spring-security-oauth2" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Spring Security OAuth2 Plugin</h1>\n<p><a href=\"https://travis-ci.org/MatrixCrawler/grails-spring-security-oauth2\"><img src=\"https://travis-ci.org/MatrixCrawler/grails-spring-security-oauth2.svg?branch=master\" alt=\"Build Status\" /></a> <a href=\"https://bintray.com/matrixcrawler/plugins/spring-security-oauth2/_latestVersion\"><img src=\"https://api.bintray.com/packages/matrixcrawler/plugins/spring-security-oauth2/images/download.svg\" alt=\"Download\" /></a></p>\n<p>Main differences with the Grails 2 plugin:</p>\n<ul>\n<li>no more dependency on https://github.com/antony/grails-oauth-scribe but some code of that plugin was ported in this</li>\n<li>Relies on <a href=\"https://github.com/scribejava/scribejava\">Scribejava</a> to do most of the OAuth logic</li>\n<li>simplest code as possible</li>\n<li>easy to extend</li>\n</ul>\n<h2>Installation</h2>\n<p>Add the following dependencies in <code>build.gradle</code></p>\n<pre><code>dependencies {\n...\n compile 'org.grails.plugins:spring-security:3.+'\n compile 'org.grails.plugins:spring-security-oauth2:1.1.0'\n...\n}\n</code></pre>\n<p>You will also need at least one provider extension, i.e the <code>grails-spring-security-oauth2-google</code> plugin\nChange the version to reflect the actual version you would like to use.</p>\n<p>You can configure the following parameters in your <code>application.yml</code>. This is fully optional</p>\n<pre><code>grails:\n plugin:\n springsecurity:\n oauth2:\n active: true #whether the whole plugin is active or not\n registration:\n askToLinkOrCreateAccountUri: '/oauth2/ask' # The URI that is called to aks the user to either create a new account or link to an existing account\n roleNames: ['ROLE_USER'] #A list of role names that should be automatically granted to an OAuth User. The roles will be created if they do not exist\n</code></pre>\n<p>Once you have an User domain class, initialize this plugin by using the init script <code>grails init-oauth2 <domain-class-package> <user-class-name> <oauthid-class-name></code>\nIn example: <code>grails init-oauth2 com.yourapp User OAuthID</code>\nThat will create the domain class <code>com.yourapp.oAuthID</code></p>\n<p>Finally add:</p>\n<pre><code class=\"language-groovy\">static hasMany = [oAuthIDs: OAuthID]\n</code></pre>\n<p>to your user domain class.</p>\n<h2>Extensions</h2>\n<p>List of known extension</p>\n<ul>\n<li><a href=\"https://github.com/MatrixCrawler/grails-spring-security-oauth2-google\">Google</a></li>\n<li><a href=\"https://github.com/MatrixCrawler/grails-spring-security-oauth2-facebook\">Facebook</a></li>\n<li>[Github] (https://github.com/rpalcolea/grails-spring-security-oauth2-github)</li>\n</ul>\n<h2>How to create a new provider plugin</h2>\n<ol>\n<li>Create a new plugin with <code>grails create-plugin spring-security-oauth2-myProvider</code></li>\n<li>Add the following plugins as dependency in <code>build.gradle</code>:\n<ul>\n<li><code>provided 'org.grails.plugins:spring-security-core:3.+'</code></li>\n<li><code>provided 'org.grails.plugins:spring-security-oauth2:1.1.+'</code></li>\n</ul>\n</li>\n<li>Create a service in your plugin that extends <code>OAuth2AbstractProviderService</code> and implement the abstract methods. You can override the other methods for fine-tuning if needed.</li>\n</ol>\n<h2>License</h2>\n<p>Apache 2</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "spring-security-oauth2-facebook", |
| "repo": "plugins", |
| "owner": "matrixcrawler", |
| "desc": "This plugin provides the capability to authenticate via facebook-oauth provider. Depends on grails-spring-security-oauth2.", |
| "labels": [ |
| "security", |
| "spring-security", |
| "oauth2" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/MatrixCrawler/grails-spring-security-oauth2-facebook/issues", |
| "latestVersion": "1.0.0", |
| "updated": "2016-06-22T08:30:58.925Z", |
| "systemIds": [ |
| "org.grails.plugins:spring-security-oauth2-facebook" |
| ], |
| "vcsUrl": "https://github.com/MatrixCrawler/grails-spring-security-oauth2-facebook" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Spring Security OAuth2 Facebook Plugin</h1>\n<p><a href=\"https://bintray.com/matrixcrawler/plugins/spring-security-oauth2-facebook/_latestVersion\"><img src=\"https://api.bintray.com/packages/matrixcrawler/plugins/spring-security-oauth2-facebook/images/download.svg\" alt=\"Download\" /></a></p>\n<p>Add a Google OAuth2 provider to the <a href=\"https://github.com/MatrixCrawler/grails-spring-security-oauth2\">Spring Security OAuth2 Plugin</a>.</p>\n<h2>Installation</h2>\n<p>Add the following dependencies in <code>build.gradle</code></p>\n<pre><code>dependencies {\n...\n compile 'org.grails.plugins:spring-security-oauth2:1.1+'\n compile 'org.grails.plugins:spring-security-oauth2-facebook:1.0.0'\n...\n}\n</code></pre>\n<h2>Usage</h2>\n<p>Add this to your application.yml</p>\n<pre><code>grails:\n plugin:\n springsecurity:\n oauth2:\n providers:\n google:\n api_key: 'facebook-api-key' #needed\n api_secret: 'facebook-api-secret' #needed\n successUri: "/oauth2/facebook/success" #optional\n failureUri: "/oauth2/facebook/failure" #optional\n callback: "/oauth2/facebook/callback" #optional\n</code></pre>\n<p>You can replace the URIs with your own controller implementation.</p>\n<p>In your view you can use the taglib exposed from this plugin and from OAuth plugin to create links and to know if the user is authenticated with a given provider:</p>\n<pre><code class=\"language-xml\"><oauth2:connect provider="facebook" id="google-connect-link">Facebbok</oauth2:connect>\n\nLogged with facebook?\n<oauth2:ifLoggedInWith provider="facebook">yes</oauth2:ifLoggedInWith>\n<oauth2:ifNotLoggedInWith provider="facebook">no</oauth2:ifNotLoggedInWith>\n</code></pre>\n<h2>License</h2>\n<p>Apache 2</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "spring-security-oauth2-github", |
| "repo": "plugins", |
| "owner": "rpalcolea", |
| "desc": "This plugin provides the capability to authenticate via Github-oauth provider. Depends on grails-spring-security-oauth2.", |
| "labels": [ |
| "security", |
| "spring-security", |
| "oauth2" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/rpalcolea/grails-spring-security-oauth2-github/issues", |
| "latestVersion": "1.0.2", |
| "updated": "2016-08-31T16:00:36.554Z", |
| "systemIds": [ |
| "org.grails.plugins:spring-security-oauth2-github" |
| ], |
| "vcsUrl": "https://github.com/rpalcolea/grails-spring-security-oauth2-github" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Spring Security OAuth2 Github Plugin</h1>\n<p><a href=\"https://travis-ci.org/rpalcolea/grails-spring-security-oauth2-github\"><img src=\"https://travis-ci.org/rpalcolea/grails-spring-security-oauth2-github.svg?branch=master\" alt=\"Build Status\" /></a>\n<a href=\"https://bintray.com/rpalcolea/plugins/spring-security-oauth2-github/_latestVersion\"><img src=\"https://api.bintray.com/packages/rpalcolea/plugins/spring-security-oauth2-github/images/download.svg\" alt=\"Download\" /></a>\n<a href=\"http://slack-signup.grails.org\"><img src=\"http://slack-signup.grails.org/badge.svg\" alt=\"Slack Signup\" /></a></p>\n<p>Add a Github OAuth2 provider to the <a href=\"https://github.com/MatrixCrawler/grails-spring-security-oauth2\">Spring Security OAuth2 Plugin</a> by @MatrixCrawler (Johannes Brunswicker).</p>\n<h2>Installation</h2>\n<p>Add the following dependencies in <code>build.gradle</code></p>\n<pre><code>dependencies {\n...\n compile 'org.grails.plugins:spring-security-oauth2:1.+'\n compile 'org.grails.plugins:spring-security-oauth2-github:1.0.+'\n...\n}\n</code></pre>\n<h2>Usage</h2>\n<p>Add this to your application.yml</p>\n<pre><code>grails:\n plugin:\n springsecurity:\n oauth2:\n providers:\n github:\n api_key: 'github-client-id' #needed\n api_secret: 'github-client-secret' #needed\n successUri: "/oauth2/github/success" #optional\n failureUri: "/oauth2/github/failure" #optional\n callback: "/oauth2/github/callback" #optional\n</code></pre>\n<p>You can replace the URIs with your own controller implementation.</p>\n<p>In your view you can use the taglib exposed from this plugin and from OAuth plugin to create links and to know if the user is authenticated with a given provider:</p>\n<pre><code class=\"language-xml\"><oauth2:connect provider="github" id="github-connect-link">Github</oauth2:connect>\n\nLogged with Github?\n<oauth2:ifLoggedInWith provider="github">yes</oauth2:ifLoggedInWith>\n<oauth2:ifNotLoggedInWith provider="github">no</oauth2:ifNotLoggedInWith>\n</code></pre>\n<h2>License</h2>\n<p>Apache 2</p>\n<h2>Sponsors</h2>\n<p><a href=\"https://www.yourkit.com/.net/profiler/index.jsp\"><img src=\"https://www.yourkit.com/images/yklogo.png\" alt=\"Alt text\" title=\"YourKit\" /></a></p>\n<p>YourKit supports open source projects with its full-featured Java Profiler.\nYourKit, LLC is the creator of <a href=\"https://www.yourkit.com/java/profiler/index.jsp\">YourKit Java Profiler</a>\nand <a href=\"https://www.yourkit.com/.net/profiler/index.jsp\">YourKit .NET Profiler</a>,\ninnovative and intelligent tools for profiling Java and .NET applications.</p>\n" |
| }, |
| { |
| "deprecated": "This plugin seems superseeded by the plugin with the same name by author grails. This entry should probably be removed from the registry to avoid confusion.", |
| "bintrayPackage": { |
| "name": "spring-security-oauth2-google", |
| "repo": "plugins", |
| "owner": "matrixcrawler", |
| "desc": "This plugin provides the capability to authenticate via g+-oauth provider. Depends on grails-spring-security-oauth2.", |
| "labels": [ |
| "security", |
| "spring-security", |
| "oauth2" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/MatrixCrawler/grails-spring-security-oauth2-google/issues", |
| "latestVersion": "1.1.0", |
| "updated": "2018-05-08T19:17:09.225Z", |
| "systemIds": [ |
| "org.grails.plugins:spring-security-oauth2-google" |
| ], |
| "vcsUrl": "https://github.com/MatrixCrawler/grails-spring-security-oauth2-google" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Spring Security OAuth2 Google Plugin</h1>\n<p><a href=\"https://bintray.com/matrixcrawler/plugins/spring-security-oauth2-google/_latestVersion\"><img src=\"https://api.bintray.com/packages/matrixcrawler/plugins/spring-security-oauth2-google/images/download.svg\" alt=\"Download\" /></a></p>\n<p>Add a Google OAuth2 provider to the <a href=\"https://github.com/MatrixCrawler/grails-spring-security-oauth2\">Spring Security OAuth2 Plugin</a>.</p>\n<h2>Installation</h2>\n<p>Add the following dependencies in <code>build.gradle</code></p>\n<pre><code>dependencies {\n...\n compile 'org.grails.plugins:spring-security-oauth2:1.+'\n compile 'org.grails.plugins:spring-security-oauth2-google:1.1.+'\n...\n}\n</code></pre>\n<h2>Usage</h2>\n<p>Add this to your application.yml</p>\n<pre><code>grails:\n plugin:\n springsecurity:\n oauth2:\n providers:\n google:\n api_key: 'google-api-key' #needed\n api_secret: 'google-api-secret' #needed\n successUri: "/oauth2/google/success" #optional\n failureUri: "/oauth2/google/failure" #optional\n callback: "/oauth2/google/callback" #optional\n scopes: "some_scope" #optional, see https://developers.google.com/identity/protocols/googlescopes#monitoringv3\n</code></pre>\n<p>You can replace the URIs with your own controller implementation.</p>\n<p>In your view you can use the taglib exposed from this plugin and from OAuth plugin to create links and to know if the user is authenticated with a given provider:</p>\n<pre><code class=\"language-xml\"><oauth2:connect provider="google" id="google-connect-link">Google</oauth2:connect>\n\nLogged with google?\n<oauth2:ifLoggedInWith provider="google">yes</oauth2:ifLoggedInWith>\n<oauth2:ifNotLoggedInWith provider="google">no</oauth2:ifNotLoggedInWith>\n</code></pre>\n<h2>License</h2>\n<p>Apache 2</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "spring-security-oauth2-google", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "This plugin provides the capability to authenticate via g+-oauth provider. Depends on grails-spring-security-oauth2. v1.2.0 starts after fork to grails-plugins org. Includes unreleased 1.1.1 from other repo.", |
| "labels": [ |
| "security", |
| "spring-security", |
| "oauth2" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/grails-spring-security-oauth2-google/issues", |
| "latestVersion": "1.2.0", |
| "updated": "2018-05-08T19:03:02.647Z", |
| "systemIds": [ |
| "org.grails.plugins:spring-security-oauth2-google" |
| ], |
| "vcsUrl": "https://github.com/grails-plugins/grails-spring-security-oauth2-google" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Spring Security OAuth2 Google Plugin</h1>\n<p><a href=\"https://bintray.com/grails/plugins/spring-security-oauth2-google/_latestVersion\"><img src=\"https://api.bintray.com/packages/grails/plugins/spring-security-oauth2-google/images/download.svg\" alt=\"Download\" /></a></p>\n<p>Add a Google OAuth2 provider to the <a href=\"https://github.com/grails-plugins/grails-spring-security-oauth2\">Spring Security OAuth2 Plugin</a>.</p>\n<h2>Installation</h2>\n<p>Add the following dependencies in <code>build.gradle</code></p>\n<pre><code>dependencies {\n...\n compile 'org.grails.plugins:spring-security-oauth2:1.+'\n compile 'org.grails.plugins:spring-security-oauth2-google:1.1.+'\n...\n}\n</code></pre>\n<h2>Usage</h2>\n<p>Add this to your application.yml</p>\n<pre><code>grails:\n plugin:\n springsecurity:\n oauth2:\n providers:\n google:\n api_key: 'google-api-key' #needed\n api_secret: 'google-api-secret' #needed\n successUri: "/oauth2/google/success" #optional\n failureUri: "/oauth2/google/failure" #optional\n callback: "/oauth2/google/callback" #optional\n scopes: "some_scope" #optional, see https://developers.google.com/identity/protocols/googlescopes#monitoringv3\n</code></pre>\n<p>You can replace the URIs with your own controller implementation.</p>\n<p>In your view you can use the taglib exposed from this plugin and from OAuth plugin to create links and to know if the user is authenticated with a given provider:</p>\n<pre><code class=\"language-xml\"><oauth2:connect provider="google" id="google-connect-link">Google</oauth2:connect>\n\nLogged with google?\n<oauth2:ifLoggedInWith provider="google">yes</oauth2:ifLoggedInWith>\n<oauth2:ifNotLoggedInWith provider="google">no</oauth2:ifNotLoggedInWith>\n</code></pre>\n<h2>License</h2>\n<p>Apache 2</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "spring-security-oauth2-ok", |
| "repo": "plugins", |
| "owner": "purpleraven", |
| "desc": "This plugin provides the capability to authenticate via ok-oauth provider. Depends on grails-spring-security-oauth2.", |
| "labels": [ |
| "security", |
| "spring-security", |
| "oauth2" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/purpleraven/grails-spring-security-oauth2-ok/issues", |
| "latestVersion": "1.0", |
| "updated": "2019-05-15T14:56:35.110Z", |
| "systemIds": [ |
| "org.grails.plugins:spring-security-oauth2-ok" |
| ], |
| "vcsUrl": "https://github.com/purpleraven/grails-spring-security-oauth2-ok" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Spring Security OAuth2 Odnoklassniki Plugin</h1>\n<p><a href=\"https://bintray.com/purpleraven/plugins/spring-security-oauth2-ok/_latestVersion\"><img src=\"https://api.bintray.com/packages/purpleraven/plugins/spring-security-oauth2-ok/images/download.svg\" alt=\"Download\" /></a></p>\n<p>Add a Odnoklassniki OAuth2 provider to the <a href=\"https://github.com/MatrixCrawler/grails-spring-security-oauth2\">Spring Security OAuth2 Plugin</a>.</p>\n<h2>Installation</h2>\n<p>Add the following dependencies in <code>build.gradle</code></p>\n<pre><code>repositories {\n ...\n maven { url "http://dl.bintray.com/purpleraven/plugins" }\n ...\n}\n\ndependencies {\n...\n compile 'org.grails.plugins:spring-security-oauth2:1.1+'\n compile 'org.grails.plugins:spring-security-oauth2-ok:1.0'\n...\n}\n</code></pre>\n<h2>Usage</h2>\n<p>Add this to your application.yml</p>\n<pre><code>grails:\n plugin:\n springsecurity:\n oauth2:\n providers:\n odnoklassniki:\n api_key: 'odnoklassniki-api-key' #needed\n api_secret: 'odnoklassniki-api-secret' #needed\n successUri: "/oauth2/odnoklassniki/success" #optional\n failureUri: "/oauth2/odnoklassniki/failure" #optional\n callback: "/oauth2/odnoklassniki/callback" #optional\n</code></pre>\n<p>You can replace the URIs with your own controller implementation.</p>\n<p>In your view you can use the taglib exposed from this plugin and from OAuth plugin to create links and to know if the user is authenticated with a given provider:</p>\n<pre><code class=\"language-xml\"><oauth2:connect provider="odnoklassniki" id="odnoklassniki-connect-link">odnoklassniki</oauth2:connect>\n\nLogged with odnoklassniki?\n<oauth2:ifLoggedInWith provider="odnoklassniki">yes</oauth2:ifLoggedInWith>\n<oauth2:ifNotLoggedInWith provider="odnoklassniki">no</oauth2:ifNotLoggedInWith>\n</code></pre>\n<h2>License</h2>\n<p>Apache 2</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "spring-security-oauth2-outlook", |
| "repo": "plugins", |
| "owner": "andreperegrina", |
| "desc": "This plugin provides the capability to authenticate via outlook-oauth provider. Depends on grails-spring-security-oauth2.", |
| "labels": [ |
| "security", |
| "spring-security", |
| "oauth2" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/andreperegrina/grails-spring-security-oauth2-outlook/issues", |
| "latestVersion": "0.1", |
| "updated": "2018-12-12T10:23:49.730Z", |
| "systemIds": [ |
| "org.grails.plugins:spring-security-oauth2-outlook" |
| ], |
| "vcsUrl": "https://github.com/andreperegrina/grails-spring-security-oauth2-outlook" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1><img src=\"./header.png\" alt=\"header\" />\nSpring Security OAuth2 Outlook Plugin</h1>\n<p><a href=\"https://bintray.com/andreperegrina/plugins/spring-security-oauth2-outlook/_latestVersion\"><img src=\"https://api.bintray.com/packages/andreperegrina/plugins/spring-security-oauth2-outlook/images/download.svg\" alt=\"Download\" /></a></p>\n<p>Add a Outlook OAuth2 provider to the <a href=\"https://github.com/MatrixCrawler/grails-spring-security-oauth2\">Spring Security OAuth2 Plugin</a>.</p>\n<h2>Installation</h2>\n<p>Add the following dependencies in <code>build.gradle</code></p>\n<pre><code>dependencies {\n...\n compile 'org.grails.plugins:spring-security-oauth2:1.+'\n compile 'org.grails.plugins:spring-security-oauth2-outlook:0.1'\n...\n}\n</code></pre>\n<h2>Usage</h2>\n<p>Add this to your application.yml</p>\n<pre><code>grails:\n plugin:\n springsecurity:\n oauth2:\n providers:\n outlook:\n api_key: 'outlook-api-key' #needed\n api_secret: 'outlook-api-secret' #needed\n successUri: "/oauth2/outlook/success" #optional\n failureUri: "/oauth2/outlook/failure" #optional\n callback: "/oauth2/outlook/callback" #optional\n scopes: "some_scope" #optional\n</code></pre>\n<p>You can replace the URIs with your own controller implementation.</p>\n<p>In your view you can use the taglib exposed from this plugin and from OAuth plugin to create links and to know if the user is authenticated with a given provider:</p>\n<pre><code class=\"language-xml\"><oauth2:connect provider="outlook" id="outlook-connect-link">Outlook</oauth2:connect>\n\nLogged with outlook?\n<oauth2:ifLoggedInWith provider="outlook">yes</oauth2:ifLoggedInWith>\n<oauth2:ifNotLoggedInWith provider="outlook">no</oauth2:ifNotLoggedInWith>\n</code></pre>\n<h2>License</h2>\n<p>Apache 2</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "spring-security-oauth2-provider", |
| "repo": "grails-plugins", |
| "owner": "grails", |
| "desc": "Grails OAuth 2 Provider Plugin", |
| "labels": [ |
| "security", |
| "spring-security", |
| "oauth2" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/grails-spring-security-oauth2-provider/issues", |
| "latestVersion": "4.0.0-RC1", |
| "updated": "2019-07-19T14:51:49.069Z", |
| "systemIds": [ |
| "org.grails.plugins:spring-security-oauth2-provider" |
| ], |
| "vcsUrl": "https://github.com/grails-plugins/grails-spring-security-oauth2-provider" |
| }, |
| "documentationUrl": "https://grails-plugins.github.io/grails-spring-security-oauth2-provider/", |
| "mavenMetadataUrl": null, |
| "readme": "<h2>Deprecation Notice</h2>\n<p>The plugin has been moved to new repository.</p>\n<p>Please browse to <a href=\"https://github.com/grails-plugins\">grails-plugins</a> fork for new updates for the plugin source code:\nhttps://github.com/grails-plugins/grails-spring-security-oauth2-provider</p>\n<h1>Grails Spring Security OAuth2 Provider Plugin</h1>\n<p><a href=\"https://travis-ci.org/bluesliverx/grails-spring-security-oauth2-provider\"><img src=\"https://travis-ci.org/bluesliverx/grails-spring-security-oauth2-provider.svg?branch=master\" alt=\"Build Status\" /></a></p>\n<p>See <a href=\"http://bluesliverx.github.io/grails-spring-security-oauth2-provider/\">documentation</a> and the\n<a href=\"http://plugins.grails.org/plugin/bluesliverx/spring-security-oauth2-provider\">Grails plugin page</a> for further information.</p>\n<p>Until the newer deploys work with the Grails repos, you may use the following for Grails 3.3+:</p>\n<pre><code>repositories {\n ...\n maven { url "http://dl.bintray.com/bluesliverx/grails-plugins" }\n}\ndependencies {\n ...\n compile 'org.grails.plugins:spring-security-oauth2-provider:3.1.0-RC1'\n}\n</code></pre>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "spring-security-oauth2-vk", |
| "repo": "plugins", |
| "owner": "purpleraven", |
| "desc": "This plugin provides the capability to authenticate via vk-oauth provider. Depends on grails-spring-security-oauth2.", |
| "labels": [ |
| "security", |
| "spring-security", |
| "oauth2" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/purpleraven/grails-spring-security-oauth2-vk/issues", |
| "latestVersion": "1.0", |
| "updated": "2019-05-15T09:20:16.953Z", |
| "systemIds": [ |
| "org.grails.plugins:spring-security-oauth2-vk" |
| ], |
| "vcsUrl": "https://github.com/purpleraven/grails-spring-security-oauth2-vk" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Spring Security OAuth2 VK Plugin</h1>\n<p><a href=\"https://bintray.com/purpleraven/plugins/spring-security-oauth2-vk/_latestVersion\"><img src=\"https://api.bintray.com/packages/purpleraven/plugins/spring-security-oauth2-vk/images/download.svg\" alt=\"Download\" /></a></p>\n<p>Add a VK OAuth2 provider to the <a href=\"https://github.com/MatrixCrawler/grails-spring-security-oauth2\">Spring Security OAuth2 Plugin</a>.</p>\n<h2>Installation</h2>\n<p>Add the following dependencies in <code>build.gradle</code></p>\n<pre><code>repositories {\n ...\n maven { url "http://dl.bintray.com/purpleraven/plugins" }\n ...\n}\n\ndependencies {\n...\n compile 'org.grails.plugins:spring-security-oauth2:1.1+'\n compile 'org.grails.plugins:spring-security-oauth2-vk:1.0'\n...\n}\n</code></pre>\n<h2>Usage</h2>\n<p>Add this to your application.yml</p>\n<pre><code>grails:\n plugin:\n springsecurity:\n oauth2:\n providers:\n vk:\n api_key: 'vk-api-key' #needed\n api_secret: 'vk-api-secret' #needed\n successUri: "/oauth2/vk/success" #optional\n failureUri: "/oauth2/vk/failure" #optional\n callback: "/oauth2/vk/callback" #optional\n</code></pre>\n<p>You can replace the URIs with your own controller implementation.</p>\n<p>In your view you can use the taglib exposed from this plugin and from OAuth plugin to create links and to know if the user is authenticated with a given provider:</p>\n<pre><code class=\"language-xml\"><oauth2:connect provider="vk" id="vk-connect-link">VK</oauth2:connect>\n\nLogged with VK?\n<oauth2:ifLoggedInWith provider="vk">yes</oauth2:ifLoggedInWith>\n<oauth2:ifNotLoggedInWith provider="vk">no</oauth2:ifNotLoggedInWith>\n</code></pre>\n<h2>License</h2>\n<p>Apache 2</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "spring-security-rest", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Grails spring-security-rest plugin", |
| "labels": [ |
| "security", |
| "spring-security", |
| "spring-security-rest" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/grails-spring-security-rest/issues", |
| "latestVersion": "3.0.1", |
| "updated": "2020-04-06T05:51:10.703Z", |
| "systemIds": [ |
| "org.grails.plugins:spring-security-rest" |
| ], |
| "vcsUrl": "https://github.com/alvarosanchez/grails-spring-security-rest" |
| }, |
| "documentationUrl": "https://grails-plugins.github.io/grails-spring-security-rest/latest/docs/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Spring Security REST for Grails</h1>\n<p><a href=\"https://travis-ci.org/alvarosanchez/grails-spring-security-rest\"><img src=\"https://travis-ci.org/alvarosanchez/grails-spring-security-rest.png?branch=develop\" alt=\"Build Status\" /></a>\n<a href=\"https://bintray.com/grails/plugins/spring-security-rest/_latestVersion\"><img src=\"https://api.bintray.com/packages/grails/plugins/spring-security-rest/images/download.svg\" alt=\"Latest version\" /></a>\n<a href=\"https://snyk.io/test/github/alvarosanchez/grails-spring-security-rest\"><img src=\"https://snyk.io/test/github/alvarosanchez/grails-spring-security-rest/develop/badge.svg\" alt=\"Known Vulnerabilities\" /></a></p>\n<p>Grails plugin to implement a stateless, token-based, RESTful authentication\nusing Spring Security. Sponsored and supported by <a href=\"http://www.ociweb.com\">Object Computing Inc.</a></p>\n<p>Documentation:</p>\n<ul>\n<li><a href=\"http://alvarosanchez.github.io/grails-spring-security-rest/latest/docs/\">User guide</a>.</li>\n<li><a href=\"http://alvarosanchez.github.io/grails-spring-security-rest/latest/docs/gapi/\">Javadoc</a>.</li>\n</ul>\n<h2>Companies using this plugin</h2>\n<ul>\n<li><a href=\"http://www.onlinephotosubmission.com\">CloudCard Online Photo Submission</a></li>\n<li><a href=\"http://www.healthreveal.com\">HealthReveal</a></li>\n<li><a href=\"http://murallo.com\">Murallo</a></li>\n<li><a href=\"http://www.odobo.com\">Odobo</a></li>\n<li><a href=\"http://www.sharptop.io\">Sharptop Software</a></li>\n<li><a href=\"http://www.zaccak.com\">Zaccak Solutions</a></li>\n<li><a href=\"https://lyshnia.com\">Lyshnia Limited</a></li>\n<li><a href=\"https://www.wizpanda.com\">Wiz Panda</a></li>\n<li><a href=\"https://zana.com\">Zana Technologies GmbH</a></li>\n</ul>\n<p><em>Are you using this plugin and want to be listed here? <a href=\"https://github.com/alvarosanchez/grails-spring-security-rest/edit/develop/README.md\">Include your company yourself</a></em>.</p>\n<h2>Support</h2>\n<ul>\n<li>General questions should go to the <a href=\"https://grails.slack.com/messages/spring-security-rest\"><code>#spring-security-rest</code> channel in Slack</a>.</li>\n<li>You can also find answers at <a href=\"http://stackoverflow.com/questions/tagged/grails+spring-security-rest\">StackOverflow</a>. Label your questions with both the <code>grails</code> and <code>spring-security-rest</code> tags.</li>\n<li>If you've got issues, report them <a href=\"https://github.com/alvarosanchez/grails-spring-security-rest/issues\">here in GitHub</a>.</li>\n<li>If you need commercial support, you can ask <a href=\"http://www.ociweb.com\">OCI</a> at <a href=\"mailto:infoATociwebDOTcom\">info AT ociweb DOT com</a>.</li>\n</ul>\n<p><strong>NOTE</strong>: if you have questions or issues, <a href=\"http://alvarosanchez.github.io/grails-spring-security-rest/latest/docs/index.html#_debugging\">enable debug logging</a>,\nand include the output in your request.</p>\n<h2>Contributors</h2>\n<ul>\n<li><a href=\"https://github.com/aeischeid\">Aaron Eischeid</a>.</li>\n<li><a href=\"https://github.com/ajbrown\">A.J. Brown</a>.</li>\n<li><a href=\"https://github.com/andrew-wharton\">Andrew Wharton</a>.</li>\n<li><a href=\"https://github.com/andrehschmid\">Andr\ufffd\ufffd\ufffd\ufffd Schmid</a>.</li>\n<li><a href=\"https://github.com/Alotor\">Alonso Torres</a>.</li>\n<li><a href=\"https://github.com/bgawel\">Bartek Gawel</a>.</li>\n<li><a href=\"https://github.com/rbfinch\">Bob Finch</a>.</li>\n<li><a href=\"https://github.com/bobbywarner\">Bobby Warner</a>.</li>\n<li><a href=\"https://github.com/burtbeckwith\">Burt Beckwith</a>.</li>\n<li><a href=\"https://github.com/conalllaverty\">Conall Laverty</a>.</li>\n<li><a href=\"https://github.com/tkvw\">Dennie de Lange</a>.</li>\n<li><a href=\"https://github.com/dmahapatro\">Dhiraj Mahapatro</a>.</li>\n<li><a href=\"https://github.com/domurtag\">Donal Murtagh</a>.</li>\n<li><a href=\"https://github.com/liftyourgame\">Greg Pagendam-Turner</a>.</li>\n<li><a href=\"https://github.com/Schlogen\">James Kleeh</a>.</li>\n<li><a href=\"https://github.com/jladenfors\">Jonas Ladenfors</a>.</li>\n<li><a href=\"https://github.com/jagedn\">Jorge Aguilera</a>.</li>\n<li><a href=\"https://github.com/zeludo\">Ludovic Ronsin</a>.</li>\n<li><a href=\"https://github.com/stlhrt\">Lukasz Wozniak</a>.</li>\n<li><a href=\"https://github.com/marcos-carceles\">Marcos Carceles</a>.</li>\n<li><a href=\"https://github.com/michallula\">Micha\ufffd\ufffd\ufffd\ufffd\ufffd Lula</a>.</li>\n<li><a href=\"https://github.com/majkelo\">Michal Szulc</a>.</li>\n<li><a href=\"https://github.com/nllarson\">Nick Larson</a>.</li>\n<li><a href=\"https://github.com/peh\">Philipp Eschenbach</a>.</li>\n<li><a href=\"https://github.com/giboow\">Philippe Gibert</a>.</li>\n<li><a href=\"https://github.com/pphetra\">Polawat Phetra</a>.</li>\n<li><a href=\"https://github.com/rvargas\">Rafael Vargas</a>.</li>\n<li><a href=\"https://github.com/sbrady\">Sean Brady</a>.</li>\n<li><a href=\"https://github.com/Prototik\">Sergey Shatunov</a>.</li>\n<li><a href=\"https://github.com/sdelamo\">Sergio del Amo</a>.</li>\n<li><a href=\"https://github.com/sagrawal31\">Shashank Agrawal</a>.</li>\n<li><a href=\"https://github.com/srohlin\">Svante Rohlin</a>.</li>\n<li><a href=\"https://github.com/tcrespog\">Tom\ufffd\ufffd\ufffd\ufffds Crespo</a>.</li>\n<li><a href=\"https://github.com/tonyerskine\">Tony Erskine</a>.</li>\n<li><a href=\"https://github.com/vsaar\">Victor Saar</a>.</li>\n</ul>\n<h2>License</h2>\n<p>This software is licensed under the terms of the <a href=\"http://www.apache.org/licenses/LICENSE-2.0.html\">Apache License, Version 2.0</a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "spring-security-rest-gorm", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Spring Security REST plugin for Grails - GORM module", |
| "labels": [ |
| "security", |
| "spring-security", |
| "spring-security-rest" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/grails-spring-security-rest/issues", |
| "latestVersion": "3.0.1", |
| "updated": "2020-04-06T05:51:13.612Z", |
| "systemIds": [ |
| "org.grails.plugins:spring-security-rest-gorm" |
| ], |
| "vcsUrl": "https://github.com/grails-plugins/grails-spring-security-rest" |
| }, |
| "documentationUrl": "https://grails-plugins.github.io/grails-spring-security-rest/latest/docs/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Spring Security REST for Grails</h1>\n<p><a href=\"https://travis-ci.org/alvarosanchez/grails-spring-security-rest\"><img src=\"https://travis-ci.org/alvarosanchez/grails-spring-security-rest.png?branch=develop\" alt=\"Build Status\" /></a>\n<a href=\"https://bintray.com/grails/plugins/spring-security-rest/_latestVersion\"><img src=\"https://api.bintray.com/packages/grails/plugins/spring-security-rest/images/download.svg\" alt=\"Latest version\" /></a>\n<a href=\"https://snyk.io/test/github/alvarosanchez/grails-spring-security-rest\"><img src=\"https://snyk.io/test/github/alvarosanchez/grails-spring-security-rest/develop/badge.svg\" alt=\"Known Vulnerabilities\" /></a></p>\n<p>Grails plugin to implement a stateless, token-based, RESTful authentication\nusing Spring Security. Sponsored and supported by <a href=\"http://www.ociweb.com\">Object Computing Inc.</a></p>\n<p>Documentation:</p>\n<ul>\n<li><a href=\"http://alvarosanchez.github.io/grails-spring-security-rest/latest/docs/\">User guide</a>.</li>\n<li><a href=\"http://alvarosanchez.github.io/grails-spring-security-rest/latest/docs/gapi/\">Javadoc</a>.</li>\n</ul>\n<h2>Companies using this plugin</h2>\n<ul>\n<li><a href=\"http://www.onlinephotosubmission.com\">CloudCard Online Photo Submission</a></li>\n<li><a href=\"http://www.healthreveal.com\">HealthReveal</a></li>\n<li><a href=\"http://murallo.com\">Murallo</a></li>\n<li><a href=\"http://www.odobo.com\">Odobo</a></li>\n<li><a href=\"http://www.sharptop.io\">Sharptop Software</a></li>\n<li><a href=\"http://www.zaccak.com\">Zaccak Solutions</a></li>\n<li><a href=\"https://lyshnia.com\">Lyshnia Limited</a></li>\n<li><a href=\"https://www.wizpanda.com\">Wiz Panda</a></li>\n<li><a href=\"https://zana.com\">Zana Technologies GmbH</a></li>\n</ul>\n<p><em>Are you using this plugin and want to be listed here? <a href=\"https://github.com/alvarosanchez/grails-spring-security-rest/edit/develop/README.md\">Include your company yourself</a></em>.</p>\n<h2>Support</h2>\n<ul>\n<li>General questions should go to the <a href=\"https://grails.slack.com/messages/spring-security-rest\"><code>#spring-security-rest</code> channel in Slack</a>.</li>\n<li>You can also find answers at <a href=\"http://stackoverflow.com/questions/tagged/grails+spring-security-rest\">StackOverflow</a>. Label your questions with both the <code>grails</code> and <code>spring-security-rest</code> tags.</li>\n<li>If you've got issues, report them <a href=\"https://github.com/alvarosanchez/grails-spring-security-rest/issues\">here in GitHub</a>.</li>\n<li>If you need commercial support, you can ask <a href=\"http://www.ociweb.com\">OCI</a> at <a href=\"mailto:infoATociwebDOTcom\">info AT ociweb DOT com</a>.</li>\n</ul>\n<p><strong>NOTE</strong>: if you have questions or issues, <a href=\"http://alvarosanchez.github.io/grails-spring-security-rest/latest/docs/index.html#_debugging\">enable debug logging</a>,\nand include the output in your request.</p>\n<h2>Contributors</h2>\n<ul>\n<li><a href=\"https://github.com/aeischeid\">Aaron Eischeid</a>.</li>\n<li><a href=\"https://github.com/ajbrown\">A.J. Brown</a>.</li>\n<li><a href=\"https://github.com/andrew-wharton\">Andrew Wharton</a>.</li>\n<li><a href=\"https://github.com/andrehschmid\">Andr\ufffd\ufffd\ufffd\ufffd Schmid</a>.</li>\n<li><a href=\"https://github.com/Alotor\">Alonso Torres</a>.</li>\n<li><a href=\"https://github.com/bgawel\">Bartek Gawel</a>.</li>\n<li><a href=\"https://github.com/rbfinch\">Bob Finch</a>.</li>\n<li><a href=\"https://github.com/bobbywarner\">Bobby Warner</a>.</li>\n<li><a href=\"https://github.com/burtbeckwith\">Burt Beckwith</a>.</li>\n<li><a href=\"https://github.com/conalllaverty\">Conall Laverty</a>.</li>\n<li><a href=\"https://github.com/tkvw\">Dennie de Lange</a>.</li>\n<li><a href=\"https://github.com/dmahapatro\">Dhiraj Mahapatro</a>.</li>\n<li><a href=\"https://github.com/domurtag\">Donal Murtagh</a>.</li>\n<li><a href=\"https://github.com/liftyourgame\">Greg Pagendam-Turner</a>.</li>\n<li><a href=\"https://github.com/Schlogen\">James Kleeh</a>.</li>\n<li><a href=\"https://github.com/jladenfors\">Jonas Ladenfors</a>.</li>\n<li><a href=\"https://github.com/jagedn\">Jorge Aguilera</a>.</li>\n<li><a href=\"https://github.com/zeludo\">Ludovic Ronsin</a>.</li>\n<li><a href=\"https://github.com/stlhrt\">Lukasz Wozniak</a>.</li>\n<li><a href=\"https://github.com/marcos-carceles\">Marcos Carceles</a>.</li>\n<li><a href=\"https://github.com/michallula\">Micha\ufffd\ufffd\ufffd\ufffd\ufffd Lula</a>.</li>\n<li><a href=\"https://github.com/majkelo\">Michal Szulc</a>.</li>\n<li><a href=\"https://github.com/nllarson\">Nick Larson</a>.</li>\n<li><a href=\"https://github.com/peh\">Philipp Eschenbach</a>.</li>\n<li><a href=\"https://github.com/giboow\">Philippe Gibert</a>.</li>\n<li><a href=\"https://github.com/pphetra\">Polawat Phetra</a>.</li>\n<li><a href=\"https://github.com/rvargas\">Rafael Vargas</a>.</li>\n<li><a href=\"https://github.com/sbrady\">Sean Brady</a>.</li>\n<li><a href=\"https://github.com/Prototik\">Sergey Shatunov</a>.</li>\n<li><a href=\"https://github.com/sdelamo\">Sergio del Amo</a>.</li>\n<li><a href=\"https://github.com/sagrawal31\">Shashank Agrawal</a>.</li>\n<li><a href=\"https://github.com/srohlin\">Svante Rohlin</a>.</li>\n<li><a href=\"https://github.com/tcrespog\">Tom\ufffd\ufffd\ufffd\ufffds Crespo</a>.</li>\n<li><a href=\"https://github.com/tonyerskine\">Tony Erskine</a>.</li>\n<li><a href=\"https://github.com/vsaar\">Victor Saar</a>.</li>\n</ul>\n<h2>License</h2>\n<p>This software is licensed under the terms of the <a href=\"http://www.apache.org/licenses/LICENSE-2.0.html\">Apache License, Version 2.0</a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "spring-security-rest-grailscache", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Spring Security REST plugin for Grails - Grails cache module", |
| "labels": [ |
| "security", |
| "spring-security", |
| "spring-security-rest" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/grails-spring-security-rest/issues", |
| "latestVersion": "3.0.1", |
| "updated": "2020-04-06T05:51:20.871Z", |
| "systemIds": [ |
| "org.grails.plugins:spring-security-rest-grailscache" |
| ], |
| "vcsUrl": "https://github.com/grails-plugins/grails-spring-security-rest" |
| }, |
| "documentationUrl": "https://grails-plugins.github.io/grails-spring-security-rest/latest/docs/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Spring Security REST for Grails</h1>\n<p><a href=\"https://travis-ci.org/alvarosanchez/grails-spring-security-rest\"><img src=\"https://travis-ci.org/alvarosanchez/grails-spring-security-rest.png?branch=develop\" alt=\"Build Status\" /></a>\n<a href=\"https://bintray.com/grails/plugins/spring-security-rest/_latestVersion\"><img src=\"https://api.bintray.com/packages/grails/plugins/spring-security-rest/images/download.svg\" alt=\"Latest version\" /></a>\n<a href=\"https://snyk.io/test/github/alvarosanchez/grails-spring-security-rest\"><img src=\"https://snyk.io/test/github/alvarosanchez/grails-spring-security-rest/develop/badge.svg\" alt=\"Known Vulnerabilities\" /></a></p>\n<p>Grails plugin to implement a stateless, token-based, RESTful authentication\nusing Spring Security. Sponsored and supported by <a href=\"http://www.ociweb.com\">Object Computing Inc.</a></p>\n<p>Documentation:</p>\n<ul>\n<li><a href=\"http://alvarosanchez.github.io/grails-spring-security-rest/latest/docs/\">User guide</a>.</li>\n<li><a href=\"http://alvarosanchez.github.io/grails-spring-security-rest/latest/docs/gapi/\">Javadoc</a>.</li>\n</ul>\n<h2>Companies using this plugin</h2>\n<ul>\n<li><a href=\"http://www.onlinephotosubmission.com\">CloudCard Online Photo Submission</a></li>\n<li><a href=\"http://www.healthreveal.com\">HealthReveal</a></li>\n<li><a href=\"http://murallo.com\">Murallo</a></li>\n<li><a href=\"http://www.odobo.com\">Odobo</a></li>\n<li><a href=\"http://www.sharptop.io\">Sharptop Software</a></li>\n<li><a href=\"http://www.zaccak.com\">Zaccak Solutions</a></li>\n<li><a href=\"https://lyshnia.com\">Lyshnia Limited</a></li>\n<li><a href=\"https://www.wizpanda.com\">Wiz Panda</a></li>\n<li><a href=\"https://zana.com\">Zana Technologies GmbH</a></li>\n</ul>\n<p><em>Are you using this plugin and want to be listed here? <a href=\"https://github.com/alvarosanchez/grails-spring-security-rest/edit/develop/README.md\">Include your company yourself</a></em>.</p>\n<h2>Support</h2>\n<ul>\n<li>General questions should go to the <a href=\"https://grails.slack.com/messages/spring-security-rest\"><code>#spring-security-rest</code> channel in Slack</a>.</li>\n<li>You can also find answers at <a href=\"http://stackoverflow.com/questions/tagged/grails+spring-security-rest\">StackOverflow</a>. Label your questions with both the <code>grails</code> and <code>spring-security-rest</code> tags.</li>\n<li>If you've got issues, report them <a href=\"https://github.com/alvarosanchez/grails-spring-security-rest/issues\">here in GitHub</a>.</li>\n<li>If you need commercial support, you can ask <a href=\"http://www.ociweb.com\">OCI</a> at <a href=\"mailto:infoATociwebDOTcom\">info AT ociweb DOT com</a>.</li>\n</ul>\n<p><strong>NOTE</strong>: if you have questions or issues, <a href=\"http://alvarosanchez.github.io/grails-spring-security-rest/latest/docs/index.html#_debugging\">enable debug logging</a>,\nand include the output in your request.</p>\n<h2>Contributors</h2>\n<ul>\n<li><a href=\"https://github.com/aeischeid\">Aaron Eischeid</a>.</li>\n<li><a href=\"https://github.com/ajbrown\">A.J. Brown</a>.</li>\n<li><a href=\"https://github.com/andrew-wharton\">Andrew Wharton</a>.</li>\n<li><a href=\"https://github.com/andrehschmid\">Andr\ufffd\ufffd\ufffd\ufffd Schmid</a>.</li>\n<li><a href=\"https://github.com/Alotor\">Alonso Torres</a>.</li>\n<li><a href=\"https://github.com/bgawel\">Bartek Gawel</a>.</li>\n<li><a href=\"https://github.com/rbfinch\">Bob Finch</a>.</li>\n<li><a href=\"https://github.com/bobbywarner\">Bobby Warner</a>.</li>\n<li><a href=\"https://github.com/burtbeckwith\">Burt Beckwith</a>.</li>\n<li><a href=\"https://github.com/conalllaverty\">Conall Laverty</a>.</li>\n<li><a href=\"https://github.com/tkvw\">Dennie de Lange</a>.</li>\n<li><a href=\"https://github.com/dmahapatro\">Dhiraj Mahapatro</a>.</li>\n<li><a href=\"https://github.com/domurtag\">Donal Murtagh</a>.</li>\n<li><a href=\"https://github.com/liftyourgame\">Greg Pagendam-Turner</a>.</li>\n<li><a href=\"https://github.com/Schlogen\">James Kleeh</a>.</li>\n<li><a href=\"https://github.com/jladenfors\">Jonas Ladenfors</a>.</li>\n<li><a href=\"https://github.com/jagedn\">Jorge Aguilera</a>.</li>\n<li><a href=\"https://github.com/zeludo\">Ludovic Ronsin</a>.</li>\n<li><a href=\"https://github.com/stlhrt\">Lukasz Wozniak</a>.</li>\n<li><a href=\"https://github.com/marcos-carceles\">Marcos Carceles</a>.</li>\n<li><a href=\"https://github.com/michallula\">Micha\ufffd\ufffd\ufffd\ufffd\ufffd Lula</a>.</li>\n<li><a href=\"https://github.com/majkelo\">Michal Szulc</a>.</li>\n<li><a href=\"https://github.com/nllarson\">Nick Larson</a>.</li>\n<li><a href=\"https://github.com/peh\">Philipp Eschenbach</a>.</li>\n<li><a href=\"https://github.com/giboow\">Philippe Gibert</a>.</li>\n<li><a href=\"https://github.com/pphetra\">Polawat Phetra</a>.</li>\n<li><a href=\"https://github.com/rvargas\">Rafael Vargas</a>.</li>\n<li><a href=\"https://github.com/sbrady\">Sean Brady</a>.</li>\n<li><a href=\"https://github.com/Prototik\">Sergey Shatunov</a>.</li>\n<li><a href=\"https://github.com/sdelamo\">Sergio del Amo</a>.</li>\n<li><a href=\"https://github.com/sagrawal31\">Shashank Agrawal</a>.</li>\n<li><a href=\"https://github.com/srohlin\">Svante Rohlin</a>.</li>\n<li><a href=\"https://github.com/tcrespog\">Tom\ufffd\ufffd\ufffd\ufffds Crespo</a>.</li>\n<li><a href=\"https://github.com/tonyerskine\">Tony Erskine</a>.</li>\n<li><a href=\"https://github.com/vsaar\">Victor Saar</a>.</li>\n</ul>\n<h2>License</h2>\n<p>This software is licensed under the terms of the <a href=\"http://www.apache.org/licenses/LICENSE-2.0.html\">Apache License, Version 2.0</a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "spring-security-rest-memcached", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Grails plugin to implement token-based, RESTful authentication using Spring Security", |
| "labels": [ |
| "security", |
| "spring-security", |
| "spring-security-rest", |
| "memcached" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/grails-spring-security-rest/issues", |
| "latestVersion": "3.0.1", |
| "updated": "2020-04-06T05:51:16.025Z", |
| "systemIds": [ |
| "org.grails.plugins:spring-security-rest-memcached" |
| ], |
| "vcsUrl": "https://github.com/grails-plugins/grails-spring-security-rest" |
| }, |
| "documentationUrl": "https://grails-plugins.github.io/grails-spring-security-rest/latest/docs/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Spring Security REST for Grails</h1>\n<p><a href=\"https://travis-ci.org/alvarosanchez/grails-spring-security-rest\"><img src=\"https://travis-ci.org/alvarosanchez/grails-spring-security-rest.png?branch=develop\" alt=\"Build Status\" /></a>\n<a href=\"https://bintray.com/grails/plugins/spring-security-rest/_latestVersion\"><img src=\"https://api.bintray.com/packages/grails/plugins/spring-security-rest/images/download.svg\" alt=\"Latest version\" /></a>\n<a href=\"https://snyk.io/test/github/alvarosanchez/grails-spring-security-rest\"><img src=\"https://snyk.io/test/github/alvarosanchez/grails-spring-security-rest/develop/badge.svg\" alt=\"Known Vulnerabilities\" /></a></p>\n<p>Grails plugin to implement a stateless, token-based, RESTful authentication\nusing Spring Security. Sponsored and supported by <a href=\"http://www.ociweb.com\">Object Computing Inc.</a></p>\n<p>Documentation:</p>\n<ul>\n<li><a href=\"http://alvarosanchez.github.io/grails-spring-security-rest/latest/docs/\">User guide</a>.</li>\n<li><a href=\"http://alvarosanchez.github.io/grails-spring-security-rest/latest/docs/gapi/\">Javadoc</a>.</li>\n</ul>\n<h2>Companies using this plugin</h2>\n<ul>\n<li><a href=\"http://www.onlinephotosubmission.com\">CloudCard Online Photo Submission</a></li>\n<li><a href=\"http://www.healthreveal.com\">HealthReveal</a></li>\n<li><a href=\"http://murallo.com\">Murallo</a></li>\n<li><a href=\"http://www.odobo.com\">Odobo</a></li>\n<li><a href=\"http://www.sharptop.io\">Sharptop Software</a></li>\n<li><a href=\"http://www.zaccak.com\">Zaccak Solutions</a></li>\n<li><a href=\"https://lyshnia.com\">Lyshnia Limited</a></li>\n<li><a href=\"https://www.wizpanda.com\">Wiz Panda</a></li>\n<li><a href=\"https://zana.com\">Zana Technologies GmbH</a></li>\n</ul>\n<p><em>Are you using this plugin and want to be listed here? <a href=\"https://github.com/alvarosanchez/grails-spring-security-rest/edit/develop/README.md\">Include your company yourself</a></em>.</p>\n<h2>Support</h2>\n<ul>\n<li>General questions should go to the <a href=\"https://grails.slack.com/messages/spring-security-rest\"><code>#spring-security-rest</code> channel in Slack</a>.</li>\n<li>You can also find answers at <a href=\"http://stackoverflow.com/questions/tagged/grails+spring-security-rest\">StackOverflow</a>. Label your questions with both the <code>grails</code> and <code>spring-security-rest</code> tags.</li>\n<li>If you've got issues, report them <a href=\"https://github.com/alvarosanchez/grails-spring-security-rest/issues\">here in GitHub</a>.</li>\n<li>If you need commercial support, you can ask <a href=\"http://www.ociweb.com\">OCI</a> at <a href=\"mailto:infoATociwebDOTcom\">info AT ociweb DOT com</a>.</li>\n</ul>\n<p><strong>NOTE</strong>: if you have questions or issues, <a href=\"http://alvarosanchez.github.io/grails-spring-security-rest/latest/docs/index.html#_debugging\">enable debug logging</a>,\nand include the output in your request.</p>\n<h2>Contributors</h2>\n<ul>\n<li><a href=\"https://github.com/aeischeid\">Aaron Eischeid</a>.</li>\n<li><a href=\"https://github.com/ajbrown\">A.J. Brown</a>.</li>\n<li><a href=\"https://github.com/andrew-wharton\">Andrew Wharton</a>.</li>\n<li><a href=\"https://github.com/andrehschmid\">Andr\ufffd\ufffd\ufffd\ufffd Schmid</a>.</li>\n<li><a href=\"https://github.com/Alotor\">Alonso Torres</a>.</li>\n<li><a href=\"https://github.com/bgawel\">Bartek Gawel</a>.</li>\n<li><a href=\"https://github.com/rbfinch\">Bob Finch</a>.</li>\n<li><a href=\"https://github.com/bobbywarner\">Bobby Warner</a>.</li>\n<li><a href=\"https://github.com/burtbeckwith\">Burt Beckwith</a>.</li>\n<li><a href=\"https://github.com/conalllaverty\">Conall Laverty</a>.</li>\n<li><a href=\"https://github.com/tkvw\">Dennie de Lange</a>.</li>\n<li><a href=\"https://github.com/dmahapatro\">Dhiraj Mahapatro</a>.</li>\n<li><a href=\"https://github.com/domurtag\">Donal Murtagh</a>.</li>\n<li><a href=\"https://github.com/liftyourgame\">Greg Pagendam-Turner</a>.</li>\n<li><a href=\"https://github.com/Schlogen\">James Kleeh</a>.</li>\n<li><a href=\"https://github.com/jladenfors\">Jonas Ladenfors</a>.</li>\n<li><a href=\"https://github.com/jagedn\">Jorge Aguilera</a>.</li>\n<li><a href=\"https://github.com/zeludo\">Ludovic Ronsin</a>.</li>\n<li><a href=\"https://github.com/stlhrt\">Lukasz Wozniak</a>.</li>\n<li><a href=\"https://github.com/marcos-carceles\">Marcos Carceles</a>.</li>\n<li><a href=\"https://github.com/michallula\">Micha\ufffd\ufffd\ufffd\ufffd\ufffd Lula</a>.</li>\n<li><a href=\"https://github.com/majkelo\">Michal Szulc</a>.</li>\n<li><a href=\"https://github.com/nllarson\">Nick Larson</a>.</li>\n<li><a href=\"https://github.com/peh\">Philipp Eschenbach</a>.</li>\n<li><a href=\"https://github.com/giboow\">Philippe Gibert</a>.</li>\n<li><a href=\"https://github.com/pphetra\">Polawat Phetra</a>.</li>\n<li><a href=\"https://github.com/rvargas\">Rafael Vargas</a>.</li>\n<li><a href=\"https://github.com/sbrady\">Sean Brady</a>.</li>\n<li><a href=\"https://github.com/Prototik\">Sergey Shatunov</a>.</li>\n<li><a href=\"https://github.com/sdelamo\">Sergio del Amo</a>.</li>\n<li><a href=\"https://github.com/sagrawal31\">Shashank Agrawal</a>.</li>\n<li><a href=\"https://github.com/srohlin\">Svante Rohlin</a>.</li>\n<li><a href=\"https://github.com/tcrespog\">Tom\ufffd\ufffd\ufffd\ufffds Crespo</a>.</li>\n<li><a href=\"https://github.com/tonyerskine\">Tony Erskine</a>.</li>\n<li><a href=\"https://github.com/vsaar\">Victor Saar</a>.</li>\n</ul>\n<h2>License</h2>\n<p>This software is licensed under the terms of the <a href=\"http://www.apache.org/licenses/LICENSE-2.0.html\">Apache License, Version 2.0</a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "spring-security-rest-redis", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Spring Security REST plugin for Grails - Redis module", |
| "labels": [ |
| "security", |
| "spring-security", |
| "spring-security-rest", |
| "redis" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/grails-spring-security-rest/issues", |
| "latestVersion": "3.0.1", |
| "updated": "2020-04-06T05:51:18.295Z", |
| "systemIds": [ |
| "org.grails.plugins:spring-security-rest-redis" |
| ], |
| "vcsUrl": "https://github.com/alvarosanchez/grails-spring-security-rest" |
| }, |
| "documentationUrl": "https://grails-plugins.github.io/grails-spring-security-rest/latest/docs/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Spring Security REST for Grails</h1>\n<p><a href=\"https://travis-ci.org/alvarosanchez/grails-spring-security-rest\"><img src=\"https://travis-ci.org/alvarosanchez/grails-spring-security-rest.png?branch=develop\" alt=\"Build Status\" /></a>\n<a href=\"https://bintray.com/grails/plugins/spring-security-rest/_latestVersion\"><img src=\"https://api.bintray.com/packages/grails/plugins/spring-security-rest/images/download.svg\" alt=\"Latest version\" /></a>\n<a href=\"https://snyk.io/test/github/alvarosanchez/grails-spring-security-rest\"><img src=\"https://snyk.io/test/github/alvarosanchez/grails-spring-security-rest/develop/badge.svg\" alt=\"Known Vulnerabilities\" /></a></p>\n<p>Grails plugin to implement a stateless, token-based, RESTful authentication\nusing Spring Security. Sponsored and supported by <a href=\"http://www.ociweb.com\">Object Computing Inc.</a></p>\n<p>Documentation:</p>\n<ul>\n<li><a href=\"http://alvarosanchez.github.io/grails-spring-security-rest/latest/docs/\">User guide</a>.</li>\n<li><a href=\"http://alvarosanchez.github.io/grails-spring-security-rest/latest/docs/gapi/\">Javadoc</a>.</li>\n</ul>\n<h2>Companies using this plugin</h2>\n<ul>\n<li><a href=\"http://www.onlinephotosubmission.com\">CloudCard Online Photo Submission</a></li>\n<li><a href=\"http://www.healthreveal.com\">HealthReveal</a></li>\n<li><a href=\"http://murallo.com\">Murallo</a></li>\n<li><a href=\"http://www.odobo.com\">Odobo</a></li>\n<li><a href=\"http://www.sharptop.io\">Sharptop Software</a></li>\n<li><a href=\"http://www.zaccak.com\">Zaccak Solutions</a></li>\n<li><a href=\"https://lyshnia.com\">Lyshnia Limited</a></li>\n<li><a href=\"https://www.wizpanda.com\">Wiz Panda</a></li>\n<li><a href=\"https://zana.com\">Zana Technologies GmbH</a></li>\n</ul>\n<p><em>Are you using this plugin and want to be listed here? <a href=\"https://github.com/alvarosanchez/grails-spring-security-rest/edit/develop/README.md\">Include your company yourself</a></em>.</p>\n<h2>Support</h2>\n<ul>\n<li>General questions should go to the <a href=\"https://grails.slack.com/messages/spring-security-rest\"><code>#spring-security-rest</code> channel in Slack</a>.</li>\n<li>You can also find answers at <a href=\"http://stackoverflow.com/questions/tagged/grails+spring-security-rest\">StackOverflow</a>. Label your questions with both the <code>grails</code> and <code>spring-security-rest</code> tags.</li>\n<li>If you've got issues, report them <a href=\"https://github.com/alvarosanchez/grails-spring-security-rest/issues\">here in GitHub</a>.</li>\n<li>If you need commercial support, you can ask <a href=\"http://www.ociweb.com\">OCI</a> at <a href=\"mailto:infoATociwebDOTcom\">info AT ociweb DOT com</a>.</li>\n</ul>\n<p><strong>NOTE</strong>: if you have questions or issues, <a href=\"http://alvarosanchez.github.io/grails-spring-security-rest/latest/docs/index.html#_debugging\">enable debug logging</a>,\nand include the output in your request.</p>\n<h2>Contributors</h2>\n<ul>\n<li><a href=\"https://github.com/aeischeid\">Aaron Eischeid</a>.</li>\n<li><a href=\"https://github.com/ajbrown\">A.J. Brown</a>.</li>\n<li><a href=\"https://github.com/andrew-wharton\">Andrew Wharton</a>.</li>\n<li><a href=\"https://github.com/andrehschmid\">Andr\ufffd\ufffd\ufffd\ufffd Schmid</a>.</li>\n<li><a href=\"https://github.com/Alotor\">Alonso Torres</a>.</li>\n<li><a href=\"https://github.com/bgawel\">Bartek Gawel</a>.</li>\n<li><a href=\"https://github.com/rbfinch\">Bob Finch</a>.</li>\n<li><a href=\"https://github.com/bobbywarner\">Bobby Warner</a>.</li>\n<li><a href=\"https://github.com/burtbeckwith\">Burt Beckwith</a>.</li>\n<li><a href=\"https://github.com/conalllaverty\">Conall Laverty</a>.</li>\n<li><a href=\"https://github.com/tkvw\">Dennie de Lange</a>.</li>\n<li><a href=\"https://github.com/dmahapatro\">Dhiraj Mahapatro</a>.</li>\n<li><a href=\"https://github.com/domurtag\">Donal Murtagh</a>.</li>\n<li><a href=\"https://github.com/liftyourgame\">Greg Pagendam-Turner</a>.</li>\n<li><a href=\"https://github.com/Schlogen\">James Kleeh</a>.</li>\n<li><a href=\"https://github.com/jladenfors\">Jonas Ladenfors</a>.</li>\n<li><a href=\"https://github.com/jagedn\">Jorge Aguilera</a>.</li>\n<li><a href=\"https://github.com/zeludo\">Ludovic Ronsin</a>.</li>\n<li><a href=\"https://github.com/stlhrt\">Lukasz Wozniak</a>.</li>\n<li><a href=\"https://github.com/marcos-carceles\">Marcos Carceles</a>.</li>\n<li><a href=\"https://github.com/michallula\">Micha\ufffd\ufffd\ufffd\ufffd\ufffd Lula</a>.</li>\n<li><a href=\"https://github.com/majkelo\">Michal Szulc</a>.</li>\n<li><a href=\"https://github.com/nllarson\">Nick Larson</a>.</li>\n<li><a href=\"https://github.com/peh\">Philipp Eschenbach</a>.</li>\n<li><a href=\"https://github.com/giboow\">Philippe Gibert</a>.</li>\n<li><a href=\"https://github.com/pphetra\">Polawat Phetra</a>.</li>\n<li><a href=\"https://github.com/rvargas\">Rafael Vargas</a>.</li>\n<li><a href=\"https://github.com/sbrady\">Sean Brady</a>.</li>\n<li><a href=\"https://github.com/Prototik\">Sergey Shatunov</a>.</li>\n<li><a href=\"https://github.com/sdelamo\">Sergio del Amo</a>.</li>\n<li><a href=\"https://github.com/sagrawal31\">Shashank Agrawal</a>.</li>\n<li><a href=\"https://github.com/srohlin\">Svante Rohlin</a>.</li>\n<li><a href=\"https://github.com/tcrespog\">Tom\ufffd\ufffd\ufffd\ufffds Crespo</a>.</li>\n<li><a href=\"https://github.com/tonyerskine\">Tony Erskine</a>.</li>\n<li><a href=\"https://github.com/vsaar\">Victor Saar</a>.</li>\n</ul>\n<h2>License</h2>\n<p>This software is licensed under the terms of the <a href=\"http://www.apache.org/licenses/LICENSE-2.0.html\">Apache License, Version 2.0</a></p>\n" |
| }, |
| { |
| "deprecated": "The source repository for this entry states to use the entry with the same name from author valentingoebel. This entry should probably be removed from the registry to avoid confusion.", |
| "bintrayPackage": { |
| "name": "spring-security-saml", |
| "repo": "plugins", |
| "owner": "jeffwils", |
| "desc": "Grails 3 Saml2 Support for Spring Security plugin.", |
| "labels": [ |
| "security", |
| "spring-security", |
| "saml" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/jeffwils/grails-spring-security-saml/issues", |
| "latestVersion": "3.3.0", |
| "updated": "2018-03-21T14:19:16.784Z", |
| "systemIds": [ |
| "org.grails.plugins:spring-security-saml" |
| ], |
| "vcsUrl": "https://github.com/jeffwils/grails-spring-security-saml" |
| }, |
| "documentationUrl": "https://jeffwils.github.io/grails-spring-security-saml/", |
| "mavenMetadataUrl": null, |
| "readme": "<h2>SAML 2.0 Plugin for Grails 3 and 4</h2>\n<p>This plugin provides SAML 2.0 support for Grails 3 and 4 applications. It was originally built from the Plugin that supported Grails 2 applications. It enables SAML configuration directly from your application.yml or application.groovy without having to manually configure the Spring SAML Plugin and Grails Spring Security Plugin</p>\n<h3>Plugin Compatibility with Grails</h3>\n<ul>\n<li>Grails 3.0.x - Use Version 3.0.x of the plugin</li>\n<li>Grails 3.1.x - Use Version 3.1.x of the plugin</li>\n<li>Grails 3.3.x - Use Version 3.3.x of the plugin</li>\n<li>Grails 4.0.x - Use Version 4.0.2 of the plugin</li>\n</ul>\n<h3>Installation</h3>\n<p><strong>Maven</strong></p>\n<pre><code class=\"language-xml\"><dependency>\n <groupId>org.grails.plugins</groupId>\n <artifactId>spring-security-saml</artifactId>\n <version>4.0.2</version>\n <type>pom</type>\n</dependency>\n</code></pre>\n<p><strong>Gradle</strong></p>\n<p>Grails 3.3.x</p>\n<pre><code class=\"language-gradle\">compile 'org.grails.plugins:spring-security-saml:3.3.1'\n</code></pre>\n<p>Grails 4.0.0:</p>\n<pre><code class=\"language-gradle\">compile 'org.grails.plugins:spring-security-saml:4.0.2'\n</code></pre>\n<p>NOTE: you may have to add the following repositories</p>\n<pre><code>repositories {\n maven { url "http://central.maven.org/maven2/"}\n maven { url "https://build.shibboleth.net/nexus/content/repositories/releases"}\n maven { url "https://build.shibboleth.net/nexus/content/groups/public/"}\n maven { url "https://code.lds.org/nexus/content/groups/main-repo"}\n maven { url "http://repository.jboss.org/maven2/"}\n}\n</code></pre>\n<p>See the <a href=\"https://jeffwils.github.io/grails-spring-security-saml/\">documentation page</a> for more information.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "spring-security-saml", |
| "repo": "plugins", |
| "owner": "valentingoebel", |
| "desc": "Grails spring-security-saml plugin", |
| "labels": [ |
| "security", |
| "spring-security", |
| "saml" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-spring-security-saml/grails-spring-security-saml/issues", |
| "latestVersion": "6.0.10", |
| "updated": "2025-04-07T07:07:49.000Z", |
| "systemIds": [ |
| "io.github.grails-spring-security-saml:spring-security-saml" |
| ], |
| "vcsUrl": "https://github.com/grails-spring-security-saml/grails-spring-security-saml" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/io/github/grails-spring-security-saml/spring-security-saml/maven-metadata.xml", |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "spring-security-shiro", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Grails spring-security-shiro plugin", |
| "labels": [ |
| "security", |
| "shiro", |
| "spring-security" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails-plugins/grails-spring-security-shiro/issues", |
| "latestVersion": "3.1.1", |
| "updated": "2018-05-14T06:57:20.438Z", |
| "systemIds": [ |
| "org.grails.plugins:spring-security-shiro" |
| ], |
| "vcsUrl": "https://github.com/grails-plugins/grails-spring-security-shiro" |
| }, |
| "documentationUrl": "https://grails-plugins.github.io/grails-spring-security-shiro/", |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails Spring Security Shiro Plugin <a href=\"https://travis-ci.org/grails-plugins/grails-spring-security-shiro\"><img src=\"https://travis-ci.org/grails-plugins/grails-spring-security-shiro.svg?branch=master\" alt=\"Build Status\" /></a></h1>\n<p>See <a href=\"http://grails-plugins.github.io/grails-spring-security-shiro/\">documentation</a> for further information.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "spring-security-ui", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Grails Spring Security UI", |
| "labels": [ |
| "security", |
| "spring-security" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/grails-spring-security-ui/issues", |
| "latestVersion": "4.0.0-RC1", |
| "updated": "2022-09-07T00:00:00.000Z", |
| "systemIds": [ |
| "org.grails.plugins:spring-security-ui" |
| ], |
| "vcsUrl": "https://github.com/grails-plugins/grails-spring-security-ui" |
| }, |
| "documentationUrl": "https://grails.github.io/grails-spring-security-ui/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/grails/plugins/spring-security-ui/maven-metadata.xml", |
| "readme": "<h1>Grails Spring Security UI</h1>\n<p><a href=\"https://grails.github.io/grails-spring-security-ui/\">Documentation</a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "spring-session", |
| "repo": "plugins", |
| "owner": "jeetmp3", |
| "desc": "This plugin provides spring-session support in grails application.", |
| "labels": [ |
| "http-session" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/jeetmp3/spring-session/issues", |
| "latestVersion": "2.0.0-RC1", |
| "updated": "2016-03-31T13:31:54.746Z", |
| "systemIds": [ |
| "org.grails.plugins:spring-session" |
| ], |
| "vcsUrl": "https://github.com/jeetmp3/spring-session" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails 3</h1>\n<p>The <a href=\"https://bintray.com/jeetmp3/plugins/spring-session/view\">2.X version of the plugin</a> is compatible only with grails 3.</p>\n<h4><a href='https://goo.gl/VmI8yQ' target='_blank'>Grails 2.x Documentation</a></h4>\n<h1>spring-session-grails-plugin</h1>\n<p>This plugin provides <a href=\"http://projects.spring.io/spring-session\">spring-session</a> support in grails application. SpringSession provides nice features:</p>\n<ul>\n<li>HttpSession\n<ul>\n<li>Clustered Sessions</li>\n<li>Multiple Browser Sessions</li>\n<li>RESTful APIs</li>\n</ul>\n</li>\n<li>WebSocket</li>\n</ul>\n<p>SpringSession uses Redis to persist the HTTP Sessions.\nYou can find official documentation for Spring Session project here: http://docs.spring.io/spring-session/docs/1.0.1.RELEASE/reference/html5/</p>\n<p>Currently this plugin provides support for HttpSession only. WebSocket support will be added in further release.</p>\n<h2>Using</h2>\n<p>Just add a plugin in BuildConfig.groovy.</p>\n<pre><code>plugins {\n runtime ":spring-session:1.2"\n ...\n}\n</code></pre>\n<p>Note: Redis must be installed on your machine.</p>\n<h2>Configuration</h2>\n<h4>1. Redis Configuration</h4>\n<p>Default configuration will lookup Redis server on your <code>localhost</code> port <code>6379</code>. To override default configuration add below code in Config.groovy</p>\n<pre><code>springsession.redis.connectionFactory.hostName = "<redis server ip>"\nspringsession.redis.connectionFactory.port = 6379\nspringsession.redis.connectionFactory.password = "<password>"\nspringsession.redis.connectionFactory.timeout = 2000\nspringsession.redis.connectionFactory.usePool = true\nspringsession.redis.connectionFactory.dbIndex = 0\n</code></pre>\n<h4>2. Change Session Strategy Configuration</h4>\n<p>Default session strategy is <code>Cookie</code> based and session cookie name is <code>SESSION</code> You can override the default session strategy</p>\n<pre><code>springsession.strategy.defaultStrategy='HEADER'\n</code></pre>\n<p>This will enable HTTP Header based session strategy. Default token name is <code>x-auth-token</code> you can override this</p>\n<pre><code>springsession.strategy.token.headerName = "new token name"\n</code></pre>\n<p>To change default cookie name add below configuration.</p>\n<pre><code>springsession.strategy.cookie.name="Your Cookie name"\n</code></pre>\n<p>(<strong>Note: Property ~~springsession.strategy.defaultStrategy.cookie.name~~ is no longer available in version 1.1 and higher</strong>)</p>\n<h4>3. Configure redis sentinel</h4>\n<pre><code>springsession.redis.sentinel.master="<Sentinel master name>"\nspringsession.redis.sentinel.nodes=[[host: "hostname", port: xxxx], [host: "another host", port: xxxx]]\nspringsession.redis.sentinel.password="Sentinel password"\n</code></pre>\n<h4>4. Enable update mutable objects in session</h4>\n<p>By default spring session doesn't update mutable object value stored in session. You can override this behaviour by setting\nbelow property to <code>true</code>. By default this value is <code>false</code>.</p>\n<pre><code>springsession.allow.persist.mutable = true\n</code></pre>\n<h2>Version Support</h2>\n<ul>\n<li>Grails 2.4 +</li>\n<li>Redis 2.8 +</li>\n</ul>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "springws", |
| "repo": "plugins", |
| "owner": "dmahapatro", |
| "desc": "Spring WS Plugin for Grails 3", |
| "labels": [ |
| "soap", |
| "spring-ws" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/dmahapatro/grails-springws/issues", |
| "latestVersion": "3.0.2", |
| "updated": "2016-06-20T21:49:14.187Z", |
| "systemIds": [ |
| "org.grails.plugins:springws" |
| ], |
| "vcsUrl": "https://github.com/dmahapatro/grails-springws/tree/grails3" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<p><strong>Spring WS Grails Plugin</strong></p>\n<p>Spring WS plugin without security.</p>\n<h2>Grails 3</h2>\n<p><strong>build.gradle Dependency:</strong></p>\n<pre><code class=\"language-groovy\">repositories {\n ...\n maven { url "http://dl.bintray.com/dmahapatro/plugins" }\n}\n\ndependencies {\n ...\n compile 'org.grails.plugins:springws:3.0.1'\n}\n</code></pre>\n<p>Plugin upgraded to Grails 3.1.8 with no security features. It uses <code>spring-boot-starter-ws</code> and partially follows the steps to <a href=\"https://spring.io/guides/gs/producing-web-service/\">Produce a SOAP service in Spring Boot app</a>. Use of JAXB, <code>@Endpoint</code>, <code>@PayloadRoot</code>, <code>@RequestPayload</code> and <code>@ResponsePayload</code> is avoided in order to stick to legacy plugin architecture.</p>\n<blockquote>\n<p>Legacy Grails 2 applications using this plugin and have a wide range of SOAP services will be stuck in Grails 2 unless services are moved to REST or a better version of SOAP Producer options. Making this plugin upgrade to Grails 3 will ease the transformation to Grails 3 apps without changing any of the plugin configuation or loginc inside the Endpoints and Interceptors.</p>\n</blockquote>\n<h2>Grails 2</h2>\n<p>With the upgrade of the plugin to Grails 2.4.2 came across the problem of clash between older version of spring security core with that of the latest got from Spring Security Core plugin 2.0-RC4.\nThis version is created by removing all security related classes and beans so that it won't give a compile error when used in an app in NetJets.</p>\n<p><strong>Dependency:</strong><br />\n<code>compile ':springws:2.1.0'</code></p>\n<p><strong>Feature for v2.1.0</strong>\nThis is an update to the older version of plugin (v 2.0.0) with the below basic feature updates:</p>\n<ul>\n<li>No Security features</li>\n<li>No dependency to spring-security-core</li>\n<li>Removed all security related classes to avoid compilation issues</li>\n</ul>\n<p><strong>Feature for v2.0.0</strong>\nThis is an update to the older version of plugin (v 1.0.0) with the below basic feature updates:</p>\n<ul>\n<li>Updated to Grails 2.4.2</li>\n<li>Updated <code>spring-ws-core</code> to version <code>2.2.0.RELEASE</code> from <code>2.1.2.RELEASE</code>.</li>\n<li>Removed deprecated classes</li>\n<li>Endpoints with security is a breaking change (TODO: Fix one test case)</li>\n</ul>\n<p><strong>Feature for v1.0.0</strong><br />\nThis is an update to the older version of <a href=\"http://grails.org/plugin/springws\">springws</a> plugin (v 0.5.0) with the below basic feature updates:</p>\n<ul>\n<li>Removed dependencies from <code>lib</code> directory to avoid clash with project dependencies.</li>\n<li>Updated <code>spring-ws-core</code> to version <code>2.1.2</code> from <code>1.5.8</code>.</li>\n<li>Added bean property <code>inline</code> to wsdl config in order to add imported schemas inline the <code>wsdl</code>.</li>\n<li>Added a separate <a href=\"https://github.com/dmahapatro/grails-springws-sample\">sample app</a> showing the usage of latest version of <code>springws</code> plugin.</li>\n</ul>\n<p><strong>To Run Locally</strong></p>\n<ul>\n<li>Clone the project.</li>\n<li>Run <code>grails maven-install</code> to package the plugin and push it to local <code>.m2</code> repo if avaialble.</li>\n<li>Or, use the plugin location directly using <code>grails.plugin.location.springws="your/plugin/location"</code>.</li>\n</ul>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "swagger", |
| "repo": "plugins", |
| "owner": "ajay-kumar", |
| "desc": "Grails Swagger Plugin", |
| "labels": [ |
| "swagger" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/ajay-kmr/swagger/issues", |
| "latestVersion": "1.0.1", |
| "updated": "2019-04-06T11:55:00.162Z", |
| "systemIds": [ |
| "org.grails.plugins:swagger", |
| "swagger:swagger" |
| ], |
| "vcsUrl": "https://github.com/ajay-kmr/swagger" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<div class=\"sect1\">\n<h2 id=\"_table_of_contents\">Table of Contents</h2>\n<div class=\"sectionbody\">\n<div class=\"olist arabic\">\n<ol class=\"arabic\">\n<li>\n<p>Introduction</p>\n</li>\n<li>\n<p>Installation</p>\n</li>\n<li>\n<p>Configuration</p>\n</li>\n<li>\n<p>How To Use</p>\n</li>\n<li>\n<p>Sample Code</p>\n</li>\n</ol>\n</div>\n<div class=\"sect2\">\n<h3 id=\"_introduction\">Introduction</h3>\n<div class=\"paragraph\">\n<p>This plugin provides easy integration of Swagger with GRAILS. It is highly aligned with Swagger and its 2.0 specification, thereby creating a language-agnostic interface to REST APIs. This allows both humans and computers to discover and understand the capabilities of service without access to source code, documentation simply through network traffic inspection</p>\n</div>\n</div>\n<div class=\"sect2\">\n<h3 id=\"_installation\">Installation</h3>\n<div class=\"olist arabic\">\n<ol class=\"arabic\">\n<li>\n<p>Add repository and dependency in your <strong><em>build.gradle</em></strong> file using below lines:-</p>\n</li>\n</ol>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre>repositories {\n maven { url \"https://dl.bintray.com/ajay-kumar/plugins\" }\n}\n\ndependencies {\n compile 'org.grails.plugins:swagger:1.0.1'\n}</pre>\n</div>\n</div>\n<div class=\"admonitionblock note\">\n<table>\n<tr>\n<td class=\"icon\">\n<div class=\"title\">Note</div>\n</td>\n<td class=\"content\">\nIf you are using version 1.0.0 or older, your logging might not work as per your expected logback config file.<br>\nThis is an issue with swagger servlet jar.\nIssue has already been raised for this:- <a href=\"https://github.com/swagger-api/swagger-core/issues/1813\">https://github.com/swagger-api/swagger-core/issues/1813</a><br>\nHowever, you can easily overcome this issue by explicitly setting the name of your logback configuration file in your <strong><em>build.gradle</em></strong> using:-<br>\n</td>\n</tr>\n</table>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-java\" data-lang=\"java\">bootRun {\n jvmArgs = [\n \"-Dlogging.config=${project.projectDir}/grails-app/conf/logback.groovy\"\n ]\n}</code></pre>\n</div>\n</div>\n<div class=\"admonitionblock note\">\n<table>\n<tr>\n<td class=\"icon\">\n<div class=\"title\">Note</div>\n</td>\n<td class=\"content\">\nAlternatively, you can also pass the name of logback configuration file using JVM argumants or system properties as follow:-\n</td>\n</tr>\n</table>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-java\" data-lang=\"java\">java -Dlogback.configurationFile=/path/to/config.xml</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>Please refer <a href=\"https://logback.qos.ch/manual/configuration.html#configFileProperty\">this link</a> to know more about how to set logback config file location.</p>\n</div>\n</div>\n<div class=\"sect2\">\n<h3 id=\"_configuration\">Configuration</h3>\n<div class=\"olist arabic\">\n<ol class=\"arabic\">\n<li>\n<p>Expose an API from your application by adding line- <strong><em>\"/apidoc/$action?/$id?\"(controller: \"apiDoc\", action: \"getDocuments\")</em></strong> in your <strong>UrlMappings.groovy</strong> file under the <strong>\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdstatic mappings\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd</strong> block.</p>\n<div class=\"admonitionblock note\">\n<table>\n<tr>\n<td class=\"icon\">\n<div class=\"title\">Note</div>\n</td>\n<td class=\"content\">\nThis API will be used to generate swagger document. So if you want to access your swagger document with different URI, do the necessary changes here eg if you want to expose your swagger document using URI- <strong><em>api/vi/myDoc</em></strong> then you should add <strong><em>\"/api/vi/myDoc/$action?/$id?\"(controller: \"apiDoc\", action: \"getDocuments\")</em></strong> in your <strong>UrlMappings.groovy</strong> file under the <strong>\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdstatic mappings\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd</strong> block.\n</td>\n</tr>\n</table>\n</div>\n</li>\n<li>\n<p>If your application is located behind a proxy that enables the required CORS headers then you need to enable CORS support too.</p>\n<div class=\"admonitionblock note\">\n<table>\n<tr>\n<td class=\"icon\">\n<div class=\"title\">Note</div>\n</td>\n<td class=\"content\">\nPlease read <a href=\"https://github.com/swagger-api/swagger-ui#testing-cors-support\">this article</a> to know if CORS support needs to be enabled or not for your application.\n</td>\n</tr>\n</table>\n</div>\n</li>\n<li>\n<p>Create a configuration file (eg application.groovy) in conf folder present inside your application\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffds grails-app folder (if not created yet) and add the following configuration details:-</p>\n</li>\n</ol>\n</div>\n<div class=\"paragraph\">\n<p>application.groovy</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-java\" data-lang=\"java\">import io.swagger.models.Scheme\n\nswagger {\n info {\n description = \"Move your app forward with the Swagger API Documentation\"\n version = \"ttn-swagger-1.0.0\"\n title = \"Swagger API\"\n termsOfServices = \"http://swagger.io/\"\n contact {\n name = \"Contact Us\"\n url = \"http://swagger.io\"\n email = \"contact@gmail.com\"\n }\n license {\n name = \"licence under http://www.tothenew.com/\"\n url = \"http://www.tothenew.com/\"\n }\n }\n schemes = [Scheme.HTTP]\n consumes = [\"application/json\"]\n}</code></pre>\n</div>\n</div>\n</div>\n<div class=\"sect2\">\n<h3 id=\"_how_to_use\">How To Use</h3>\n<div class=\"olist arabic\">\n<ol class=\"arabic\">\n<li>\n<p>Next there is a good example to show you how the set of annotations can be used to generate swagger documentation.\nPlease refer <a href=\"https://github.com/ajay-kmr/swagger/blob/master/swagger/src/test/groovy/services/swaggerResources/SwaggerAnnotatedResource.groovy\">this sample example</a> to know more.</p>\n</li>\n<li>\n<p>A set of annotations is used to generate swagger documentation. Please refer <a href=\"https://github.com/swagger-api/swagger-core/wiki/Annotations\">this link</a> to know more about the available annotations.</p>\n<div class=\"admonitionblock note\">\n<table>\n<tr>\n<td class=\"icon\">\n<div class=\"title\">Note</div>\n</td>\n<td class=\"content\">\nOnly annotations provided by swagger-core are supported and JAX-RS annotations are not supported.\n</td>\n</tr>\n</table>\n</div>\n</li>\n<li>\n<p>Annotate your controller class with annotation <em>@io.swagger.annotations.Api</em> to make it available for documentation. For more details see sample code.</p>\n</li>\n<li>\n<p>Annotate your methods/action of controller with <em>@io.swagger.annotations.ApiOperation, @io.swagger.annotations.ApiResponses, @io.swagger.annotations.ApiImplicitParams</em> to include various method level information in your documentation. <strong>See next section to know more details about how to use these annotations.</strong></p>\n<div class=\"admonitionblock note\">\n<table>\n<tr>\n<td class=\"icon\">\n<div class=\"title\">Note</div>\n</td>\n<td class=\"content\">\nThe value corresponding to <strong>\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdvalue\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd</strong> attribute of <strong>API</strong> annotation present at class level and the value corresponding to <strong>\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdnickname\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd</strong> attribute of <strong>\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdApiOperation\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd</strong> annotation present at method level when combined together, <em>it should form the relative end point provided in UrlMappings.groovy.</em>\n <strong>Refer to explanation below the provided sample.</strong>\n</td>\n</tr>\n</table>\n</div>\n</li>\n<li>\n<p>If the <strong>\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdvalue\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd</strong> attribute of <strong>\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdAPI\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd</strong> annotation present at class label is not provided then it defaults to the controller name.</p>\n</li>\n<li>\n<p>The <strong>\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdnickname\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd</strong> attribute of <strong>\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdApiOperation\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd</strong> annotation is also new and serves as unique name for the operation. If this is not provided this default to the method name</p>\n<div class=\"admonitionblock note\">\n<table>\n<tr>\n<td class=\"icon\">\n<div class=\"title\">Note</div>\n</td>\n<td class=\"content\">\nIf you are not explicitly providing the mapping of your actions defined in controller to the end points using <strong>UrlMappings.groovy</strong> file, you need not to bother about <strong>\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdvalue\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd</strong> attribute of <strong>\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdAPI\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd</strong> annotation present at <strong>class</strong> label and <strong>\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdnickname\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd</strong> attribute of <strong>\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdApiOperation\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd</strong> annotation present at <strong>method</strong> label. Its default value will work fine.\n</td>\n</tr>\n</table>\n</div>\n</li>\n</ol>\n</div>\n</div>\n<div class=\"sect2\">\n<h3 id=\"_sample_code\">Sample Code</h3>\n<div class=\"paragraph\">\n<p>Assume your <strong>UrlMappings.groovy</strong> class is as follow:-</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-java\" data-lang=\"java\">package testswaggerplugin\n\nclass UrlMappings {\n static mappings = {\n \"/$controller/$action?/$id?(.$format)?\" {\n constraints {\n // apply constraints here\n }\n }\n \"/\"(view: \"/index\")\n \"500\"(view: '/error')\n \"404\"(view: '/notFound')\n \"/api/v1/city/$cityId\"(controller: \"city\", action: \"getCity\", method: \"GET\")\n \"/api/v1/city/list\"(controller: \"city\", action: \"getCityList\", method: \"GET\")\n \"/api/v1/city/createUpdate\"(controller: \"city\", action: \"createOrUpdateCity\", method: \"POST\")\n \"/api/v1/city/$cityId\"(controller: \"city\", action: \"deleteCity\", method: \"DELETE\")\n }\n}</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>Then your swagger annotated <strong>CityController.groovy</strong> is as follow:-</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-java\" data-lang=\"java\">package testswaggerplugin\n\nimport CityDTO\nimport ResponseDTO\nimport grails.converters.JSON\nimport io.swagger.annotations.*\n\n@Api(value = \"/api/v1\", tags = [\"City\"], description = \"City Api's\")\nclass CityController {\n\n static namespace = 'v1'\n\n @ApiOperation(\n value = \"List Cities\",\n nickname = \"city/{cityId}\",\n produces = \"application/json\",\n consumes = \"application/json\",\n httpMethod = \"GET\",\n response = ResponseDTO.class\n )\n @ApiResponses([\n @ApiResponse(code = 405,\n message = \"Method Not Allowed. Only GET is allowed\"),\n\n @ApiResponse(code = 404,\n message = \"Method Not Found\")\n ])\n @ApiImplicitParams([\n @ApiImplicitParam(name = \"cityId\",\n paramType = \"path\",\n required = true,\n value = \"City Id\",\n dataType = \"string\"),\n\n @ApiImplicitParam(name = \"applicationType\",\n paramType = \"header\",\n required = true,\n defaultValue = \"web\",\n value = \"Application Types\",\n dataType = \"string\"),\n\n @ApiImplicitParam(name = \"Accept-Language\",\n paramType = \"header\",\n required = true,\n defaultValue = \"en\",\n value = \"Accept-Language\",\n dataType = \"string\")\n ])\n def getCity(String cityId) {\n // Demonstrate how to use swagger annotation to generate documentation\n // for method which accepts cityId as parameter provided in url path.\n\n render(new ResponseDTO(status: true,\n message: \"New Delhi\",\n data: [\"key1\": \"value1\", \"key2\": \"value2\"]) as JSON)\n }\n\n @ApiOperation(\n value = \"List Cities\",\n nickname = \"city/list\",\n produces = \"application/json\",\n consumes = \"application/json\",\n httpMethod = \"GET\",\n response = ResponseDTO.class\n )\n @ApiResponses([\n @ApiResponse(code = 405,\n message = \"Method Not Allowed. Only GET is allowed\"),\n\n @ApiResponse(code = 404,\n message = \"Method Not Found\")\n ])\n\n @ApiImplicitParams([\n @ApiImplicitParam(name = \"offset\",\n paramType = \"query\", required = true,\n value = \"Offset\", dataType = \"integer\"),\n\n @ApiImplicitParam(name = \"limit\",\n paramType = \"query\",\n required = true,\n value = \"Max size\",\n dataType = \"integer\"),\n\n @ApiImplicitParam(name = \"applicationType\",\n paramType = \"header\",\n required = true,\n defaultValue = \"web\",\n value = \"Application Types\",\n dataType = \"string\"),\n\n @ApiImplicitParam(name = \"Accept-Language\",\n paramType = \"header\",\n required = true,\n defaultValue = \"en\",\n value = \"Accept-Language\",\n dataType = \"string\")\n ])\n def getCityList(Integer offset, Integer limit) {\n // Demonstrate how to use swagger annotation to generate documentation\n // for method which accepts offset and limit as query parameter.\n render(new ResponseDTO(status: true,\n message: \"City List fetched successfully\",\n data: [\"key1\": \"value1\", \"key2\": \"value2\"]) as JSON)\n }\n\n @ApiOperation(\n value = \"Create City\",\n notes = \"Creates a new City. Accepts a City json.\",\n produces = \"application/json\",\n consumes = \"application/json\",\n httpMethod = \"POST\",\n nickname = \"/city/createUpdate\",\n response = ResponseDTO.class\n )\n @ApiResponses([\n @ApiResponse(code = 405,\n message = \"Method Not Allowed. Only POST is allowed\"),\n\n @ApiResponse(code = 404,\n message = \"Method Not Found\")\n ])\n @ApiImplicitParams([\n @ApiImplicitParam(name = \"body\",\n paramType = \"body\",\n required = true,\n value = \"Requires City Details\",\n dataType = \"CityDTO\"),\n\n @ApiImplicitParam(name = \"applicationType\",\n paramType = \"header\",\n required = true,\n defaultValue = \"web\",\n value = \"Application Types\",\n dataType = \"string\"),\n\n @ApiImplicitParam(name = \"Accept-Language\",\n paramType = \"header\",\n required = true,\n defaultValue = \"en\",\n value = \"Accept-Language\",\n dataType = \"string\")\n ])\n def createOrUpdateCity(CityDTO cityDTO) {\n render(new ResponseDTO(status: true,\n message: \"City updated successfully\",\n data: cityDTO) as JSON)\n }\n\n @ApiOperation(\n value = \"Delete City\",\n notes = \"Deletes a City.Accepts a City ID .\",\n produces = \"application/json\",\n consumes = \"application/json\",\n httpMethod = \"DELETE\",\n nickname = \"/city/{cityId}\",\n response = ResponseDTO.class\n )\n @ApiResponses([\n @ApiResponse(code = 405,\n message = \"Method Not Allowed. Only Delete is allowed\"),\n @ApiResponse(code = 404,\n message = \"Method Not Found\")])\n\n @ApiImplicitParams([\n @ApiImplicitParam(name = 'cityId',\n paramType = 'path',\n required = true, value = \"Requires City id for delete\",\n dataType = \"string\"),\n\n @ApiImplicitParam(name = \"applicationType\",\n paramType = \"header\",\n required = true,\n defaultValue = \"web\",\n value = \"Application Types\",\n dataType = \"string\"),\n\n @ApiImplicitParam(name = \"Accept-Language\",\n paramType = \"header\",\n required = true,\n defaultValue = \"en\",\n value = \"Accept-Language\",\n dataType = \"string\")\n ])\n def deleteCity(String cityId) {\n render(new ResponseDTO(status: true,\n message: \"City deleted successfully\") as JSON)\n }\n\n @ApiOperation(value = \"Upload File Example\",\n notes = \"Upload File Example\",\n nickname = \"/city/upload\",\n response = ResponseDTO.class,\n httpMethod = \"POST\")\n @ApiResponses(value = [\n @ApiResponse(code = 405, message = \"Method Not Allowed. Only POST is allowed\"),\n @ApiResponse(code = 404, message = \"Method Not Found\")\n ])\n @ApiImplicitParams([\n @ApiImplicitParam(name = 'cityFile', paramType = 'form',\n required = true,\n value = \"Requires File Containing City Information\",\n dataType = \"java.io.File\")])\n ResponseDTO uploadCityData(HttpServletRequest request) {\n // Demonstrate how to use swagger annotation to generate documentation\n // for method which accepts MultipartFile in request.\n MultipartFile file = request.getFile('cityFile')\n //Do with file\n (new ResponseDTO(status: true, message: \"File with name ${file?.originalFilename} uploaded successfully\") as JSON)\n }\n}</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>In the sample code provided above you can find that <strong>CityController</strong> is annotated with <strong>@Api(value = \"/api/v1\", tags = [\"City\"], description = \"City Api’s\")</strong>. So the value corresponding to <strong>\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdvalue\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd</strong> attribute of <strong>\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdAPI\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd</strong> annotation present at this class label is <strong>\"/api/v1\"</strong>.<br></p>\n</div>\n<div class=\"paragraph\">\n<p>Similarly you can observe that <strong>getCity()</strong> method of <strong>CityController</strong> has annotation <strong>@ApiOperation(value = \"List Cities\", nickname = \"city/{cityId}\", produces = \"application/json\", consumes = \"application/json\", httpMethod = \"GET\", response = ResponseDTO.class)</strong>. Hence the value corresponding to <strong>\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdnickname\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd</strong> attribute of <strong>\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdApiOperation\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd</strong> annotation present at this method label is <strong>\"city/{cityId}\"</strong> and when these two values of <strong>API</strong> annotation and <strong>ApiOperation</strong> annotations are combined together it gives- <strong>\"/api/v1/city/{cityId}\"</strong>.<br></p>\n</div>\n<div class=\"paragraph\">\n<p>This combined value is Swagger’s way of specifying the end url- <strong>\"/api/v1/city/$cityId\"</strong> defined in <strong>UrlMappings.groovy</strong> file for <strong>(controller: \"city\", action: \"getCity\", method: \"GET\")</strong></p>\n</div>\n</div>\n</div>\n</div>" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "swagger4jaxrs", |
| "repo": "plugins", |
| "owner": "donald-jackson", |
| "desc": "Grails swagger4jaxrs plugin", |
| "labels": [ |
| "swagger", |
| "jax-rs" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/donald-jackson/swagger4jaxrs/issues", |
| "latestVersion": "3.0.2", |
| "updated": "2016-05-18T10:06:43.567Z", |
| "systemIds": [ |
| "org.grails.plugins:swagger4jaxrs" |
| ], |
| "vcsUrl": "https://github.com/donald-jackson/swagger4jaxrs" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"http://www.nerderg.com/\"><img src=\"http://i.imgur.com/vNBBHNW.png\" alt=\"nerdErg home\" /></a></p>\n<hr />\n<h1><a href=\"http://grails.org/plugin/swagger4jaxrs\">swagger4jaxrs</a></h1>\n<p>This is a Grails plugin that adds <a href=\"https://developers.helloreverb.com/swagger/\">Swagger</a> support to document REST APIs of any Grails projects that use the <a href=\"http://grails.org/plugin/jaxrs\">Grails JAX-RS (JSR 311) plugin</a>.</p>\n<h2>Changelog</h2>\n<ul>\n<li><strong>version 0.2</strong>:</li>\n<li>The recommmended way to configure this plugin is using the Config.groovy files instead of the resources.groovy file. Lookk at the documentation bellow. This enables hot-swap when the configuration parameters change.</li>\n<li>Ugraded <strong>com.wordnick:swagger-jaxrs_2.10</strong> dependency to version <strong>1.3.2</strong> from 1.3.0</li>\n<li>Upgraded <a href=\"https://github.com/wordnik/swagger-ui\"><strong>swagger-ui</strong></a> client code to version <strong>2.0.14</strong> from 2.0.2</li>\n<li>Compatible with Grails 2.3 when using jaxrs:0.10</li>\n<li>Updated documentation.</li>\n<li><strong>version 0.1</strong>:</li>\n<li>Initial release.</li>\n</ul>\n<h2>Installation</h2>\n<p>First add the following plugin dependency to your BuildConfig.groovy file:</p>\n<pre><code class=\"language-groovy\">compile ":swagger4jaxrs:0.2"\n</code></pre>\n<p>By default this plugin depends on the jaxrs plugin <strong>version 0.8</strong>. That version of jaxrs is <strong>only compatible with Grails 2.2</strong>. If you are using a different version of Grails you will have to manually add the jaxrs plugin dependecy:</p>\n<ul>\n<li>If Grails version <= 2.2</li>\n</ul>\n<pre><code> compile ":jaxrs:0.9"\n</code></pre>\n<ul>\n<li>If Grails version >= 2.3</li>\n</ul>\n<pre><code> compile ":jaxrs:0.10"\n</code></pre>\n<h2>Configuration</h2>\n<p>The following configuration is the minimum the plugin requires, which can be placed in the <code>grails-app/conf/Config.groovy</code> file:</p>\n<pre><code class=\"language-groovy\">'swagger4jaxrs' {\n resourcePackage = '<package with your resources>'\n}\n</code></pre>\n<p>And this is the fully enumerated setup:</p>\n<pre><code class=\"language-groovy\">'swagger4jaxrs' {\n resourcePackage = '<package with your resources>'\n\tbasePath = "${grailsApplication.config.grails.serverURL}/api" ?: ''\n version = '<your REST API version>' // Default "1".\n title = '<your desired title>' // Default: App Name.\n description = '<your description here>'\n contact = '<your email>'\n license = '<your license>'\n licenseUrl = '<your license link>'\n scan = true\n}\n</code></pre>\n<p>Make sure you have added the Swagger annotations in your JAX-RS "resources" with the required meta information to generate a comprehensive documentarion for you REST API. Next there is a good <a href=\"https://github.com/wordnik/swagger-core/tree/master/samples\" title=\"Swager implementation samples\">example</a> to show you how:</p>\n<pre><code class=\"language-java\">/**\n * Copyright 2012 Wordnik, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.wordnik.swagger.sample.resource;\n\nimport com.wordnik.swagger.annotations.*;\nimport com.wordnik.swagger.sample.data.UserData;\nimport com.wordnik.swagger.sample.model.User;\nimport com.wordnik.swagger.sample.exception.ApiException;\nimport com.wordnik.swagger.sample.exception.NotFoundException;\n\n\nimport javax.ws.rs.core.Response;\nimport javax.ws.rs.*;\n\n@Path("/api/user")\n@Api(value="/api/user", description = "Operations about user")\n@Produces({"application/json"})\npublic class UserResource {\n\tstatic UserData userData = new UserData();\n\n\t@POST\n\t@ApiOperation(value = "Create user", notes = "This can only be done by the logged in user.")\n\tpublic Response createUser(\n\t\t\t@ApiParam(value = "Created user object", required = true) User user) {\n\t\tuserData.addUser(user);\n\t\treturn Response.ok().entity("").build();\n\t}\n\n @POST\n @Path("/createWithArray")\n @ApiOperation(value = "Creates list of users with given input array")\n public Response createUsersWithArrayInput(@ApiParam(value = "List of user object", required = true) User[] users) {\n for (User user : users) {\n userData.addUser(user);\n }\n return Response.ok().entity("").build();\n }\n\n @POST\n @Path("/createWithList")\n @ApiOperation(value = "Creates list of users with given input array")\n public Response createUsersWithListInput(@ApiParam(value = "List of user object", required = true) java.util.List<User> users) {\n for (User user : users) {\n userData.addUser(user);\n }\n return Response.ok().entity("").build();\n }\n\n\t@PUT\n\t@Path("/{username}")\n\t@ApiOperation(value = "Updated user", notes = "This can only be done by the logged in user.")\n\t@ApiResponses(value = [\n\t\t\t@ApiResponse(code = 400, message = "Invalid user supplied"),\n\t\t\t@ApiResponse(code = 404, message = "User not found") ])\n\tpublic Response updateUser(\n\t\t\t@ApiParam(value = "name that need to be deleted", required = true) @PathParam("username") String username,\n\t\t\t@ApiParam(value = "Updated user object", required = true) User user) {\n\t\tuserData.addUser(user);\n\t\treturn Response.ok().entity("").build();\n\t}\n\n\t@DELETE\n\t@Path("/{username}")\n\t@ApiOperation(value = "Delete user", notes = "This can only be done by the logged in user.")\n\t@ApiResponses(value = [\n\t\t\t@ApiResponse(code = 400, message = "Invalid username supplied"),\n\t\t\t@ApiResponse(code = 404, message = "User not found") ])\n\tpublic Response deleteUser(\n\t\t\t@ApiParam(value = "The name that needs to be deleted", required = true) @PathParam("username") String username) {\n\t\tuserData.removeUser(username);\n\t\treturn Response.ok().entity("").build();\n\t}\n\n\t@GET\n\t@Path("/{username}")\n\t@ApiOperation(value = "Get user by user name", response = User.class)\n\t@ApiResponses(value = [\n\t\t\t@ApiResponse(code = 400, message = "Invalid username supplied"),\n\t\t\t@ApiResponse(code = 404, message = "User not found") ])\n\tpublic Response getUserByName(\n\t\t\t@ApiParam(value = "The name that needs to be fetched. Use user1 for testing. ", required = true) @PathParam("username") String username)\n\t\tthrows ApiException {\n\t\tUser user = userData.findUserByName(username);\n\t\tif (null != user) {\n\t\t\treturn Response.ok().entity(user).build();\n\t\t} else {\n\t\t\tthrow new NotFoundException(404, "User not found");\n\t\t}\n\t}\n\n\t@GET\n\t@Path("/login")\n\t@ApiOperation(value = "Logs user into the system", response = String.class)\n\t@ApiResponses(value = [ @ApiResponse(code = 400, message = "Invalid username/password supplied") ])\n\tpublic Response loginUser(\n\t\t\t@ApiParam(value = "The user name for login", required = true) @QueryParam("username") String username,\n\t\t\t@ApiParam(value = "The password for login in clear text", required = true) @QueryParam("password") String password) {\n\t\treturn Response.ok()\n\t\t\t\t.entity("logged in user session:" + System.currentTimeMillis())\n\t\t\t\t.build();\n\t}\n\n\t@GET\n\t@Path("/logout")\n\t@ApiOperation(value = "Logs out current logged in user session")\n\tpublic Response logoutUser() {\n\t\treturn Response.ok().entity("").build();\n\t}\n}\n\n</code></pre>\n<h2>Checking that everything is working</h2>\n<p>First of all, after running your app, please check that your <a href=\"https://github.com/wordnik/swagger-core/wiki/API-Declaration\">Swagger API declaration</a> is indeed available by using the following url:</p>\n<pre><code>http://localhost:<port>/<host-app-context>/api-docs\n</code></pre>\n<p>If you get a JSON body by visiting that url then you are ready to see if the <a href=\"https://github.com/wordnik/swagger-ui\">Swagger-UI</a> can render it in your browser:</p>\n<pre><code>http://localhost:<port>/<host-app-context>/showRestApi\n</code></pre>\n<p>or if you are using <a href=\"http://grails.org/doc/2.2.x/guide/theWebLayer.html#customizingUrlFormat\">"hyphenated" URL convention</a>:</p>\n<pre><code>http://localhost:<port>/<host-app-context>/show-rest-api\n</code></pre>\n<h3>and then you should be getting something as beautiful as the following screenshot :-):</h3>\n<p><img src=\"http://i.imgur.com/y7ar45l.png\" alt=\"Swagger REST API representation\" /></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "timezone-detection", |
| "repo": "plugins", |
| "owner": "captivatelabs", |
| "desc": "The Grails Timezone Detection Plugin makes use of the jsTimezoneDetect Library in order to make the client/browser's timezone available on the server/JVM.", |
| "labels": [ |
| "date", |
| "timezone" |
| ], |
| "licenses": [ |
| "MIT" |
| ], |
| "issueTrackerUrl": "https://github.com/dustindclark/grails-timezone-detection/issues", |
| "latestVersion": "0.4.57", |
| "updated": "2020-03-03T12:07:41.783Z", |
| "systemIds": [ |
| "com.captivatelabs.grails.plugins:timezone-detection" |
| ], |
| "vcsUrl": "https://github.com/dustindclark/grails-timezone-detection" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>About</h1>\n<p>The Grails Timezone Detection Plugin makes use of the\n<a href=\"http://pellepim.bitbucket.org/jstz/\">jsTimezoneDetect Library</a> in order to make the\nclient/browser's timezone available on the server/JVM. Additionally, this plugin overrides\nthe default Grails formatDate tag to make use of the user's current timezone.</p>\n<h1>Installation</h1>\n<p>Add the following to your BuildConfig.groovy in the plugins section:</p>\n<pre><code class=\"language-groovy\">compile "org.grails.plugins:timezone-detection:latest.integration"\n\n</code></pre>\n<h2>Latest Version</h2>\n<p><a href=\"https://bintray.com/captivatelabs/plugins/timezone-detection/_latestVersion\"><img src=\"https://api.bintray.com/packages/captivatelabs/plugins/timezone-detection/images/download.svg\" alt=\"Latest Version\" /></a></p>\n<h1>Usage</h1>\n<p>Simply include the tz:detect tag inside of your head tag (preferably in your layout):</p>\n<pre><code class=\"language-rhtml\"><head>\n ...\n <tz:detect />\n</head>\n</code></pre>\n<p>If the timezone has not already been detected, the plugin will do a quick redirect to set the timezone,\nand will then redirect back to the originally requested page. This guarantees that the formatDate tag\nwill make use of the end user's timezone, even on the first page.</p>\n<p>You can also use the 'show' tag to render other timezone information:</p>\n<pre><code class=\"language-rhtml\"><tz:show /> <!-- results in TimeZone ID (i.e. UTC, CST) -->\n<tz:show attribute="displayName" /> <!-- results in TimeZone display name (i.e. Universal Time Coordinated, America/Chicago, etc) -->\n</code></pre>\n<p>See the <a href=\"http://docs.oracle.com/javase/7/docs/api/java/util/TimeZone.html\">java.util.TimeZone class</a> for all available attributes.</p>\n<p>This plugin also overrides the default Grails implementations for <code>g:formatDate</code> and <code>g:datePicker</code> to make them timezone aware.\nAdditionally, you can make use of Java 8 by binding to an <code>Instant</code> instead of a date. For example:</p>\n<pre><code><g:datePicker date="${Instant.now()}" />\n</code></pre>\n<p><strong>NOTE\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd</strong> If you leverage Spring Security with rejectIfNoRule set to true <em>and</em> you intend to detect the user's timezone on unprotected pages\nor in your template/layout, you <em>MUST</em> unprotect /timezone/**. Otherwise, an infinite redirect to your login page may occur.\nThank you, @harbdog for pointing this out.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "twitter-service", |
| "repo": "plugins", |
| "owner": "novadge", |
| "desc": "Use Twitter API to read and write twitter data", |
| "labels": [ |
| "twitter" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/Novadge/twitter-service/issues", |
| "latestVersion": "0.2.4", |
| "updated": "2018-02-14T10:49:37.027Z", |
| "systemIds": [ |
| "org.grails.plugins:twitter-service", |
| "org.grails.plugins:twitter" |
| ], |
| "vcsUrl": "https://github.com/Novadge/twitter-service" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Twitter service</h1>\n<h2>Description</h2>\n<p>The Twitter service plug-in allows a grails application to use twitter API to read and write twitter data\nEg. post tweets, retrieve tweets, send direct messages, etc.</p>\n<h2>Configuration</h2>\nAdd `compile 'org.grails.plugins:twitter:0.1.6'` to your build.gradle file\n<h3>Side note </h3>\nYou have to retrieve twitter credentials from twitter.com in order to use their API. Go to \n[https://dev.twitter.com/] to create an app and retrieve the necessary API keys and access tokens\n<h2>Usage</h2>\n<p><em>twitterService</em> provides several methods for interactions with twitter API.</p>\n<p>Inject twitterService into your controller</p>\n<p><code>def twitterService</code></p>\n<p><code>class MyController{ def twitterService }</code></p>\n<p>Inside your controller action, retrieve a twitter object like this:</p>\n<pre><code>def myCustomerAction(){ \n String consumerKey = [YOUR_TWITTER_APP_CONSUMER_KEY]\n String consumerSecret = [YOUR_TWITTER_APP_CONSUMER_SECRET]\n String accessToken = [TWITTER_ACCESS_TOKEN]\n String accessTokenSecret = [TWITTER_ACCESS_TOKEN_SECRET]\n Map twitterProps = [consumerKey:consumerKey,consumerSecret:consumerSecret,\n accessToken:accessToken,accessTokenSecret:accessTokenSecret]\n // post a tweet\n Map twitterParams = [text:"Hello twitter"]\n twitterService.updateStatus(twitterParams, twitterProps)\n \n // delete a tweet\n twitterParams = [statusId:'THE_TWEET_ID']\n twitterService.destroyStatus(twitterParams, twitterProps)\n \n // retrieve a single tweet\n twitterParams = [statusId:'THE_TWEET_ID']\n twitterService.showStatus(twitterParams, twitterProps)\n \n // send direct message\n twitterParams = [recipientId:'TWITTER_USER_ID',text:"Hello friend"]\n twitterService.sendDirectMessage(twitterParams, twitterProps)\n \n // get direct messages\n twitterParams = [count:5]\n twitterService.getDirectMessages(twitterParams,twitterProps)\n}\n</code></pre>\n<p>`</p>\n<p>And so much more you could do ......</p>\n<h4></h4>\nDo not forget to fork the project, fix bugs, or add features :)\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "typescript-asset-pipeline", |
| "repo": "asset-pipeline", |
| "owner": "bertramlabs", |
| "desc": null, |
| "labels": [ |
| "asset-pipeline", |
| "typescript" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/bertramdev/asset-pipeline/issues", |
| "latestVersion": "4.3.0", |
| "updated": "2023-05-01T16:24:22.000Z", |
| "systemIds": [ |
| "com.bertramlabs.plugins:typescript-asset-pipeline" |
| ], |
| "vcsUrl": "https://github.com/bertramdev/asset-pipeline" |
| }, |
| "documentationUrl": "https://bertramdev.github.io/asset-pipeline/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/com/bertramlabs/plugins/typescript-asset-pipeline/maven-metadata.xml", |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "version-update", |
| "repo": "grails-plugins", |
| "owner": "mathifonseca", |
| "desc": "Provides a friendlier way to update your application or plugin version.", |
| "labels": [ |
| "util" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/mathifonseca/grails-version-update/issues", |
| "latestVersion": "2.0.0", |
| "updated": "2016-08-22T12:50:16.298Z", |
| "systemIds": [ |
| "org.grails.plugins:version-update" |
| ], |
| "vcsUrl": "https://github.com/mathifonseca/grails-version-update" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>Grails Plugin for Application or Plugin Version Update</h1>\n<p><a href=\"https://travis-ci.org/mathifonseca/grails-version-update\"><img src=\"https://travis-ci.org/mathifonseca/grails-version-update.svg?branch=master\" alt=\"Build Status\" /></a></p>\n<p>When you have a bunch of applications or plugins to maintain and each of them needs to update its version with every change, and you combine that with your useless memory... you end up following always the same process:</p>\n<ol>\n<li>Make your changes</li>\n<li>Start writing the <code>grails set-version</code> command</li>\n<li>Forget which the current version was</li>\n<li>Check the <code>application.properties</code> (or <code>*GrailsPlugin.groovy</code> for plugins) file to get the current version</li>\n<li>Go back to your command and finish writing it</li>\n<li>Execute the command</li>\n</ol>\n<p>So, when you get tired of that, you create a plugin for doing a little less steps and your process becomes:</p>\n<ol>\n<li>Make your changes</li>\n<li>Execute the <code>grails version-update</code> command</li>\n<li>Drink your coffee</li>\n</ol>\n<p><a href=\"http://i.imgur.com/iZcUNxH.gif\">Magic</a>, right?</p>\n<h2>Usage</h2>\n<p><code>grails version-update $param $label</code></p>\n<p>The idea is that you write the least possible. So by convention, if you don't type any params, the plugin will increase the last level of your version by one.</p>\n<p>In case you type a param, it can be the exact version you want or you can do some tricks using a simple notation. Lets imagine that your current version is 0.2.4.6 and you want to <strong>keep</strong> the 0, <strong>increase</strong> the 2, <strong>decrease</strong> the 4 and <strong>change</strong> the 6 to 1. The param you should type (for this extremely complicated version change) would be: <code>x.+.-.1</code>. Each char meaning, default values and configuration is explained below.</p>\n<p>Lets think of some more common examples:</p>\n<pre><code>Old version: 0.2.4\nCommand: grails version-update\nNew version: 0.2.5\n</code></pre>\n<pre><code>Old version: 0.2.4\nCommand: grails version-update x.+.x\nNew version: 0.3.4\n</code></pre>\n<pre><code>Old version: 0.2.4\nCommand: grails version-update +.+.0\nNew version: 1.3.0\n</code></pre>\n<pre><code>Old version: 0.2.4\nCommand: grails version-update 8.-.x\nNew version: 8.1.4\n</code></pre>\n<p>Also, starting from version 1.2.0 of this plugin, you can use shortcuts to increase major, minor or patch versions and reset or keep the other accordingly.</p>\n<p>For example:</p>\n<pre><code>Old version: 1.2.4\nCommand: grails version-update M\nNew version: 2.0.0\n</code></pre>\n<pre><code>Old version: 1.2.4\nCommand: grails version-update m\nNew version: 1.3.0\n</code></pre>\n<pre><code>Old version: 1.2.4\nCommand: grails version-update p\nNew version: 1.2.5\n</code></pre>\n<p>From version 1.5.0 of this plugin, if you specify a second param, it will be used as a label for the version. This is useful for tagging alpha, beta, snapshot, release candidates, etc. Anything you type will be appended to the version, except for <code>s</code> and <code>rc</code>, which are shortcuts for <code>SNAPSHOT</code> and <code>RC</code>.</p>\n<pre><code>Old version: 1.2.4\nCommand: grails version-update p beta\nNew version: 1.2.5-beta\n</code></pre>\n<pre><code>Old version: 1.2.4\nCommand: grails version-update p s\nNew version: 1.2.5-SNAPSHOT\n</code></pre>\n<pre><code>Old version: 1.2.4\nCommand: grails version-update p rc\nNew version: 1.2.5-RC\n</code></pre>\n<h2>Configuration</h2>\n<h3>Grails 3.x</h3>\n<p>You need to make two small changes in your application configuration.</p>\n<p>First, add the <code>appVersion</code> key in your <code>gradle.properties</code> file like this:</p>\n<pre><code>grailsVersion=3.1.9\ngradleWrapperVersion=2.9\nappVersion=1.0.0 //add this line\n</code></pre>\n<p>Then, go to your <code>build.gradle</code> file and change the <code>version</code> line to this:</p>\n<pre><code>version appVersion\n</code></pre>\n<p>Remember to never change the version directly in your <code>build.gradle</code> manually. If you need to do it, change the value in your <code>gradle.properties</code>.</p>\n<h3>Grails 2.x</h3>\n<p>The plugin is thought to be used with the standard version format taken from <a href=\"http://semver.org/\">Semantic Versioning 2.0.0</a> where, in summary, they define the format <strong>X.Y.Z</strong> as the standard. The plugin uses this as convention, but if you want to override it, you can do it by adding the following at the end of your <code>BuildConfig.groovy</code></p>\n<pre><code class=\"language-groovy\">grails.project.dependency.resolution = {\n repositories {\n ...\n }\n dependencies {\n ...\n }\n plugins {\n ...\n }\n}\n\nversionUpdate {\n\n depth = 3\n separator = '.'\n keep = 'x'\n increase = '+'\n decrease = '-'\n major = 'M'\n minor = 'm'\n patch = 'p'\n colored = true\n\n}\n</code></pre>\n<p>Those values are also the defaults. That means that if you do not define any of them, the above values are going to be asumed.</p>\n<p>Here is an explanation of each of them:</p>\n<h4>depth</h4>\n<p>This is the amount of levels that your version has. The default is 3, so the expected format is X.Y.Z but if you change it to 4, it will be W.X.Y.Z and so on.</p>\n<h4>separator</h4>\n<p>You also can change the separator for each level. The default is a simple dot, but if you want something like X-Y-Z, you should change this value.</p>\n<h4>keep</h4>\n<p>This char means that you want to maintain the version at that level as it is right now. For example, the command 'x.x.7' would only put a seven at the last level and keep the others unchanged.</p>\n<h4>increase</h4>\n<p>This is the char that means that you want to increase by one the version in the specified level. For example, the command 'x.x.+' will keep the first two levels as they are and increase the last one by one.</p>\n<h4>decrease</h4>\n<p>The opposite of the above, you use this char when you want to decrease your version at that level. Note that if it is already zero, it will stay in zero to avoid negative numbers.</p>\n<h4>major</h4>\n<p>This means that you want to increase your major version and reset minor and patch to zero. Only works when depth is 3.</p>\n<h4>minor</h4>\n<p>This means that you want to increase your minor version. It will keep major as it is and reset patch to zero. Only works when depth is 3.</p>\n<h4>patch</h4>\n<p>This means that you want to increase your patch version and keep major and minor untouched. Only works when depth is 3.</p>\n<h4>colored</h4>\n<p>By default, the output of the command will be colored to help you identify the new version. If you want to deactivate this, you can set this flag to false.</p>\n<h2>Contact</h2>\n<p>If you have any questions or suggestions, you can contact me at <a href=\"mailto:mathifonseca@gmail.com\">mathifonseca@gmail.com</a> or make any pull requests you want.</p>\n<h2>Release Notes (excluding patches)</h2>\n<pre><code>0.0.1 > Initial version\n1.0.0 > It's official and published. Also upgraded to Grails 2.3.5 and improved performance.\n1.1.0 > Now working for updating plugin versions. Upgraded to Grails 2.3.8.\n1.2.0 > Added shortcuts for increasing major, minor and patch versions.\n1.3.0 > Added labels support (x.y.z-label).\n1.4.0 > Added colored output deactivation support.\n1.5.0 > Added shortcut for SNAPSHOT labels.\n1.6.0 > Added shortcut for RC labels.\n2.0.0 > Grails 3.x compatibility. (Grails 2.x versions will still be maintained)\n</code></pre>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "view-tools", |
| "repo": "grails-plugins", |
| "owner": "9ci", |
| "desc": "Grails View tools - Grails plugin to help locate views in the spring mvc context", |
| "labels": [ |
| "views" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/yakworks/view-tools/issues", |
| "latestVersion": "1.2.1", |
| "updated": "2019-05-09T18:34:34.658Z", |
| "systemIds": [ |
| "org.grails.plugins:view-tools" |
| ], |
| "vcsUrl": "https://github.com/yakworks/view-tools" |
| }, |
| "documentationUrl": "https://yakworks.github.io/view-tools/", |
| "mavenMetadataUrl": null, |
| "readme": "<p><a href=\"https://circleci.com/gh/yakworks/view-tools\"><img src=\"https://img.shields.io/circleci/project/github/yakworks/view-tools/master.svg?longCache=true&style=for-the-badge&logo=circleci\" alt=\"CircleCI\" /></a>\n<a href=\"http://9ci.com\"><img src=\"https://img.shields.io/badge/BUILT%20BY-9ci%20Inc-blue.svg?longCache=true&style=for-the-badge\" alt=\"9ci\" /></a>\n<img src=\"https://forthebadge.com/images/badges/built-with-love.svg\" height=\"28\">\n<a href=\"https://forthebadge.com\"><img src=\"https://forthebadge.com/images/badges/made-with-groovy.svg\" alt=\"forthebadge\" /></a>\n<img src=\"https://forthebadge.com/images/badges/gluten-free.svg\" height=\"28\">\n<a href=\"https://forthebadge.com\"><img src=\"https://forthebadge.com/images/badges/approved-by-george-costanza.svg\" alt=\"forthebadge\" /></a></p>\n<pre style=\"line-height: normal; background-color:#2b2929; color:#76ff00; font-family: monospace; white-space: pre;\">\n\n____ ____.__ _.-````'-,_\n\\ \\ / /|__| ____ __ _ __ ,-'` `'-.,_\n \\ Y / | |_/ __ \\ \\ \\/ \\/ / /) (\\ 9ci's '``-.\n \\ / | |\\ ___/ \\ / ( ( .,-') ) Yak Works ```\n \\___/ |__| \\___ > \\/\\_/ \\ ' (_/ !!\n \\/ | /) ' !!!\n ___________ .__ ^\\ ~' ' ! !!!!\n \\__ ___/___ ____ | | ______ ! _/! , ! ! ! ! ! !!!\n | | / _ \\ / _ \\| | / ___/ \\Y, |!!! ! ! !! !! !!!!!!!\n | |( <_> | <_> ) |__\\___ \\ `!!! !!!! !! )!!!!!!!!!!!!!\n |____| \\____/ \\____/|____/____ > !! ! ! \\( \\( !!!|/! |/!\n \\/ /_( /_(/_( /_( /_( \n Version: 1.2.1\n \n</pre>\n<p><a href=\"docs/release-notes.md\">RELEASE NOTES</a></p>\n<p>| Guide | API |\n|------|--------|\n|<a href=\"https://yakworks.github.io/view-tools/\">Released Docs</a> | <a href=\"https://yakworks.github.io/view-tools/api\">Released Api</a>\n|<a href=\"https://yakworks.github.io/view-tools/snapshot\">snapshot</a> | <a href=\"https://yakworks.github.io/view-tools/snapshot/api\">snapshot</a></p>\n<pre><code>compile "org.grails.plugins:view-tools:1.2.1"\n\n</code></pre>\n<h2>Description</h2>\n<p>API Documentation can be found here <a href=\"https://yakworks.github.io/view-tools/api\">https://yakworks.github.io/view-tools/api</a></p>\n<p>utility helpers to locate views in the spring mvc context</p>\n<ul>\n<li><strong>ViewResourceLocator</strong> for locating views in grails-app/views, plugins, and custom external paths.</li>\n<li><strong>GrailsWebEnvironment</strong> for binding a mock request if one doesn't exist so that services can operate without a controller.</li>\n</ul>\n<p>Used to locate View resources whether in development or WAR deployed mode from static\nresources, custom resource loaders and binary plugins.\nLoads from a local grails-app folder for dev and from WEB-INF in\ndevelopment mode.</p>\n<h2>Install</h2>\n<p><strong>Grails 3</strong></p>\n<pre><code>compile org.grails.plugins:view-tools:1.2.0\n</code></pre>\n<p><strong>Grails 2</strong></p>\n<pre><code>compile :view-tools:0.3-grails2\n</code></pre>\n<h2>Configuration</h2>\n<p>To make plugin look into grails3 folders add next line as a first line for you <code>BuildConfig.groovy</code></p>\n<pre><code>grails.useGrails3FolderLayout = true\n</code></pre>\n<h3>ViewResourceLocator</h3>\n<p><strong>Example Bean</strong></p>\n<pre><code class=\"language-groovy\">viewResourceLocator(grails.plugin.viewtools.ViewResourceLocator) { bean ->\n //initial searchLocations\n searchLocations = [\n "classpath:templates/", // consistent with spring-boot defaults\n "file:/someLoc/my-templates/"\n ] \n\n searchBinaryPlugins = false //whether to look in binary plugins, does not work in grails2\n\n // in dev mode there will be a groovyPageResourceLoader \n // with base dir set to the running project\n //if(Environment.isDevelopmentEnvironmentAvailable()) <- better for Grails 3\n if(!application.warDeployed){ // <- grails2\n resourceLoader = ref('groovyPageResourceLoader') //adds to list, does not replace\n }\n\n}\n</code></pre>\n<ul>\n<li><strong>Resource locate(String uri)</strong> : is the primary method and is used to find a view resource for a path. For example /foo/bar.xyz will search for /WEB-INF/grails-app/views/foo/bar.xyz in production and grails-app/views/foo/bar.xyz at development time. It also uses the the controller if called from a plugin to figure out where its located and finally does a brute force locate. Most of the logic is based on and uses what Grail's DefaultGroovyPageLocator does.</li>\n<li><strong>Resource getResource(String uri)</strong> : also implements Springs <a href=\"https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/io/ResourceLoader.html\">ResourceLoader</a> interface. This method works like a normal ResoruceLoader and <strong>uri</strong> can start with the standard <em>file:, classpath:, etc</em></li>\n</ul>\n<h3>GrailsWebEnvironment</h3>\n<p>GrailsWebEnvironment.bindRequestIfNull() methods are the ones of interest.\nbased on the RenderEnvironment in grails-rendering and private class in grails-mail\nAll this does is bind a mock request and mock response if one doesn't exist\ndeals with setting the WrappedResponseHolder.wrappedResponse as well\nYou will need the spring test lib on your main compile.</p>\n<p><code>compile "org.springframework:spring-test"</code></p>\n<h3>Example App</h3>\n<p>see https://github.com/yakworks/view-tools/tree/master/test-projects/app\nIt contains a number of examples as well as a simple spring based viewResolver that uses ViewResourceLocator to find the template files it needs.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "views-gradle", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Enables Gradle to compile views for production environment", |
| "labels": [ |
| "views" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/grails-views/issues", |
| "latestVersion": "3.2.3", |
| "updated": "2024-04-04T11:02:55.000Z", |
| "systemIds": [ |
| "org.grails.plugins:views-gradle" |
| ], |
| "vcsUrl": "https://github.com/grails/grails-views" |
| }, |
| "documentationUrl": "https://views.grails.org/latest/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/grails/plugins/views-gradle/maven-metadata.xml", |
| "readme": "<h1>Grails Views</h1>\n<p>Additional View Technologies for Grails 3.0 and above.</p>\n<p>Initial implementation includes JSON views powered by Groovy's JsonBuilder, however this project provides the basis for implementation other view types.</p>\n<p>View <a href=\"https://grails.github.io/grails-views/latest/\">the latest documentation</a> for details.</p>\n<p><a href=\"https://github.com/grails/grails-views/actions/workflows/gradle.yml\"><img src=\"https://github.com/grails/grails-views/actions/workflows/gradle.yml/badge.svg?branch=master\" alt=\"Java CI\" /></a></p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "views-json-templates", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "If you are also using MongoDB you may want to add the views-json-templates plugin which includes support for GeoJSON", |
| "labels": [ |
| "views", |
| "json" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/grails-views/issues", |
| "latestVersion": "3.2.3", |
| "updated": "2024-04-04T11:03:05.000Z", |
| "systemIds": [ |
| "org.grails.plugins:views-json-templates" |
| ], |
| "vcsUrl": "https://github.com/grails/grails-views" |
| }, |
| "documentationUrl": "https://views.grails.org/latest/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/grails/plugins/views-json-templates/maven-metadata.xml", |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "views-markup", |
| "repo": "plugins", |
| "owner": "grails", |
| "desc": "Grails views-markup plugin", |
| "labels": [ |
| "views", |
| "xml" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/grails/grails-views/issues", |
| "latestVersion": "3.2.3", |
| "updated": "2024-04-04T11:03:08.000Z", |
| "systemIds": [ |
| "org.grails.plugins:views-markup" |
| ], |
| "vcsUrl": "https://github.com/grails/grails-views" |
| }, |
| "documentationUrl": "https://views.grails.org/latest/#_markup_views", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/grails/plugins/views-markup/maven-metadata.xml", |
| "readme": null |
| }, |
| { |
| "bintrayPackage": { |
| "name": "wkhtmltopdf", |
| "repo": "plugins", |
| "owner": "rlovtangen", |
| "desc": "Grails wkhtmltopdf plugin", |
| "labels": [ |
| "pdf" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/rlovtangen/grails-wkhtmltopdf/issues", |
| "latestVersion": "1.0.0.RC9", |
| "updated": "2018-05-07T20:01:31.387Z", |
| "systemIds": [ |
| "org.grails.plugins:wkhtmltopdf" |
| ], |
| "vcsUrl": "https://github.com/rlovtangen/grails-wkhtmltopdf" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<div id=\"preamble\">\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>This plugin provides an easy integration of <code>wkhtmltopdf</code>, a command line tool to render HTML into PDF.</p>\n</div>\n<div class=\"paragraph\">\n<p>This enables you to write a Grails View in HTML as usual, but render as PDF.</p>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_wkhtmltopdf\">Wkhtmltopdf</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p><code>wkhtmltopdf</code> and <code>wkhtmltoimage</code> are open source (LGPLv3) command line tools to render HTML into PDF and various image formats using the Qt WebKit rendering engine.\nThese run entirely \"headless\" and do not require a display or display service.<br>\n<a href=\"http://wkhtmltopdf.org/\" class=\"bare\">http://wkhtmltopdf.org/</a></p>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_installation\">Installation</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>In addition to adding the plugin as dependency to your Grails project, the <code>wkhtmltopdf</code> binary must be installed.\nSee instructions at <a href=\"http://wkhtmltopdf.org/\" class=\"bare\">http://wkhtmltopdf.org/</a> or install using your package manager (apt-get, yum, brew etc)</p>\n</div>\n<div class=\"paragraph\">\n<p>Finally make sure the following command works as expected:</p>\n</div>\n<div class=\"literalblock\">\n<div class=\"content\">\n<pre>wkhtmltopdf www.google.com test.pdf</pre>\n</div>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_configuration\">Configuration</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Put the following line into your <code>application.groovy</code> (or corresponding property in <code>application.yml</code>) and adjust the path to your wkhtmltopdf binary (<code>which wkhtmltopdf</code>)</p>\n</div>\n<div class=\"literalblock\">\n<div class=\"content\">\n<pre>grails.plugin.wkhtmltopdf.binary = \"/usr/local/bin/wkhtmltopdf\"</pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>Typical paths:</p>\n</div>\n<table class=\"tableblock frame-all grid-all stretch\">\n<colgroup>\n<col style=\"width: 50%;\">\n<col style=\"width: 50%;\">\n</colgroup>\n<thead>\n<tr>\n<th class=\"tableblock halign-left valign-top\">OS</th>\n<th class=\"tableblock halign-left valign-top\">Path</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td class=\"tableblock halign-left valign-top\"><p class=\"tableblock\">OS X</p></td>\n<td class=\"tableblock halign-left valign-top\"><p class=\"tableblock\">/usr/local/bin/wkhtmltopdf</p></td>\n</tr>\n<tr>\n<td class=\"tableblock halign-left valign-top\"><p class=\"tableblock\">Linux</p></td>\n<td class=\"tableblock halign-left valign-top\"><p class=\"tableblock\">/usr/bin/wkhtmltopdf</p></td>\n</tr>\n<tr>\n<td class=\"tableblock halign-left valign-top\"><p class=\"tableblock\">Windows</p></td>\n<td class=\"tableblock halign-left valign-top\"><p class=\"tableblock\">C:/local/wkhtmltopdf/wkhtmltopdf.exe</p></td>\n</tr>\n</tbody>\n</table>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_supported_grails_versions\">Supported Grails versions</h2>\n<div class=\"sectionbody\">\n<div class=\"sect2\">\n<h3 id=\"_grails_3_0_0_3_0_2\">Grails 3.0.0 - 3.0.2</h3>\n<div class=\"paragraph\">\n<p>Not supported</p>\n</div>\n</div>\n<div class=\"sect2\">\n<h3 id=\"_grails_3_0_3\">Grails 3.0.3</h3>\n<div class=\"paragraph\">\n<p>Add the pdf mime type to grails.mime.types in application.yml</p>\n</div>\n<div class=\"literalblock\">\n<div class=\"content\">\n<pre>pdf: application/pdf</pre>\n</div>\n</div>\n</div>\n<div class=\"sect2\">\n<h3 id=\"_grails_3_0_4_3_0_7\">Grails 3.0.4 - 3.0.7</h3>\n<div class=\"paragraph\">\n<p>Supported, but only with mail plugin 2.0.0.RC4. (See <a href=\"https://github.com/grails3-plugins/mail/issues/16\" class=\"bare\">https://github.com/grails3-plugins/mail/issues/16</a>)</p>\n</div>\n</div>\n<div class=\"sect2\">\n<h3 id=\"_grails_3_0_8\">Grails 3.0.8 > *</h3>\n<div class=\"paragraph\">\n<p>Supported</p>\n</div>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_usage\">Usage</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>To stream the content of a Controller-action as PDF just call <code>/some/someAction.pdf</code></p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-groovy\" data-lang=\"groovy\">class SomeController {\n def someAction() {\n def someInstance = SomeDomainObject.get(params.id)\n\n render( filename:\"File ${someInstance.id}.pdf\",\n view:\"/some/someGspTemplate\",\n model:[someInstance:someInstance],\n header:\"/pdf/someHeader\",\n footer:\"/pdf/someFooter\",\n marginLeft:20,\n marginTop:35,\n marginBottom:20,\n marginRight:20,\n headerSpacing:10)\n }\n}</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>Or create binary PDF data and use them for any other purpose</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-groovy\" data-lang=\"groovy\">class SomeService {\n\n static transactional = false\n\n def doSomething() {\n def byte[] pdfData = wkhtmltoxService.makePdf(\n view: \"/pdf/someGspTemplate\",\n model: [someInstance: someInstance],\n header: \"/pdf/someHeader\",\n footer: \"/pdf/someFooter\",\n marginLeft: 20,\n marginTop: 35,\n marginBottom: 20,\n marginRight: 20,\n headerSpacing: 10)\n\n\n // DO Something e.g. send as mail\n //sendAsynchronousMail {\n // multipart true\n // to \"mail@mail.de\"\n // subject \"see PDF Attachment\";\n // attachBytes \"PDF Attachment.pdf\", \"application/pdf\", pdfData\n // body \"see my pdf attachment\"\n //}\n }\n}</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>Write your GSPs as usual, just make sure, that the urls to the assets are absolute and reachable by the host machine</p>\n</div>\n<div class=\"paragraph\">\n<p>Development mode:</p>\n</div>\n<div class=\"literalblock\">\n<div class=\"content\">\n<pre>grails.assets.url = \"http://localhost:8080/assets/\"</pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>Production:</p>\n</div>\n<div class=\"literalblock\">\n<div class=\"content\">\n<pre>grails.assets.url = \"https://example.com/assets/\"</pre>\n</div>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_options\">Options</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>See the following command for all options available:</p>\n</div>\n<div class=\"literalblock\">\n<div class=\"content\">\n<pre>wkhtmltopdf --extended-help</pre>\n</div>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_known_issues\">Known issues</h2>\n<div class=\"sectionbody\">\n<div class=\"ulist\">\n<ul>\n<li>\n<p><code>wkhtmltopdf</code> must work ( try: <code>wkhtmltopdf www.myhomepage.com myhomepage.pdf</code> )</p>\n</li>\n<li>\n<p>For <code>v0.12.4</code> & Mac OS users <a href=\"https://github.com/wkhtmltopdf/wkhtmltopdf/issues/3241\" class=\"bare\">https://github.com/wkhtmltopdf/wkhtmltopdf/issues/3241</a></p>\n</li>\n<li>\n<p>Not tested on Windows (except Windows 7)</p>\n</li>\n</ul>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_changes_since_grails_2_version\">Changes since Grails 2 version</h2>\n<div class=\"sectionbody\">\n<div class=\"ulist\">\n<ul>\n<li>\n<p>Properties renamed from <code>grails.plugin.wkhtmltox.xxx</code> to <code>grails.plugin.wkhtmltopdf.xxx</code></p>\n</li>\n<li>\n<p>Removed support for property <code>grails.plugin.wkhtmltox.makeBinaryAvailableClosure</code>. Was not documented and didn’t work as expected.</p>\n</li>\n<li>\n<p>Package renamed to <code>org.grails.plugins.wkhtmltopdf</code></p>\n</li>\n</ul>\n</div>\n</div>\n</div>" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "wschat", |
| "repo": "maven", |
| "owner": "vahid", |
| "desc": "Grails wschat plugin", |
| "labels": [ |
| "chat", |
| "websocket" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/vahidhedayati/grails-wschat-plugin/issues", |
| "latestVersion": "3.0.16", |
| "updated": "2016-03-31T13:31:55.147Z", |
| "systemIds": [ |
| "org.grails.plugins:wschat", |
| "org.grails.plugins:grails-wschat-plugin" |
| ], |
| "vcsUrl": "https://github.com/vahidhedayati/grails-wschat-plugin" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>wschat</h1>\n<p>Grails websocket chat Plugin provides a multi-chat room add-on to an existing grails based site/application.</p>\n<h6><a href=\"https://github.com/vahidhedayati/grails-wschat-plugin/wiki/Installation\">How to install</a></h6>\n<h6><a href=\"https://github.com/vahidhedayati/grails-wschat-plugin/wiki/Config-v3.groovy\">Configuration variables required</a></h6>\n<h6><a href=\"https://github.com/vahidhedayati/grails-wschat-plugin/wiki/3.0.9---must-have-configuration\">3.0.9 must have these configuration items to work</a></h6>\n<h6><a href=\"https://github.com/vahidhedayati/grails-wschat-plugin/wiki/Version-info-v3\">Version info</a></h6>\n<h6><a href=\"https://github.com/vahidhedayati/grails-wschat-plugin/wiki/Creating-admin-accounts\">Creating admin accounts</a></h6>\n<h6><a href=\"https://github.com/vahidhedayati/grails-wschat-plugin/wiki/Customised-chat-menus-for-your-chat-users\">Customised chat menus for your chat users</a></h6>\n<h6><a href=\"https://github.com/vahidhedayati/grails-wschat-plugin/wiki/Customise-fonts-chat-output-through-css\">Customise fonts chat output through css</a></h6>\n<h6><a href=\"https://github.com/vahidhedayati/grails-wschat-plugin/wiki/Configure-internationlisation---customise-chat-output---menus\">Internationalisation</a></h6>\n<h6><a href=\"https://github.com/vahidhedayati/grails-wschat-plugin/wiki/Chat-Room-Bot---Live-Chat---Live-Chat-Bot\">How to use configure Live chat & Chat Bot</a></h6>\n<h6><a href=\"https://github.com/vahidhedayati/grails-wschat-plugin/wiki/profile-creation\">Add profile with taglib connection call</a></h6>\n<h6><a href=\"https://github.com/vahidhedayati/grails-wschat-plugin/wiki/Booking-chat-event\">Chat room booking/reservations</a></h6>\n<h6><a href=\"https://github.com/vahidhedayati/grails-wschat-plugin/wiki/WebtRTC-WebCam-walk-through\">WebtRTC WebCam walk through</a></h6>\n<h6><a href=\"https://github.com/vahidhedayati/grails-wschat-plugin/wiki/WebRTC-File-sharing-peer2peer\">WebtRTC File sharing</a></h6>\n<h6><a href=\"https://github.com/vahidhedayati/grails-wschat-plugin/wiki/Integrating-with-existing-grails-application\">Integrating with existing grails application</a></h6>\n<h6>Videos on youtube:</h6>\n<ol>\n<li>\n<p><a href=\"https://www.youtube.com/watch?v=E-NmbDZg9G4\">Video: grails app running wschat 0.14 part1</a></p>\n</li>\n<li>\n<p><a href=\"https://www.youtube.com/watch?v=xPxV_iEYYm0\">Video: grails app running wschat 0.14 part2</a></p>\n</li>\n<li>\n<p><a href=\"https://www.youtube.com/watch?v=zAySkzNid3E\">Video: Client/Server Messaging part 1.</a>\nEarlier version focus on backend control of socket messages. So the backend of your application. Override a service for this. Explained in links further below.</p>\n</li>\n<li>\n<p><a href=\"https://www.youtube.com/watch?v=xagMYM9n3l0\">Video: Client/Server Messaging part 2</a>\n(Messages via websockets to frontend). In short update frontend via websocket callbacks.</p>\n</li>\n<li>\n<p><a href=\"https://www.youtube.com/watch?v=ZQ86b6zN4aE\">Video: 1.12 Chat room booking/reservations</a></p>\n</li>\n<li>\n<p><a href=\"https://www.youtube.com/watch?v=aib29xIMkwU\">Video: 1.22 Multiple login with same Chat user and TicTacToe</a></p>\n</li>\n<li>\n<p><a href=\"https://www.youtube.com/watch?v=VrvJNPQ-K7M\">Video 1.23 Add Live chat to your grails application</a></p>\n</li>\n<li>\n<p><a href=\"https://www.youtube.com/watch?v=fUIckOntais\">Video 1.23-SNAPSHOT1 Live chat Logs BOT Artificial Intelligence and more</a></p>\n</li>\n<li>\n<p><a href=\"https://www.youtube.com/watch?v=jUm7QrQhpTk\">Video 1.24 Chat BOT now working in chat rooms, returning responses and banning/kicking users</a></p>\n</li>\n<li>\n<p><a href=\"https://www.youtube.com/watch?v=udbOq6fiD9o\">Video 1.25 LiveChat (1 room multiple users with 1 admin interacting with all)</a></p>\n</li>\n<li>\n<p><a href=\"https://www.youtube.com/watch?v=C-xPAr0RcIo\">Video 3.0.6 1.27 LiveChat monitoring and changing live chat style/colours</a></p>\n</li>\n<li>\n<p><a href=\"https://www.youtube.com/watch?v=PpzP6MsVKY0\">Video 3.0.9 Spring security</a></p>\n</li>\n</ol>\n<h6><a href=\"https://github.com/vahidhedayati/grails-wschat-plugin/wiki/Commands\">Chat Commands</a></h6>\n<h6><a href=\"https://github.com/vahidhedayati/grails-wschat-plugin/wiki/WebRTC-terminology\">STUN Server, setting up your own server & WebRTC-terminology</a></h6>\n<h6><a href=\"https://github.com/vahidhedayati/grails-wschat-plugin/wiki/resources-based-apps\">0.10+ & resources based apps (pre 2.4)</a></h6>\n<h6><a href=\"https://github.com/vahidhedayati/grails-wschat-plugin/wiki/wsChatClient-Client-Server-Messaging-new-feature-since-1.11\">ChatClientEndPoint Client/Server Messaging new feature since 1.11</a></h6>\n<h6><a href=\"https://github.com/vahidhedayati/grails-wschat-plugin/wiki/Screen-capture-commands\">How to screen capture</a></h6>\n<h6><a href=\"https://github.com/vahidhedayati/grails-wschat-plugin/wiki/Persist-Chat-to-DB\">Chat to DB</a></h6>\n<h6><a href=\"https://github.com/vahidhedayati/grails-wschat-plugin/wiki/offline-pm\">1.13 Offline Messaging - enable override</a></h6>\n<h6><a href=\"https://github.com/vahidhedayati/grails-wschat-plugin/wiki/complete-sites-demo-sites\">demo sites</a></h6>\n<h6><a href=\"https://github.com/vahidhedayati/grails-wschat-plugin/wiki/Known-issues\">Known issues</a></h6>\n<h6><a href=\"https://github.com/vahidhedayati/grails-wschat-plugin/wiki/Thanks-to\">Thanks to</a></h6>\n<h5>Grails wschat release/feature summary:</h5>\n<pre><code>3.0.6/1.27 \t- Major tidyup removed most ajax processing besides popup pages. \n\t\t\t Added css/internationlisation customisation\n\t\t\t \n3.0.5/1.26\t- Tidy up with new look and new feature to monitor Live Chat requests\n3.0.4/1.25 - Live Chat Many users to 1 admin (Video 10).\n\n3.0.3/1.24 - ChatBot and badWords added to the main chat room\n\n3.0.3/1.23 - Live Chat feature added as part of the plugin(watch video 7)\n\n3.0.3/1.21 - Websocket TicTacToe game added (Watch video 6)\n\n3.0.3/1.20 - Multiple login with same user but must be different rooms - removal of dbSupport check\n\n1.18 - Mediastreaming enabled but has not worked for me \n \n1.17 - Websocket -> WebRTC File sharing peer2peer available - \n \n1.12 - Chat room bookings for multiple participants\n \n1.0+ - Supports WebRTC currently only on Chrome Canary.\n\n0.19+ - Supports webcam tested on chrome/firefox.\n\nAdmin can: kick/Ban (for specified time period)\nUsers can create profiles define details and upload photos.\nChat rooms can be created in Config.groovy +/ DB once logged in using UI.\n\nYou can websocket :\n\tsend files / use webRTC technology to have video chat or share screen\n\tplay Tictactoe / noughts + crosses\n\tLive chat - set up a client easily and monitor live chats\n\tConfigure chat bookings / invite external attendees (emails)\n</code></pre>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "x-frame-options", |
| "repo": "plugins", |
| "owner": "mrhaki", |
| "desc": "Servlet filter that adds a X-FRAME-OPTIONS response header", |
| "labels": [ |
| "security" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/mrhaki/grails-x-frame-options-plugin/issues", |
| "latestVersion": "1.1.2", |
| "updated": "2017-04-06T10:24:55.924Z", |
| "systemIds": [ |
| "org.grails.plugins:x-frame-options" |
| ], |
| "vcsUrl": "https://github.com/mrhaki/grails-x-frame-options-plugin" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<div class=\"sect1\">\n<h2 id=\"_grails_x_frame_options_plugin\">Grails X-Frame-Options Plugin</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Filter to set HTTP response header X-Frame-Options to defend against\n<a href=\"http://en.wikipedia.org/wiki/Clickjacking\">ClickJacking</a>.</p>\n</div>\n<div class=\"paragraph\">\n<p>More information about using X-Frame-Options for defending against clickjacking:</p>\n</div>\n<div class=\"ulist\">\n<ul>\n<li>\n<p><a href=\"https://www.owasp.org/index.php/Clickjacking_Defense_Cheat_Sheet#Defending_with_X-Frame-Options_Response_Headers\">OWASP - Defending with X-Frame-Options response headers</a></p>\n</li>\n</ul>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_installation\">Installation</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>These instructions are targeted towards Grails 3 installations. For Grails 2.x refer to branch 1.x of the plugin.</p>\n</div>\n<div class=\"paragraph\">\n<p>Add a dependency to <code>build.gradle</code>:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre>...\ndependencies {\n ...\n runtime ('org.grails.plugins:x-frame-options:1.1.2')\n ...\n}\n...</pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>The default configuration installs a servlet filter for the URL pattern <code>/*</code> that adds a response\nheader <code>X-Frame-Options</code> with the value <code>DENY</code>.</p>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_configuration\">Configuration</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>The plugin is configured through <code>grails-app/conf/application.yml</code>.</p>\n</div>\n<div class=\"paragraph\">\n<p>We can limit the URL pattern the filter is applied to:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre>grails:\n plugin:\n xframeoptions:\n urlPattern: /path/*</pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>We can also set multiple patterns:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre>grails:\n plugin:\n xframeoptions:\n urlPattern:\n - /path/*\n - /other/*</pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>We can set different header values based on the configuration.\nTo set the header value <code>DENY</code> we must use the following configuration:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre>grails:\n plugin:\n xframeoptions:\n deny: true</pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>This is also the default value if no configuration is provided or no configuration options\nare set.</p>\n</div>\n<div class=\"paragraph\">\n<p>To set the header value <code>SAMEORIGIN</code> we must use the following configuration:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre>grails:\n plugin:\n xframeoptions:\n sameOrigin: true</pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>To set the header value <code>ALLOW-FROM</code> with a URL we must use the following configuration:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre>grails:\n plugin:\n xframeoptions:\n allowFrom: http://www.mrhaki.com</pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>To disable the filter we must use the following configuration option:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre>grails:\n plugin:\n xframeoptions:\n enabled: false</pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>The filter is enabled by default and will use the <code>DENY</code> header value.</p>\n</div>\n</div>\n</div>" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "xss-sanitizer", |
| "repo": "plugins", |
| "owner": "rpalcolea", |
| "desc": "This plugin uses OWASP ESAPI library to sanitize request parameters. This reduces the risk of dangerous XSS request parameters possibly being rendered on the client.", |
| "labels": [ |
| "security", |
| "xss", |
| "owasp" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/rpalcolea/grails-xss-sanitizer/issues", |
| "latestVersion": "1.0.0", |
| "updated": "2016-08-22T06:43:12.667Z", |
| "systemIds": [ |
| "org.grails.plugins:xss-sanitizer" |
| ], |
| "vcsUrl": "https://github.com/rpalcolea/grails-xss-sanitizer" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": null, |
| "readme": "<h1>grails-xss-sanitizer</h1>\n<p><a href=\"https://travis-ci.org/rpalcolea/grails-xss-sanitizer\"><img src=\"https://travis-ci.org/rpalcolea/grails-xss-sanitizer.svg?branch=master\" alt=\"Build Status\" /></a>\n<a href=\"https://bintray.com/rpalcolea/plugins/grails-xss-sanitizer/_latestVersion\"><img src=\"https://api.bintray.com/packages/rpalcolea/plugins/grails-xss-sanitizer/images/download.svg\" alt=\"Download\" /></a>\n<a href=\"http://slack-signup.grails.org\"><img src=\"http://slack-signup.grails.org/badge.svg\" alt=\"Slack Signup\" /></a></p>\n<p>Grails 3 plugin for sanitizing XSS from the user input. This is a port of the Grails <code>2.x</code> version by @tonyzampogna (Tony Zampogna) https://github.com/tonyzampogna/XssSanitizer</p>\n<p>This plugin uses OWASP ESAPI library to sanitize request parameters. This reduces the risk of dangerous XSS request parameters possibly being rendered on the client.</p>\n<h2>Installation</h2>\n<p>Add the following dependencies in <code>build.gradle</code></p>\n<pre><code>dependencies {\n...\n compile 'org.grails.plugins:grails-xss-sanitizer:1.1.+'\n...\n}\n</code></pre>\n<h2>Description</h2>\n<p>This plugin will add the automatic ability to strip / clean out unwanted XSS code in the browser. The plugin strips code that comes in via the request object. Also, any Servlets will use an extend HttpServletRequest so that request parameters used from that servlet will be stripped as well.</p>\n<p>Just adding this plugin to you project with the installation instructions above and adding the following Config will activate it:</p>\n<pre><code class=\"language-yaml\">\txssSanitizer:\n\t enabled: true\n</code></pre>\n<p>There is an XssSanitizerUtil class that can also be used to strip strings out.</p>\n<h2>Sponsors</h2>\n<p><a href=\"https://www.yourkit.com/.net/profiler/index.jsp\"><img src=\"https://www.yourkit.com/images/yklogo.png\" alt=\"Alt text\" title=\"YourKit\" /></a></p>\n<p>YourKit supports open source projects with its full-featured Java Profiler.\nYourKit, LLC is the creator of <a href=\"https://www.yourkit.com/java/profiler/index.jsp\">YourKit Java Profiler</a>\nand <a href=\"https://www.yourkit.com/.net/profiler/index.jsp\">YourKit .NET Profiler</a>,\ninnovative and intelligent tools for profiling Java and .NET applications.</p>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "payment", |
| "repo": "plugins", |
| "owner": "vahidhedayati", |
| "desc": "Grails payment plugin", |
| "labels": [ |
| "paypal", |
| "stripe", |
| "square", |
| "payment" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/vahidhedayati/grails-payment/issues", |
| "latestVersion": "1.0.2", |
| "updated": "2021-07-08T21:50:40.855Z", |
| "systemIds": [ |
| "io.github.vahidhedayati:payment" |
| ], |
| "vcsUrl": "https://github.com/vahidhedayati/grails-payment" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/io/github/vahidhedayati/payment/maven-metadata.xml", |
| "readme": "<div class=\"sect1\">\n<h2 id=\"_grails_payment_plugin\">Grails Payment Plugin</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Payments made easy, supports paypal, stripe and square\n.</p>\n</div>\n<div class=\"paragraph\">\n<p>More information about using Payment methods:</p>\n</div>\n<div class=\"ulist\">\n<ul>\n<li>\n<p><a href=\"https://github.com/vahidhedayati/grails-payment\">Grails Payment plugin</a></p>\n</li>\n</ul>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_installation\">Installation</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>These instructions are targeted towards Grails 4 installations. </p>\n</div>\n<div class=\"paragraph\">\n<p>Add a dependency to <code>build.gradle</code>:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre>...\ndependencies {\n ...\n compile 'io.github.vahidhedayati:payment:1.0.0'\n//You will only need this if you are looking to use square payment\n compile 'org.jetbrains.kotlin:kotlin-stdlib:1.3.70'\n ...\n}\n...</pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>The default install needs configuration updated but will very easily connect / allow payments</p>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_configuration\">Configuration</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>The plugin is configured through <code>grails-app/conf/application.groovy</code> refer to provided sampleApplication.groovy.</p>\n</div>\n</div>\n</div>\n" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "jasypt-encryption", |
| "repo": "plugins", |
| "owner": "ZenHarbinger", |
| "desc": "Integration with Jasypt, allows easy encryption of information including Hibernate/GORM integration", |
| "labels": [ |
| "encryption", |
| "jasypt" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/ZenHarbinger/grails-jasypt/issues", |
| "latestVersion": "4.0.4", |
| "updated": "2021-06-21T21:24:00.000Z", |
| "systemIds": [ |
| "org.tros:jasypt-encryption" |
| ], |
| "vcsUrl": "https://github.com/ZenHarbinger/grails-jasypt" |
| }, |
| "documentationUrl": null, |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/org/tros/jasypt-encryption/maven-metadata.xml" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "grails-jasper", |
| "repo": "plugins", |
| "owner": "daraii", |
| "desc": "This plugin is a port of the original JasperReports plugin later updated for Grails 3 to the newest JasperReports API, and based of Grails 5, that adds easy support for launching JasperReports reports from GSP pages.", |
| "labels": [ |
| "jasper", |
| "reports" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/daraii/grails-jasper/issues", |
| "latestVersion": "2.2.1", |
| "updated": "2022-09-02T02:49:13.275Z", |
| "systemIds": [ |
| "io.jellycat.plugins:jasper" |
| ], |
| "vcsUrl": "https://github.com/daraii/grails-jasper" |
| }, |
| "documentationUrl": "https://daraii.github.io/grails-jasper/", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/io/jellycat/plugins/jasper/maven-metadata.xml" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "moceanapi-grails-sms", |
| "repo": "plugins", |
| "owner": "moceanapi", |
| "desc": "This plugin allows helps you to incorporate SMS notification into your workflow.", |
| "labels": [ |
| "sms", |
| "moceanapi" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/MoceanAPI/mocean-grails-sms/issues", |
| "latestVersion": "1.0.1", |
| "updated": "2022-08-10T10:40:37.000Z", |
| "systemIds": [ |
| "com.github.moceanapi:mocean-grails-sms" |
| ], |
| "vcsUrl": "https://github.com/MoceanAPI/mocean-grails-sms" |
| }, |
| "documentationUrl": "https://github.com/MoceanAPI/mocean-grails-sms", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/com/github/moceanapi/mocean-grails-sms/maven-metadata.xml" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "Grailszk", |
| "repo": "grailszk", |
| "owner": "groovyzk", |
| "desc": "Provides integration with Java ZK framework.", |
| "labels": [ |
| "zk", |
| "zk-grails", |
| "framework" |
| ], |
| "licenses": [ |
| "LGPL-3.0" |
| ], |
| "issueTrackerUrl": "https://github.com/groovyzk/grailszk/issues", |
| "latestVersion": "4.2.3", |
| "updated": "2023-03-20T13:16:44.000Z", |
| "systemIds": [ |
| "io.github.zkgroovy:grailszk" |
| ], |
| "vcsUrl": "https://github.com/groovyzk/grailszk" |
| }, |
| "documentationUrl": "https://github.com/groovyzk/grailszk#readme", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/io/github/zkgroovy/grailszk/maven-metadata.xml" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "inertia", |
| "repo": "grails-inertia-plugin", |
| "owner": "matrei", |
| "desc": "Grails Adapter for Inertia.js", |
| "labels": [ |
| "inertia", |
| "spa" |
| ], |
| "licenses": [ |
| "Apache-2.0" |
| ], |
| "issueTrackerUrl": "https://github.com/matrei/grails-inertia-plugin/issues", |
| "latestVersion": "2.1.4", |
| "updated": "2025-12-30T09:23:20.000Z", |
| "systemIds": [ |
| "io.github.matrei:grails-inertia-plugin" |
| ], |
| "vcsUrl": "https://github.com/matrei/grails-inertia-plugin" |
| }, |
| "documentationUrl": "https://github.com/matrei/grails-inertia-plugin#readme", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/io/github/matrei/grails-inertia-plugin/maven-metadata.xml" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "Grails Liquid Plugin", |
| "repo": "grails-liquid-plugin", |
| "owner": "charlieamat", |
| "desc": "A Grails plugin for the Liquid markup language and template engine.", |
| "labels": [ |
| "liquid", |
| "markup" |
| ], |
| "licenses": [ |
| "MIT" |
| ], |
| "issueTrackerUrl": "https://github.com/charlieamat/grails-liquid-plugin/issues", |
| "latestVersion": "1.0.0", |
| "updated": "2023-07-28T18:45:11.632Z", |
| "systemIds": [ |
| "io.github.charlieamat:grails-liquid-plugin" |
| ], |
| "vcsUrl": "https://github.com/charlieamat/grails-liquid-plugin" |
| }, |
| "documentationUrl": "https://github.com/charlieamat/grails-liquid-plugin#readme", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/io/github/charlieamat/grails-liquid-plugin/maven-metadata.xml" |
| }, |
| { |
| "bintrayPackage": { |
| "name": "Grails Sanitizer", |
| "repo": "grails-sanitizer-plugin", |
| "owner": "carlosmtobon", |
| "desc": "A Grails Plugin for sanitizing markup using the OWASP AntiSamy library.", |
| "labels": [ |
| "sanitizer", |
| "antisamy" |
| ], |
| "licenses": [ |
| "MIT" |
| ], |
| "issueTrackerUrl": "https://github.com/carlosmtobon/grails-sanitizer-plugin/issues", |
| "latestVersion": "1.0.1", |
| "updated": "2023-07-28T18:46:48.776Z", |
| "systemIds": [ |
| "io.github.carlosmtobon:grails-sanitizer-plugin" |
| ], |
| "vcsUrl": "https://github.com/carlosmtobon/grails-sanitizer-plugin" |
| }, |
| "documentationUrl": "https://github.com/carlosmtobon/grails-sanitizer-plugin#readme", |
| "mavenMetadataUrl": "https://repo1.maven.org/maven2/io/github/carlosmtobon/grails-sanitizer-plugin/maven-metadata.xml" |
| } |
| ] |