Gateway
BOT
26-Jun-19 09:10 PM
[tlgrm] <Cypherthegreat> lol just playing some league with some old friends team fight tactics its a auto chess game
[dscrdeql] <MassimoStyle> heard of league but never wanted to play it, ima fortnite guy
[tlgrm] <Cypherthegreat> oh wow your one of them
[tlgrm] <Cypherthegreat> smh hahahaha
[tlgrm] <Cypherthegreat> i pref rts
[dscrdeql] <MassimoStyle> yeah lol
[dscrdeql] <MassimoStyle> i prefer br
[dscrdeql] <MassimoStyle> used to play cod and that type
[tlgrm] <Cypherthegreat> best br is tetris 99 xD
[dscrdeql] <MassimoStyle> might try rainbow but eh, some people tell me its good but not sure
(edited)
[dscrdeql] <MassimoStyle> im the fps and or br type
[tlgrm] <Cypherthegreat> yeah they can be cool haha i used to play pubg apex and csgo
[tlgrm] <Cypherthegreat> too much stress xD
[dscrdeql] <MassimoStyle> i got used to the stress, had so much when i was top 2 for apex and pub but got used to it, i used to play apex when it was popular but now no one plays it anymore, it was a decent game.
[dscrdeql] <Cypher> meh ill talk on here its eaiser xD
[dscrdeql] <MassimoStyle> is there a differnce just different account?
[dscrdeql] <Cypher> one is on telegram the yare linked to this discord
[dscrdeql] <Cypher> so if you type here
[dscrdeql] <MassimoStyle> ah k
[dscrdeql] <Cypher> it goes to there
[dscrdeql] <MassimoStyle> k have a good stream i will drop a follow gimme sec
[dscrdeql] <Cypher> cheers
[dscrdeql] <Cypher> the queue times on this new game mode is sooooooooo long
[dscrdeql] <Cypher> 15mins min
[dscrdeql] <MassimoStyle> just followed
[dscrdeql] <MassimoStyle> when i played competetive fortnite i sometimes had long que times, i had about 10 sometimes but mostly around 5
[dscrdeql] <Cypher> yeah im not that good
[dscrdeql] <Cypher> been streaming for fun but thinking about growing it a bit more
[dscrdeql] <Cypher> was supirsed when i got paid for it lol
[dscrdeql] <Cypher> just more money for cruypto xd
[dscrdeql] <MassimoStyle> youre a twitch partrnewr?
[dscrdeql] <MassimoStyle> oh nice
[dscrdeql] <Cypher> cheers
[dscrdeql] <Cypher> do you stream
[dscrdeql] <MassimoStyle> ummm once in a blue moon, used to play fn on a different platform and streamed once a week
[dscrdeql] <MassimoStyle> but i switched to pc
[dscrdeql] <MassimoStyle> and havent streamed yet
[dscrdeql] <MassimoStyle> dont feel like streaming just probably gonna upload to youtube
[dscrdeql] <Cypher> ahh fair yeah i tired the youtube
[dscrdeql] <MassimoStyle> and what happened
[dscrdeql] <Cypher> streaming i mean but they stopped youtube gaming
YouTube's gaming channel, featuring news, reviews, playthroughs, and more. This channel was generated automatically by YouTube's video discovery system.
[dscrdeql] <MassimoStyle> u mean that
[dscrdeql] <MassimoStyle> if so its still there
[dscrdeql] <Cypher> kinda its not good for streamers any more
(edited)
[dscrdeql] <MassimoStyle> ooh but you can still upload to it. i may start streaming again
[dscrdeql] <Cypher> true also they demonitside you
[dscrdeql] <MassimoStyle> not that often u can still curse little, but you have a fair point
[dscrdeql] <Cypher> and if you use music
[dscrdeql] <MassimoStyle> yeah copyright music ofc
[dscrdeql] <Cypher> used drm free before
[dscrdeql] <Cypher> and they stil lstriked me i was like rrly guys
[dscrdeql] <MassimoStyle> but if u use copyright music it doesnt rly matter
NoCopyrightSounds is a Record Label dedicated to giving a platform to the next generation of Artists in Electronic Music, representing genres from House to D...
[dscrdeql] <MassimoStyle> u wont get copyrighterd


We've got you covered*
*nomON and ordr.in do not guarantee that the meal you receive will match your allergy preferences. The nomON algorithm selects and avoids items according to the ingredients that each restaurant lists on its menu. Thus, if a restaurant does not disclose the full ingredient list, there is no guarantee that your order will not include things you specified. We suggest only selecting certain categories of restaurants that will serve your needs, thoroughly inspecting foods when received, or refraining from ordering if your allergies are severe.
Are you sure you want to delete this


 From the initial ideation to building the prototype and MVP to customer discovery and marketing and fundraising, we know what it takes to help launch a company as well as grow and scale it. Entrepreneurs ourselves, we have also advised over 250 startups and entrepreneurs looking for bespoke business solutions for their startups.
We offer unique entrepreneurial expertise that integrates real, practical experience with essential financial, legal and academic concepts. We can help you analyze your business model, gain deep insights about your industry, develop revenue streams, build financials and forecasting models, as well as tap into our huge network of experts, analysts, investors and founders to help buoy your venture and give it the added boost that will ensure its success.
Add a description of the image here
Add a description of the image here
Add a description of the image here
Add a description of the image here
Add a description of the image here
Add a description of the image here
Add a description of the image here
Add a description of the image here
Add a description of the image here


Demo 1: Accordion Menu
-
Auto Open:
Click each link in the accordion menu. After the page is reloaded, the clicked link is automatically highlighted because its href is matching the current page URL.
- Unlimited sub-menu levels
- Plain JavaScript. jQuery is not required.
- For details please visit Accordion Menu


Bruce change#2
Bo's change #3
Bruce change#3
Bo's change #4
Bruce change#4
Bo's change #5
Bruce Last Change


Adds useful methods to Helma's built-in HopObject prototype.
To use this optional module, its repository needs to be added to the application, for example by calling app.addRepository('modules/core/HopObject.js')
To use this optional module, its repository needs to be added to the application, for example by calling app.addRepository('modules/core/HopObject.js')
Methods
Iterates over each child node of the HopObject.
parameters
| Function | callback |
The callback function to be
called for each child node. On every call the first
argument of this function is set to the current value
of the counter variable i .
|
macro returns the id of a HopObject
macro returns the url for any hopobject
parameters
| param | ||
| action |
macro rendering a skin or displaying
its source (param.as == "source")
parameters
| param | ||
| name |
this macro renders a text depending on
the value of a given property
parameters
| param |
generic macro that loops over the childobjects
and renders a specified skin for each of them
parameters
| Object | providing the following properties: skin: the skin to render for each item (required) collection: the collection containing the items limit: max. number of items per page (req.data.page determines the page number) sort: property name to use for sorting order: sort order (either "asc" or "desc") itemPrefix: text to prepend to each items skin render itemSuffix: text to append to each items skin render |
Render the number of child nodes of the HopObject.
Three cases are distinguished which can be customized
by setting param.verbose to "true" and defining the
corresponding field of the
param
argument:
- param.none - not a single child node
- param.one - exactly one child node
- param.many - more than one child node
parameters
| Object | param | The default macro parameter |
| String | name | The default name for a child node |


Please login to vewi the content. If you are not registered, you... Please login to vewi the content. If you are not registered, you... Please login to vewi the content. If you are not registered, you... Please login to vewi the content. If you are not registered, you... Please login to vewi the content. If you are not registered, you...


SuperUsers can clear the DNN cache to purge all cached files from all sites within this DNN application.


Data processing is a series of operations that use information to produce a result. Common data processing operations include validation, sorting, classification, calculation, interpretation, organization and transformation of data. The following are illustrative examples of data processing.
1. Electronics: A digital camera converts raw data from a sensor into a photo file by applying a series of algorithms based on a color model.
2. Decision Support: A stock trading application converts data representing millions of stock trades into a graph that can be quickly understood by a trader.
3. Integration: An integration process moves data from one system to another. This involves a process of transferring and transforming the format of the data.
4. Automation: A telecom billing system calculates the monthly charges for customers based on factors such as the customer's service plan and their data usage for the month. The charges are summarized as a document that is mailed to customers. The entire process is automated with a billing team monitoring it.
5. Transactions: A banking website accepts a money transfer request from a user by validating it and formatting it to be processed by a backend system.
6. Media: A website accepts user submitted media such as videos and converts it to a standard format for display to users.
7. Communication: A messaging tool encrypts a message before sending it using an encryption algorithm and a public key.
8. Artificial Intelligence: A self-driving car uses real time data from sensors to detect if there are pedestrians ahead. This is done by applying models that were developed through a process of machine learning whereby an artificial intelligence examined millions of hours of sensor data to practice detecting pedestrians.


#include <cmsis-plus/rtos/os.h>
#include <cmsis-plus/posix-io/types.h>
#include <cmsis-plus/posix-io/file-descriptors-manager.h>
#include <cmsis-plus/posix-io/io.h>
#include <cmsis-plus/posix-io/char-device.h>
#include <cmsis-plus/posix-io/tty.h>
#include <cmsis-plus/posix-io/file.h>
#include <cmsis-plus/posix-io/file-system.h>
#include <cmsis-plus/posix-io/directory.h>
#include <cmsis-plus/posix-io/socket.h>
#include <cmsis-plus/posix-io/net-stack.h>
#include <cmsis-plus/posix/sys/uio.h>
#include <cmsis-plus/diag/trace.h>
#include <cstdarg>
#include <cerrno>
Go to the source code of this file.
Functions | |
| int | __posix_accept (int socket, sockaddr *address, socklen_t *address_len) |
| int | __posix_bind (int socket, const sockaddr *address, socklen_t address_len) |
| int | __posix_chdir (const char *path) |
| int | __posix_chmod (const char *path, mode_t mode) |
| int | __posix_chown (const char *path, uid_t owner, gid_t group) |
| clock_t | __posix_clock (void) |
| int | __posix_close (int fildes) |
| int | __posix_closedir (DIR *dirp) |
| int | __posix_connect (int socket, const sockaddr *address, socklen_t address_len) |
| int | __posix_execve (const char *path, char *const argv[], char *const envp[]) |
| int | __posix_fcntl (int fildes, int cmd,...) |
| pid_t | __posix_fork (void) |
| int | __posix_fstat (int fildes, struct stat *buf) |
| int | __posix_fstatvfs (int fildes, struct statvfs *buf) |
| int | __posix_fsync (int fildes) |
| int | __posix_ftruncate (int fildes, off_t length) |
| char * | __posix_getcwd (char *buf, size_t size) |
| int | __posix_getpeername (int socket, sockaddr *address, socklen_t *address_len) |
| pid_t | __posix_getpid (void) |
| int | __posix_getsockname (int socket, sockaddr *address, socklen_t *address_len) |
| int | __posix_getsockopt (int socket, int level, int option_name, void *option_value, socklen_t *option_len) |
| int | __posix_gettimeofday (timeval *ptimeval, void *ptimezone) |
| int | __posix_ioctl (int fildes, int request,...) |
| int | __posix_isatty (int fildes) |
| Test for a terminal device. | |
| int | __posix_kill (pid_t pid, int sig) |
| int | __posix_link (const char *existing, const char *_new) |
| int | __posix_listen (int socket, int backlog) |
| off_t | __posix_lseek (int fildes, off_t offset, int whence) |
| int | __posix_mkdir (const char *path, mode_t mode) |
| int | __posix_open (const char *path, int oflag,...) |
| Open file relative to directory file descriptor. | |
| DIR * | __posix_opendir (const char *dirpath) |
| int | __posix_raise (int sig) |
| ssize_t | __posix_read (int fildes, void *buf, size_t nbyte) |
| dirent * | __posix_readdir (DIR *dirp) |
| int | __posix_readdir_r (DIR *dirp, dirent *entry, dirent **result) |
| ssize_t | __posix_readlink (const char *path, char *buf, size_t bufsize) |
| ssize_t | __posix_recv (int socket, void *buffer, size_t length, int flags) |
| ssize_t | __posix_recvfrom (int socket, void *buffer, size_t length, int flags, sockaddr *address, socklen_t *address_len) |
| ssize_t | __posix_recvmsg (int socket, msghdr *message, int flags) |
| int | __posix_rename (const char *existing, const char *_new) |
| void | __posix_rewinddir (DIR *dirp) |
| int | __posix_rmdir (const char *path) |
| int | __posix_select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, timeval *timeout) |
| ssize_t | __posix_send (int socket, const void *buffer, size_t length, int flags) |
| ssize_t | __posix_sendmsg (int socket, const msghdr *message, int flags) |
| ssize_t | __posix_sendto (int socket, const void *message, size_t length, int flags, const sockaddr *dest_addr, socklen_t dest_len) |
| int | __posix_setsockopt (int socket, int level, int option_name, const void *option_value, socklen_t option_len) |
| int | __posix_shutdown (int socket, int how) |
| int | __posix_sockatmark (int socket) |
| int | __posix_socket (int domain, int type, int protocol) |
| int | __posix_socketpair (int domain, int type, int protocol, int socket_vector[2]) |
| int | __posix_stat (const char *path, struct stat *buf) |
| int | __posix_statvfs (const char *path, struct statvfs *buf) |
| int | __posix_symlink (const char *existing, const char *_new) |
| void | __posix_sync (void) |
| int | __posix_system (const char *command) |
| int | __posix_tcdrain (int fildes) |
| int | __posix_tcflush (int fildes, int queue_selector) |
| int | __posix_tcgetattr (int fildes, termios *termios_p) |
| int | __posix_tcsendbreak (int fildes, int duration) |
| int | __posix_tcsetattr (int fildes, int optional_actions, const termios *termios_p) |
| clock_t | __posix_times (tms *buf) |
| int | __posix_truncate (const char *path, off_t length) |
| int | __posix_unlink (const char *path) |
| int | __posix_utime (const char *path, const utimbuf *times) |
| pid_t | __posix_wait (int *stat_loc) |
| ssize_t | __posix_write (int fildes, const void *buf, size_t nbyte) |
| ssize_t | __posix_writev (int fildes, const iovec *iov, int iovcnt) |
| void | initialise_monitor_handles (void) |
Definition at line 589 of file c-syscalls-posix.cpp.
Definition at line 602 of file c-syscalls-posix.cpp.
| int __posix_chdir | ( | const char * | path | ) |
Definition at line 850 of file c-syscalls-posix.cpp.
| int __posix_chmod | ( | const char * | path, |
| mode_t | mode | ||
| ) |
Definition at line 427 of file c-syscalls-posix.cpp.
| int __posix_chown | ( | const char * | path, |
| uid_t | owner, | ||
| gid_t | group | ||
| ) |
Definition at line 950 of file c-syscalls-posix.cpp.
| clock_t __posix_clock | ( | void | ) |
Definition at line 867 of file c-syscalls-posix.cpp.
| int __posix_close | ( | int | fildes | ) |
Definition at line 104 of file c-syscalls-posix.cpp.
| int __posix_closedir | ( | DIR * | dirp | ) |
Definition at line 538 of file c-syscalls-posix.cpp.
Definition at line 614 of file c-syscalls-posix.cpp.
| int __posix_execve | ( | const char * | path, |
| char *const | argv[], | ||
| char *const | envp[] | ||
| ) |
Definition at line 874 of file c-syscalls-posix.cpp.
| int __posix_fcntl | ( | int | fildes, |
| int | cmd, | ||
| ... | |||
| ) |
Definition at line 334 of file c-syscalls-posix.cpp.
| pid_t __posix_fork | ( | void | ) |
Definition at line 881 of file c-syscalls-posix.cpp.
| int __posix_fstat | ( | int | fildes, |
| struct stat * | buf | ||
| ) |
Definition at line 352 of file c-syscalls-posix.cpp.
| int __posix_fstatvfs | ( | int | fildes, |
| struct statvfs * | buf | ||
| ) |
Definition at line 364 of file c-syscalls-posix.cpp.
| int __posix_fsync | ( | int | fildes | ) |
Definition at line 404 of file c-syscalls-posix.cpp.
| int __posix_ftruncate | ( | int | fildes, |
| off_t | length | ||
| ) |
Definition at line 384 of file c-syscalls-posix.cpp.
| char * __posix_getcwd | ( | char * | buf, |
| size_t | size | ||
| ) |
Definition at line 857 of file c-syscalls-posix.cpp.
Definition at line 627 of file c-syscalls-posix.cpp.
| pid_t __posix_getpid | ( | void | ) |
Definition at line 897 of file c-syscalls-posix.cpp.
Definition at line 640 of file c-syscalls-posix.cpp.
| int __posix_getsockopt | ( | int | socket, |
| int | level, | ||
| int | option_name, | ||
| void * | option_value, | ||
| socklen_t * | option_len | ||
| ) |
Definition at line 653 of file c-syscalls-posix.cpp.
| int __posix_gettimeofday | ( | timeval * | ptimeval, |
| void * | ptimezone | ||
| ) |
Definition at line 826 of file c-syscalls-posix.cpp.
| int __posix_ioctl | ( | int | fildes, |
| int | request, | ||
| ... | |||
| ) |
Definition at line 166 of file c-syscalls-posix.cpp.
| int __posix_isatty | ( | int | fildes | ) |
Test for a terminal device.
This function shall test whether fildes, an open file descriptor, is associated with a terminal device.
Definition at line 216 of file c-syscalls-posix.cpp.
| int __posix_kill | ( | pid_t | pid, |
| int | sig | ||
| ) |
Definition at line 913 of file c-syscalls-posix.cpp.
| int __posix_link | ( | const char * | existing, |
| const char * | _new | ||
| ) |
Definition at line 957 of file c-syscalls-posix.cpp.
| int __posix_listen | ( | int | socket, |
| int | backlog | ||
| ) |
Definition at line 666 of file c-syscalls-posix.cpp.
| off_t __posix_lseek | ( | int | fildes, |
| off_t | offset, | ||
| int | whence | ||
| ) |
Definition at line 191 of file c-syscalls-posix.cpp.
| int __posix_mkdir | ( | const char * | path, |
| mode_t | mode | ||
| ) |
Definition at line 472 of file c-syscalls-posix.cpp.
| int __posix_open | ( | const char * | path, |
| int | oflag, | ||
| ... | |||
| ) |
Open file relative to directory file descriptor.
The open()
function shall establish the connection between a file and a file descriptor. It shall create an open file description that refers to a file and a file descriptor that refers to that open file description. The file descriptor is used by other I/O functions to refer to that file. The path argument points to a pathname naming the file.
Definition at line 86 of file c-syscalls-posix.cpp.
| DIR * __posix_opendir | ( | const char * | dirpath | ) |
Definition at line 493 of file c-syscalls-posix.cpp.
| int __posix_raise | ( | int | sig | ) |
Definition at line 920 of file c-syscalls-posix.cpp.
| ssize_t __posix_read | ( | int | fildes, |
| void * | buf, | ||
| size_t | nbyte | ||
| ) |
Definition at line 120 of file c-syscalls-posix.cpp.
Definition at line 499 of file c-syscalls-posix.cpp.
Definition at line 812 of file c-syscalls-posix.cpp.
| ssize_t __posix_readlink | ( | const char * | path, |
| char * | buf, | ||
| size_t | bufsize | ||
| ) |
Definition at line 971 of file c-syscalls-posix.cpp.
| ssize_t __posix_recv | ( | int | socket, |
| void * | buffer, | ||
| size_t | length, | ||
| int | flags | ||
| ) |
Definition at line 678 of file c-syscalls-posix.cpp.
| ssize_t __posix_recvfrom | ( | int | socket, |
| void * | buffer, | ||
| size_t | length, | ||
| int | flags, | ||
| sockaddr * | address, | ||
| socklen_t * | address_len | ||
| ) |
Definition at line 690 of file c-syscalls-posix.cpp.
| ssize_t __posix_recvmsg | ( | int | socket, |
| msghdr * | message, | ||
| int | flags | ||
| ) |
Definition at line 703 of file c-syscalls-posix.cpp.
| int __posix_rename | ( | const char * | existing, |
| const char * | _new | ||
| ) |
Definition at line 445 of file c-syscalls-posix.cpp.
| void __posix_rewinddir | ( | DIR * | dirp | ) |
Definition at line 523 of file c-syscalls-posix.cpp.
| int __posix_rmdir | ( | const char * | path | ) |
Definition at line 478 of file c-syscalls-posix.cpp.
| int __posix_select | ( | int | nfds, |
| fd_set * | readfds, | ||
| fd_set * | writefds, | ||
| fd_set * | errorfds, | ||
| timeval * | timeout | ||
| ) |
Definition at line 835 of file c-syscalls-posix.cpp.
| ssize_t __posix_send | ( | int | socket, |
| const void * | buffer, | ||
| size_t | length, | ||
| int | flags | ||
| ) |
Definition at line 715 of file c-syscalls-posix.cpp.
| ssize_t __posix_sendmsg | ( | int | socket, |
| const msghdr * | message, | ||
| int | flags | ||
| ) |
Definition at line 727 of file c-syscalls-posix.cpp.
| ssize_t __posix_sendto | ( | int | socket, |
| const void * | message, | ||
| size_t | length, | ||
| int | flags, | ||
| const sockaddr * | dest_addr, | ||
| socklen_t | dest_len | ||
| ) |
Definition at line 739 of file c-syscalls-posix.cpp.
| int __posix_setsockopt | ( | int | socket, |
| int | level, | ||
| int | option_name, | ||
| const void * | option_value, | ||
| socklen_t | option_len | ||
| ) |
Definition at line 752 of file c-syscalls-posix.cpp.
| int __posix_shutdown | ( | int | socket, |
| int | how | ||
| ) |
Definition at line 765 of file c-syscalls-posix.cpp.
| int __posix_sockatmark | ( | int | socket | ) |
Definition at line 777 of file c-syscalls-posix.cpp.
| int __posix_socket | ( | int | domain, |
| int | type, | ||
| int | protocol | ||
| ) |
Definition at line 568 of file c-syscalls-posix.cpp.
| int __posix_socketpair | ( | int | domain, |
| int | type, | ||
| int | protocol, | ||
| int | socket_vector[2] | ||
| ) |
Definition at line 819 of file c-syscalls-posix.cpp.
| int __posix_stat | ( | const char * | path, |
| struct stat * | buf | ||
| ) |
Definition at line 433 of file c-syscalls-posix.cpp.
| int __posix_statvfs | ( | const char * | path, |
| struct statvfs * | buf | ||
| ) |
Definition at line 463 of file c-syscalls-posix.cpp.
| int __posix_symlink | ( | const char * | existing, |
| const char * | _new | ||
| ) |
Definition at line 964 of file c-syscalls-posix.cpp.
| void __posix_sync | ( | void | ) |
Definition at line 484 of file c-syscalls-posix.cpp.
| int __posix_system | ( | const char * | command | ) |
Definition at line 927 of file c-syscalls-posix.cpp.
| int __posix_tcdrain | ( | int | fildes | ) |
Definition at line 232 of file c-syscalls-posix.cpp.
| int __posix_tcflush | ( | int | fildes, |
| int | queue_selector | ||
| ) |
Definition at line 294 of file c-syscalls-posix.cpp.
| int __posix_tcgetattr | ( | int | fildes, |
| termios * | termios_p | ||
| ) |
Definition at line 252 of file c-syscalls-posix.cpp.
| int __posix_tcsendbreak | ( | int | fildes, |
| int | duration | ||
| ) |
Definition at line 314 of file c-syscalls-posix.cpp.
| int __posix_tcsetattr | ( | int | fildes, |
| int | optional_actions, | ||
| const termios * | termios_p | ||
| ) |
Definition at line 272 of file c-syscalls-posix.cpp.
| clock_t __posix_times | ( | tms * | buf | ) |
Definition at line 843 of file c-syscalls-posix.cpp.
| int __posix_truncate | ( | const char * | path, |
| off_t | length | ||
| ) |
Definition at line 439 of file c-syscalls-posix.cpp.
| int __posix_unlink | ( | const char * | path | ) |
Definition at line 451 of file c-syscalls-posix.cpp.
| int __posix_utime | ( | const char * | path, |
| const utimbuf * | times | ||
| ) |
Definition at line 457 of file c-syscalls-posix.cpp.
| pid_t __posix_wait | ( | int * | stat_loc | ) |
Definition at line 934 of file c-syscalls-posix.cpp.
| ssize_t __posix_write | ( | int | fildes, |
| const void * | buf, | ||
| size_t | nbyte | ||
| ) |
Definition at line 137 of file c-syscalls-posix.cpp.
| ssize_t __posix_writev | ( | int | fildes, |
| const iovec * | iov, | ||
| int | iovcnt | ||
| ) |
Definition at line 154 of file c-syscalls-posix.cpp.
| void initialise_monitor_handles | ( | void | ) |
Definition at line 983 of file c-syscalls-posix.cpp.


MONDAY OF THE SECOND WEEK
Entrance Antiphon
Hear the word of the LORD, O nations; declare it to the distant lands:
Behold, our Saviour will come; you need no longer fear.
Collect
with purity unblemished, we,
your servants may come, as we desire, to celebrate the great
mystery of the Incarnation of your Only-Begotten Son.
Who lives and reigns with you. . .
FIRST READING
Isaiah 35:1-10 A reading from the Book of Isaiah The wilderness and the dry land shall be glad, the
desert shall rejoice and blossom; like the crocus it shall blossom abundantly,
and rejoice with joy and singing. The glory of The word of the Lord
RESPONSORIAL PSALM
Psalm
85:9ab and 10.11-12.13-14(R.see Isaiah 35:4f) R. Our God will come and save us! I will hear what the LORD God speaks; he speaks of
peace for his people and his faithful. His salvation is near for those who fear
him, and his glory will dwell in our land.
R. Our God will come and save us! Merciful love and faithfulness have met; justice
and peace have kissed. Faithfulness shall spring from the earth,
and justice look down from heaven. R. Our God will come and save us! Also the LORD will bestow his bounty, and our earth
shall yield its increase. Justice will march before him, and guide his steps on
the way. R. Our God will come and save us! ALLELUIA Alleluia. Behold, the King is coming, the Lord of the earth, and he shall remove
the yoke of our captivity. Alleluia. GOSPEL
Luke 5:17-26 A reading from the holy Gospel according to Luke A
reading from the holy Gospel according to Luke 5:17-26 On one of those days, as Jesus was teaching, there
were Pharisees and teachers of the law sitting by, who had come from every The Gospel of the Lord
Prayer over the Offerings
Accept, we pray, O Lord, these offerings we make, g
athered from among your gifts to us, and may what you grant us to celebrate
devoutly here below, gain for us the prize of eternal redemption.
Through Christ our Lord.
Communion Antiphon
Come, O Lord, visit us in peace, that we may rejoice before you with a blameless heart.
Prayer after Communion May these mysteries, O Lord, in which we have participated,
profit us, we pray, for even now, as we walk amid passing things, you teach us by them
to love the things of heaven and hold fast to what endures.
Through Christ our Lord.


open class TransitionSetBuilder<T : TransitionSet> : TransitionBuilder<TransitionSet>
TransitionBuilder implementation for constructing TransitionSet instances.
See Also
TransitionSetBuilder(transitionSet: T)
TransitionBuilder implementation for constructing TransitionSet instances. |
var duration: Long
Sets the duration for this transition |
|
var interpolator: TimeInterpolator?
TimeInterpolator for this transition. |
|
var pathMotion: PathMotion?
PathMotion for this transition. |
|
var startDelay: Long
Set a start delay in milliseconds to this transition |
|
val transition: T |
|
var transitionPropagation: TransitionPropagation?
TransitionPropagation for this transition. Propagations are use to control start delays for transition. For example, CircularPropagation has increased start delays from the focal point and Explode defaults to using that. |
fun auto(autoBuilder: AutoTransitionBuilder.() -> Unit = {}): Unit
Adds an AutoTransition to this transition |
|
fun changeClipBounds(changeClipBoundsBuilder: ChangeClipBoundsBuilder.() -> Unit = {}): Unit
Adds a ChangeClipBounds transition to this transition that animates changes to ChangeClipBounds |
|
fun changeColor(changeColorBuilder: ChangeColorBuilder.() -> Unit = {}): Unit
Adds ChangeColor transition to this transition. |
|
fun changeImage(changeImageBuilder: ChangeImageBuilder.() -> Unit = {}): Unit
Adds a ChangeImageTransform transition to this transtion that animates changes to ImageView's image matrix and ImageView.ScaleType |
|
fun changeScroll(changeScrollBuilder: ChangeScrollBuilder.() -> Unit = {}): Unit
Adds ChangeScroll transition to this transition that animates changes to View's scroll properties |
|
fun changeText(changeTextBuilder: ChangeTextBuilder.() -> Unit = {}): Unit
Adds ChangeText transition to this transition. |
|
fun <T : Transition> customTransition(transitionBuilder: TransitionBuilder<T>.() -> Unit = {}): Unit
Instantiates Transition of type T and adds to this transition. The T type must have a public no arg constructor for the instantiation to work. fun <T : Transition> customTransition(transition: T, transitionBuilder: TransitionBuilder<T>.() -> Unit = {}): Unit
Alternative to customTransition that takes an already instantiated transition instance and allows additional configuration via the transitionBuilder block. |
|
fun explode(explodeBuilder: ExplodeBuilder.() -> Unit = {}): Unit
Adds an Explode transition to this transition that does explode transition when View's visibility changes as described by Visibility |
|
fun fade(fadeMode: Int = Fade.IN
or Fade.OUT, fadeBuilder: FadeBuilder.() -> Unit = {}): Unit
Adds a Fade transition to this transition. Fade triggers on visibility changes. |
|
fun fadeIn(fadeBuilder: FadeBuilder.() -> Unit = {}): Unit
Adds a Fade transition that triggers only when the views appear as per condition described by Visibility.isVisible |
|
fun fadeOut(fadeBuilder: FadeBuilder.() -> Unit = {}): Unit
Adds a Fade transition that triggers only when the views disappear as per condition described by Visibility.isVisible |
|
operator fun get(index: Int): Transition
Returns the Transition at index |
|
fun moveResize(changeBoundsBuilder: ChangeBoundsBuilder.() -> Unit = {}): Unit
Adds a ChangeBounds transition to this transition that animates when Views move or change their bounds. |
|
fun scaleRotate(scaleRotateBuilder: ScaleRotateBuilder.() -> Unit = {}): Unit
Adds a ChangeTransform to this transition. This transition animates View's scale or rotate properties change. |
|
fun sequentially(): Unit
Runs all Transitions contained in this TransitionSet sequentially |
|
fun slide(slideBuilder: SlideBuilder.() -> Unit = {}): Unit
Adds a Slide transition to this transition. Slide triggers on visibility changes. |
|
fun together(): Unit
Runs all Transitions contained in this TransitionSet together |
|
fun transitionSet(setBuilder: DefaultTransitionSetBuilder.() -> Unit = {}): Unit
Create another TransitionSet and add it to this transition set. The block setBuilder can contain code to configure the created TransitionSet |
|
operator fun Transition.unaryMinus(): Unit
Remove a transition from this transition set. |
|
operator fun Transition.unaryPlus(): Unit
Add a transition to this transition set. |
fun add(vararg views: View): Unit
Adds all views as targets to this transition. fun add(vararg ids: Int): Unit
Adds all view ids as targets to this transition. fun add(vararg transitionTargetNames: String): Unit
Adds all transitionTargetNames as targets to this transition |
|
fun Transition.addListener(onEnd: (transition: Transition) -> Unit = null, onStart: (transition: Transition) -> Unit = null, onCancel: (transition: Transition) -> Unit = null, onResume: (transition: Transition) -> Unit = null, onPause: (transition: Transition) -> Unit = null): Unit
Add actions at different stages of Transition. Repeated blocks does not override previously added block but instead run one after another. |
|
fun customProperties(action: Transition.() -> Unit): Unit
Builder to set custom properties to be built Transition object. In the action block, transition is received as the lambda receiver and it is possible to directly set any custom properties on the transition. |
|
fun ease(easeBuilder: Easing.() -> Interpolator): Unit
Builder to add one of the inbuilt easing as per Material Design guidelines. Calling this overwrites any previously set transitions. |
|
fun exclude(vararg views: View): Unit
Exclude givens views from this transition. The transition will not affect these views during execution. fun <Type : View> exclude(): Unit
Exclude givens View from this transition. The transition will not affect views of Type during execution. fun exclude(vararg ids: Int): Unit
Exclude givens View ids from this transition. The transition will not affect views with this ids |
|
fun excludeChildren(vararg views: View): Unit
Exclude children of given views from participating in this transition. fun <Type : View> excludeChildren(): Unit
Exclude children of given Type from participating in this transition. fun excludeChildren(vararg ids: Int): Unit
Exclude children of given view ids from participating in this transition. |
|
fun onCancel(onCancel: (transition: Transition) -> Unit): Unit
Executes onCancel during Transition.TransitionListener.onTransitionCancel |
|
fun onEnd(onEnd: (transition: Transition) -> Unit): Unit
Executes onEnd block after transition completes. |
|
fun onPause(onPause: (transition: Transition) -> Unit): Unit
Executes onPause during Transition.TransitionListener.onTransitionPause |
|
fun onResume(onResume: (transition: Transition) -> Unit): Unit
Executes onResume during Transition.TransitionListener.onTransitionResume |
|
fun onStart(onStart: (transition: Transition) -> Unit): Unit
Executes onStart during Transition.TransitionListener.onTransitionStart |
|
fun remove(vararg views: View): Unit
Remove all views as targets from this transition. fun remove(vararg ids: Int): Unit
Remove all view ids as targets from this transition. |
|
operator fun String.unaryMinus(): Unit
Remove a target identified by operator fun <Type> Type.unaryMinus(): Unit
Remove targets of type Type from this transition operator fun View.unaryMinus(): Unit
Remove a target View from this transition. |
|
operator fun String.unaryPlus(): Unit
Add a target identified by operator fun <Type> Type.unaryPlus(): Unit
Add targets of type Type to this transition operator fun View.unaryPlus(): Unit
Add a target View to this transition. |
class AutoTransitionBuilder : TransitionSetBuilder<TransitionSet>
Builder for building a TransitionSet with AutoTransition already added. |
|
class DefaultTransitionSetBuilder : TransitionSetBuilder<TransitionSet>
Base builder for building a TransitionSet |


Learn UX Club
I'm writing this at 3am and idk what to put for a description.
Layout
Quick Start
Design Principles
Direct the Eye
Leading the Eye to Areas of Interest and Beyond
How You Make a Grid (Free PDF)
Visual Hierarchy
Inspiration
Layout Inspiration: Behance Collection
Aisle One
Designspiration: Layout
Color
Quick Start
Basic Color THeory
Color and UX
How to Create Emotion with Color in UX Design
Web Design Color Theory
Classes
Skillshare Top Color Theory Classes
MIT's Open Class: Art of Color
Interaction of Color (Book)
Color Theory Tutorial
Inspiration
Flat UI Color Picker
Plenty of Color
Color Hunt
BOOOOOOOM!
LOL Colors
COLOURlovers
Typography
Quick Start
Typography in 10 Minutes
Thinking with Type
Type Crimes (Glaring No-Nos)
Key Rules of Type
Practical Typography
Type Rules for UX
Classes
Jessica Hische's Resource Section
Ellen Lupton's (Free!) Intro to Typography
Get Fancy with Knowledge
Typography Terms / Anatomy of Type
Anatomy of a Typeface
Advanced Anatomy of Type
History of Typography
Type Lecture
Inspiration
Typophile
Typetoy
I Love Typography
Type Everything
The Inspiration Grid
Designspiration
UI / UX
Quick Start
UXPin: Free Resources
UX Design: Tools, Methods, Links, Events
The Difference Between Usability and User Experience
The Difference Between UX and UI Design
Requirements Gathering
Wireframing, Prototyping, and Mockuping
Complete Beginner's Guide to Information Architecture
52 Weeks of UX
User Experience on Medium
UX Design Methods and Deliverables
UX Myths
Get Fancy with Knowledge
Neuro Design Principles
How to Use Animation to Improve UX
Everything You Need to Know About UX Sketching
Should UX Designers Join the Dark Side?
Visual Dividers in Mobile UI
Using Icons in your Apps
What Designers Can Learn From Video Games (ha ha)
Apply Design Thinking From Scratch
Good Call to Action Buttons
The Mighty Ellipsis
A Usable Guide to Cognitive Dimensions
Five Myths About Usability Testing
Reducing Cognitive Overload for a Better UX
The UX Design Success Ladder
7 Rules for Creating Gorgeous UI
Classes
Design the Airbnb Website
Designs for the Human Mind
Nielson Norman Group: UX Research
Inspiration
Dribbble
Little Big Details
Pttrns
UI OH MY
UI Parade
Really Good Emails
PatternTap
Mobile Patterns
Patternry
Usability Post
Boxes and Arrows
iA
UX Pin: Pattern Library
Felt Presence
UX A Day
FoolProof: Thinking
Accessibility
Quick Start
Improving UX for Colorblind Users
12 Typography Guidelines for Usability
Dos and Don'ts on Design Accessibility
Your Body Text is Too Small
Tools
Cheapest Tools for Prototyping
Mural
Balsamiq Mockups ($79)
Adobe Kuler
Color Safe
Grid Designer
Wireframe.cc
Lookback
Coggle.it
Crazy Egg: Interaction Heatmap
List: UX Tools
Optimizely


Tickets
All standard tickets get you into the gates of the faire anytime from 10am to 8pm, on both days! You get access to all the entertainment, fun, education, and vendors that we bring each year.
This includes:
- Daily jousting competitions
- Armored Combat League fights
- Magic shows
- The Masters of Dueling
- Birds of prey
- Horse breed presentation
- Live renaissance and medieval music performances all over the park from Stary Olsa, The Harp Twins, and many others
- The artisan village full of historical education
- The Society for Creative Anachronism demonstration area
- The House of Tudor camp
- Queen Elizabeth's music tent
- The Vikings of Utah camp
- Renaissance themed vendors of all types
- Food vendors
- ...AND SO MUCH MORE!
Queen Elizabeth's Joust and Feast tickets are for an enhanced experience that is above and beyond the standard ticket. Scroll down to see information and get more details.
Guests who are in costume and purchase general admission tickets at the gate receive $2 off a single-admission ticket!
Costume discount does not combine with the flyer you may have received.
We offer a military discount for veterans and active duty. To receive a discount, show your ID at the gate on the day of the event. The service member must be present and show their ID at the time of purchase.
Veterans
50% off for the service member
Tickets that qualify for this discount:
Adult, Student, or Senior
Active Duty
50% off for the service member, spouse, and dependents.
Tickets that qualify for this discount:
Adult, Student, Senior, and / or Family Pass
The military discount is not available online as there is no way to submit an ID there yet. We apologize that we cannot apply the military discount to the educational excursions or the Queen Elizabeth's Joust and Feast.
Children age 5 and under are free and do not require a ticket.


CSS uses selectors to reference HTML tags (i.e. p.className). jQuery has copied CSS and uses the same CSS selectors to reference HTML tags.
Keep the appearance the same for the user. We will convert the CSS to jQuery. Both CSS selectors and CSS rules work in jQuery with different syntax.
Todo inclass: Create CSS rules so each bullet is styled.
Notice there is no bold HTML element in this example.
Sample jQuery syntax: $(selector).method('CSS rule', 'CSS value');
$('.red').css('color', 'red');


Ace of wands : Initiative, passion, risk taking
2 of wands : Control
Control
3 of wands : Virtue
Virtue
4 of wands : Completion
Completion
5 of wands : Strife
Strife
6 of wands : Victory
Victory
7 of wands : Valour
Bravery
8 of wands : Swiftness
Swiftness
9 of wands : Strength
Strength
10 of wands : Oppression
Oppression
Prince of wands : Large enthusiasm, impatience, thirst for adventure
Princess of wands : Passion, sexual charisma, enthusiasm
Knight of wands : Strength of Will, individual potential, a dynamo
Queen of wands : Female dominance, strong will power, magnetic attraction
Ace of cups : Longing for union, merging, devotion
2 of cups : Love
Love
3 of cups : Abundance
Abundance
4 of cups : Luxury
Luxury
5 of cups : Disappointment
Disappointment
6 of cups : Pleasure
Pleasure
7 of cups : Debauch
Debuach
8 of cups : Indolence
Indolence
9 of cups : Happiness
Pleasure
10 of cups : Satiety
Satiety
Prince of cups : Devotion, sympathy, connection to the Higher Self
Princess of cups : Exploration of inner worlds, intuition
Knight of cups : Self-sacrifice, sympathy, helpfulness
Queen of cups : Feminine wisdom, blurring the boundaries of dreams
Ace of swords : The objective mind, intellectual organization
2 of swords : Peace
Peace
3 of swords : Misery
Misery
4 of swords : Truce
Truce
5 of swords : Loss
Loss
6 of swords : Science
Science
7 of swords : Futility
Futility
8 of swords : Interference
Interference
9 of swords : Creulty
Cruelty
10 of swords : Demise
Demise
Prince of swords : Quick solutions from a "smart talker"
Princess of swords : Impulsiveness, tempestuousness
Knight of swords : Astute, strategic, mentally agile
Queen of swords : Cool, calculating, independent and self-determining
Ace of disks : Pressing Earthly matters look for lasting bonds
2 of disks : Change
Change
3 of disks : Work
Work
4 of disks : Power
Power
5 of disks : Worry
Ordeal
6 of disks : Success
Success
7 of disks : Failure
Failure
8 of disks : Prudence
Prudence
9 of disks : Profit
Profit
10 of disks : Wealth
Wealth
Prince of disks : Reliability, pragmatism, diligence
Princess of disks : Nourishing, motherhood, emotional security
Knight of disks : Material concerns, security, sober leadership
Queen of disks : Stability in family, fertility, emotional sensibility
Adjustment
The Aeon : Revelation of abilities, recognition of correlations, awakening
Art : Combination of forces, realization, action based on accurate calculation
The Chariot : The Hero, spirit of conquest and adventure
Death : Change, voluntary or involuntary
The Devil : Blind impulse, irresistibly strong and unscrupulous, ambition
The Emperor : War, ambition, originality, confidence and megalomania
The Empress : Beauty, good fortune, graciousness, elegance, friendship
The Fool : Curiosity, experimentation, fantasy
Fortune : Alternation of fates (the wheel), a turn of events
The Hanged Man : Enforced sacrifice, punishment, loss
The Hierophant : A spiritual leader, a search for hidden truth, enlightenment
The Hermit : Introversion, wisdom, retreat
The Lovers : Openness to inspiration, intuition, intelligence, second sight
Lust : Strength, vitality, animal instincts
The Magus : Skill, wisdom, adroitness, elasticity, craft
The Moon : Illusion, deception, bewilderment, hysteria
The High Priestess : Alternation, increase and decrease, fluctuation
The Star : Creative hope, renewal, devotion to the moment
The Sun : Glory, riches, pleasure, truth, shamelessness, recovery from sickness
The Tower : Quarrel, combat, danger, ruin, destruction of plans
The Universe : homecoming, resolution of karma, wholeness, cosmic oneness


--- layout: post title: iPad 3 had arrived date: 2012-03-07 20:17:10.000000000 +08:00 permalink: ipad-3-had-arrived/ categories: - gadgets tags: [] status: publish type: post published: true meta: _edit_last: '2' _yoast_wpseo_metadesc: '' _yoast_wpseo_meta-robots-noindex: '0' OGP: a:20:{s:5:"title";s:0:"";s:4:"type";s:0:"";s:5:"image";s:0:"";s:11:"description";s:0:"";s:9:"fb:admins";s:0:"";s:9:"fb:app_id";s:0:"";s:14:"street-address";s:0:"";s:4:"city";s:0:"";s:11:"postal-code";s:0:"";s:12:"country-name";s:0:"";s:5:"email";s:0:"";s:12:"phone_number";s:0:"";s:10:"fax_number";s:0:"";s:5:"video";s:0:"";s:10:"videowidth";s:0:"";s:11:"videoheight";s:0:"";s:9:"videotype";s:0:"";s:6:"locale";s:0:"";s:18:"locale-alternative";s:0:"";s:3:"url";s:0:"";} _yoast_wpseo_title: '' _yoast_wpseo_focuskw: '' _yoast_wpseo_meta-robots-nofollow: '0' _yoast_wpseo_meta-robots-adv: none _yoast_wpseo_sitemap-include: '-' _yoast_wpseo_sitemap-prio: '-' _yoast_wpseo_canonical: '' _yoast_wpseo_redirect: '' cleaned: true ---
Apple launched another product who will empty your wallet again.
this time, luring you with greater screen resolution and faster processor.
Though it did not came with Siri, which is quite weird to have in a tablet, there is a presence of "voice dictation" which seems do the same way.
I personally dont prefer tablets because they are awkward to use in freelance jobs like programming, but its a hell good in entertainment purposes.


Be a Buggle Guide!
Sign Up
Login
Browse fresh guidebooks built by locals in the know.
advance option
"Bora" Boracay Travel Guide
Galileo Figaro Magnifico
3
$9.99
want more guides?
Featured Guides
Jan Van Boy Tigas
Professional Dancer
Galileo's Travel Guide
Galileo Figaro Magnifico
$9.99
3
view more
Galileo's Travel Guide
Galileo Figaro Magnifico
$9.99
3
view more
want more guides?
Country Guides
Galileo's Travel Guide
Galileo Figaro Magnifico
$9.99
3
view more
Galileo's Travel Guide
Galileo Figaro Magnifico
$9.99
3
view more
Galileo's Travel Guide
Galileo Figaro Magnifico
$9.99
3
view more
Galileo's Travel Guide
Galileo Figaro Magnifico
$9.99
3
view more
Galileo's Travel Guide
Galileo Figaro Magnifico
$9.99
3
view more
Galileo's Travel Guide
Galileo Figaro Magnifico
$9.99
3
view more


That’s great that your child has a college advisor! Some schools don’t provide any.
Some advisors might refuse to write a supporting letter of recommendation for your
child. Ultimately, there are several reasons why you don’t want to rely solely
on the college advisor:
1. The average advisor to student ratio is 1:296! Your child faces 1:296 competition
for advisor attention coupled with 2.63% medical school matriculation rate.
Boost your chances with customized, 1:1 guidance!
Link
2. It is not the advisor’s job to hold hands through the admissions process! He has so many
responsibilities that he doesn’t have time for any individual graduate application.
Advisors counsel on course selection, ensure students complete all the requisite credits for
graduation, teach first year seminars, hold workshops, perform committee work, organize
institutional events, and undertake many other administrative duties that detract from
direct student advising!
3. I provide everything that the advisor does not.
Mentorships
4. My experience as a doctor with active clinical experience provides a unique
perspective from the other end of the tunnel.
5. My mentorship encompasses more than on a cookbook recipe. It comprehensively
considers the before and after of the process, e.g. assess whether medical school
is the suitable path, locate funds for tuition, evaluate possible career options and
alternatives after medical school, etc.


The evaluation of an ordinary JavaScript expression may return a value, may never terminate, or may signal an error. In nondeterministic JavaScript the evaluation of an expression may in addition result in the discovery of a dead end, in which case evaluation must backtrack to a previous choice point. The interpretation of nondeterministic JavaScript is complicated by this extra case.
We will construct the amb evaluator for nondeterministic JavaScript by modifying the analyzing evaluator of section \ref{sec:separating-analysis}.[1] As in the analyzing evaluator, evaluation of an expression is accomplished by calling an execution function produced by analysis of that expression. The difference between the interpretation of ordinary JavaScript and the interpretation of nondeterministic JavaScript will be entirely in the execution functions.
Recall that the execution functions for the ordinary evaluator take one argument: the environment of execution. In contrast, the execution functions in the amb evaluator take three arguments: the environment, and two functions called continuation functions. The evaluation of an expression will finish by calling one of these two continuations: If the evaluation results in a value, the success continuation is called with that value; if the evaluation results in the discovery of a dead end, the failure continuation is called. Constructing and calling appropriate continuations is the mechanism by which the nondeterministic evaluator implements backtracking.
It is the job of the success continuation to receive a value and proceed with the computation. Along with that value, the success continuation is passed another failure continuation, which is to be called subsequently if the use of that value leads to a dead end.
It is the job of the failure continuation to try another branch of the nondeterministic process. The essence of the nondeterministic language is in the fact that expressions may represent choices among alternatives. The evaluation of such an expression must proceed with one of the indicated alternative choices, even though it is not known in advance which choices will lead to acceptable results. To deal with this, the evaluator picks one of the alternatives and passes this value to the success continuation. Together with this value, the evaluator constructs and passes along a failure continuation that can be called later to choose a different alternative.
A failure is triggered during evaluation (that is, a failure continuation is called) when a user program explicitly rejects the current line of attack (for example, a call to require may result in execution of amb(), an expression that always fails—see section \ref{sec:amb}). The failure continuation in hand at that point will cause the most recent choice point to choose another alternative. If there are no more alternatives to be considered at that choice point, a failure at an earlier choice point is triggered, and so on. Failure continuations are also invoked by the driver loop in response to a try-again request, to find another value of the expression.
In addition, if a side-effect operation (such as assignment to a variable) occurs on a branch of the process resulting from a choice, it may be necessary, when the process finds a dead end, to undo the side effect before making a new choice. This is accomplished by having the side-effect operation produce a failure continuation that undoes the side effect and propagates the failure.
In summary, failure continuations are constructed by
Failures are initiated only when a dead end is encountered. This occurs
Failure continuations are also called during processing of a failure:
The syntax- and data-representation functions for the amb evaluator, and also the basic analyze function, are identical to those in the evaluator of section \ref{sec:separating-analysis}, except for the fact that we need additional syntax functions to recognize amb expressions:[2]
function is_amb(stmt) { return is_tagged_list(stmt, "application") && is_name(operator(stmt)) && name_of_name(operator(stmt)) === "amb"; } function amb_choices(stmt) { return operands(stmt); }
We must also add to the dispatch in analyze a clause that will recognize such expressions and generate an appropriate execution function:
: is_amb(stmt) ? analyze_amb(stmt)
The top-level function ambeval (similar to the version of evaluate given in section \ref{sec:separating-analysis}) analyzes the given expression and applies the resulting execution function to the given environment, together with two given continuations:
function ambeval(exp, env, succeed, fail) { return analyze(exp)(env, succeed, fail); }
A success continuation is a function of two arguments: the value just obtained and another failure continuation to be used if that value leads to a subsequent failure. A failure continuation is a function of no arguments. So the general form of an execution function is
(env, succeed, fail) => { // succeed is a function of the form: (value, fail) => ... // fail is a function of the form: is () => ... }
Most of the complexity of the amb evaluator results from the mechanics of passing the continuations around as the execution functions call each other. In going through the following code, you should compare each of the execution functions with the corresponding function for the ordinary evaluator given in section \ref{sec:separating-analysis}.
The execution functions for the simplest kinds of expressions are essentially the same as those for the ordinary evaluator, except for the need to manage the continuations. The execution functions simply succeed with the value of the expression, passing along the failure continuation that was passed to them.
function analyze_self_evaluating(stmt) { return (env, succeed, fail) => succeed(stmt, fail); } function analyze_name(stmt) { return (env, succeed, fail) => succeed(lookup_name_value(name_of_name(stmt), env), fail); } function analyze_function_definition(stmt) { const vars = function_definition_parameters(stmt); const bfun = analyze(function_definition_body(stmt); return (env, succeed, fail) => succeed(make_function(vars, bfun, env), fail); }
Notice that looking up a
name
always succeeds.
If
lookup_name_value
fails to find the
name,
it signals an
error, as usual. Such a failure
indicates a program bug—a
reference to an unbound variable; it is not an indication that we
should try another nondeterministic choice instead of the one that is
currently being tried.
Conditionals are also handled in a similar way as in the ordinary evaluator. The execution function generated by analyze_conditional_expression invokes the predicate execution function pfun with a success continuation that checks whether the predicate value is true and goes on to execute either the consequent or the alternative. If the execution of pfun fails, the original failure continuation for the conditional expression is called.
function analyze_conditional_expression(stmt) { const pfun = analyze(cond_expr_pred(stmt); const cfun = analyze(cond_expr_cons(stmt)); const afun = analyze(cond_expr_alt(stmt)); return (env, succeed, fail) => pfun(env, // success continuation for evaluating the predicate // to obtain pred_value (pred_value, fail2) => is_true(pred_value) ? cfun(env, succeed, fail2) : afun(env, succeed, fail2), fail); }
Sequences are also handled in the same way as in the previous evaluator, except for the machinations in the subfunction sequentially that are required for passing the continuations. Namely, to sequentially execute a and then b, we call a with a success continuation that calls b.
function analyze_sequence(stmts) { function sequentially(a, b) { return (env, succeed, fail) => a(env, (a_value, fail2) => b(env, succeed, fail2), fail); } function loop(first_fun, rest_funs) { return is_null(rest_funs) ? first_fun : loop(sequentially(first_fun, head(rest_funs)), tail(rest_funs)); } const funs = map(analyze, stmts); return is_null(funs) ? env => undefined : loop(head(funs), tail(funs)); }
Declarations are another case where we must go to some trouble to manage the continuations, because it is necessary to evaluate the definition-value expression before actually defining the new variable. To accomplish this, the declaration-value execution function vfun is called with the environment, a success continuation, and the failure continuation. If the execution of vfun succeeds, obtaining a value val for the declared name, the name is declared and the success is propagated:
function analyze_variable_declaration(stmt) { const name = variable_declaration_name(stmt); const vfun = variable_declaration_value(stmt); return (env, succeed, fail) => vfun(env, (val, fail2) => { declare_variable(name, val, env); succeed("ok", fail2); }, fail); } function analyze_constant_declaration(stmt) { const name = constant_declaration_name(stmt); const vfun = constant_declaration_value(stmt); return (env, succeed, fail) => vfun(env, (val, fail2) => { declare_constant(name, val, env); succeed("ok", fail2); }, fail); }
Assignments are more interesting. This is the first place where we really use the continuations, rather than just passing them around. The execution function for assignments starts out like the one for definitions. It first attempts to obtain the new value to be assigned to the variable. If this evaluation of vfun fails, the assignment fails.
If vfun succeeds, however, and we go on to make the assignment, we must consider the possibility that this branch of the computation might later fail, which will require us to backtrack out of the assignment. Thus, we must arrange to undo the assignment as part of the backtracking process.[3]
This is accomplished by giving
vfun
a success continuation
(marked with the comment *1*
below) that saves the old value of
the variable before assigning the new value to the
variable and proceeding from the assignment. The failure continuation
that is passed along with the value of the assignment (marked with the
comment *2*
below) restores the old value of the variable
before continuing the failure.
That is, a successful assignment provides a failure continuation that
will intercept a subsequent failure; whatever failure would otherwise
have called fail2 calls this
function
instead, to undo the
assignment before actually calling fail2.
function analyze_assignment(stmt) { const variable = assignment_variable(stmt); const vfun = analyze(assignment_value(stmt)); return (env, succeed, fail) => vfun(env, (val, fail2) => { // *1* const old_value = lookup_name_value(variable, env); set_variable_value(variable, val, env); succeed("ok", () => { // *2* set_variable_value(variable, old_value, env); fail2(); }); }, fail); }
The execution function for applications contains no new ideas except for the technical complexity of managing the continuations. This complexity arises in analyze_application, due to the need to keep track of the success and failure continuations as we evaluate the operands. We use a function get_args to evaluate the list of operands, rather than a simple map as in the ordinary evaluator.
function analyze_application(stmt) { const ffun = analyze(operator(stmt)); const afuns = map(analyze, operands(stmt)); return (env, succeed, fail) => ffun(env, (fun, fail2) => get_args(afuns, env, (args, fail3) => execute_application(fun, args, succeed, fail3), fail2), fail); }
In get_args, notice how tailing down the list of afun, execution functions and pairing up the resulting list of args is accomplished by calling each afun in the list with a success continuation that recursively calls get_args. Each of these recursive calls to get_args has a success continuation whose value is the pair of the newly obtained argument onto the list of accumulated arguments:
function get_args(afuns, env, succeed, fail) { return is_null(afuns) ? succeed(null, fail) : head(afuns)(env, // success continuation for this afun (arg, fail2) => get_args(tail(afuns), env, // success continuation for // recursive call to get_args (args, fail3) => succeed(pair(arg, args), fail3), fail2), fail); }
The actual function application, which is performed by execute_application, is accomplished in the same way as for the ordinary evaluator, except for the need to manage the continuations.
function execute_application(fun, args, succeed, fail) { return is_primitive_function(fun) ? succeed(apply_primitive_function(fun, args), fail) : is_compound_function(fun) ? function_body(fun)( extend_environment( function_parameters(fun), args, function_environment(fun)), succeed, fail) : error(fun, "unknown function type in " + "execute_application"); }
The amb expression is the key element in the nondeterministic language. Here we see the essence of the interpretation process and the reason for keeping track of the continuations. The execution function for amb defines a loop try_next that cycles through the execution functions for all the possible values of the amb expression. Each execution function is called with a failure continuation that will try the next one. When there are no more alternatives to try, the entire amb expression fails.
function analyze_amb(exp) { const cfuns = map(analyze, amb_choices(exp)); return (env, succeed, fail) => { function try_next(choices) { return is_null(choices) ? fail() : head(choices)(env, succeed, () => try_next(tail(choices))); } return try_next(cfuns); }; }
The driver loop for the amb evaluator is complex, due to the mechanism that permits the user to try again in evaluating an expression. The driver uses a function called internal_loop, which takes as argument a function try_again. The intent is that calling try_again should go on to the next untried alternative in the nondeterministic evaluation. The function internal_loop either calls try_again in response to the user typing try-again at the driver loop, or else starts a new evaluation by calling ambeval.
The failure continuation for this call to ambeval informs the user that there are no more values and re-invokes the driver loop.
The success continuation for the call to ambeval
is more subtle. We print the obtained value and then invoke
the internal loop again with a
try_again
function
that will be
able to try the next alternative. This
next_alternative
function
is the second argument that was passed to the
success continuation. Ordinarily, we think of this second argument
as a failure continuation to be used if the current evaluation branch
later fails. In this case, however, we have completed a successful
evaluation, so we can invoke the failure
alternative branch in
order to search for additional successful evaluations.
const input_prompt = "// Amb-Eval input:"); const output_prompt = "// Amb-Eval value:"); function driver_loop() { function internal_loop(try_again) { prompt_for_input(input_prompt); const input = read(); if (input === "try-again") { try_again(); } else { display("// Starting a new problem "); ambeval(input, the_global_environment, // ambeval success (val, next_alternative) => { announce_output(output_prompt); user_print(val); return internal_loop(next_alternative); }, // ambeval failure () => { announce_output( "// There are no more values of"); user_print(input); return driver_loop(); }); } } return internal_loop( () => { display("// There is no current problem"); return driver_loop(); }); }
The initial call to internal_loop uses a try_again function that complains that there is no current problem and restarts the driver loop. This is the behavior that will happen if the user types try-again when there is no evaluation in progress.
let count = 0; let x = an_element_of("a", "b", "c"); let y = an_element_of("a", "b", "c"); count = count + 1; require(! x === y); list(x, y, count); // Starting a new problem // Amb-Eval value: ["a", ["b", [2, null]]] // Amb-Eval input: try-again // Amb-Eval value: ["a", ["c", [3, null]]]
// Amb-Eval input: if_fail( ( x => { require(is_even(x)); return x; } )(an_element_of(1, 3, 5)), "all-odd"); // Starting a new problem // Amb-Eval value: "all-odd" // Amb-Eval input: if_fail( ( x => { require(is_even(x)); return x; } )(an_element_of(1, 3, 5, 8)), "all-odd"); // Starting a new problem // Amb-Eval value: 8
let pairs = null; if_fail( ( p => { pairs = pair(p, pairs); amb(); } )(prime_sum_pair(list(1, 3, 5, 8), list(20, 35, 110))), pairs);
function is_require(stmt) { return is_tagged_list(stmt, "application") && is_name(operator(stmt)) && name_of_name(operator(stmt)) === "require"; } function require_predicate(exp) { return operands(exp); }
: is_require(stmt) ? analyze_require(stmt)
function analyze_require(stmt) { return (env, succeed, fail) => pfun(env, (pred_value, fail2) => ... ? ... : succeed("ok", fail2), fail); }


Video not supported
ROBOTS
APPLICATIONS
BUY
COMPANY
NEWS
CONTACT US
CAREERS
MEET
Autonomous Farming Begins with Collaborative Farm Robot
Order Burros for Spring Delivery!


Class Frame
Forms9Patch Frame layout.
Inherited Members
Namespace: Forms9Patch
Assembly: Forms9Patch.dll
Syntax
public class Frame : ContentView, ILayout, IBackground, IShape, IElement
Constructors
Frame()
Initializes an instance of the Frame class.
Declaration
public Frame()
Methods
OnPropertyChanged(String)
Called when a property has changed
Declaration
protected override void OnPropertyChanged(string propertyName = null)
Parameters
| Type | Name | Description |
|---|---|---|
| String | propertyName |


| #{{build.number}} | {{build.message}} |
{{build.author}}
{{BuildEvent[build.event]}}
{{build.branch}}
{{build.createdAt | amTimeAgo}}
{{(build.finishedAt - build.createdAt) | amDuration:'milliseconds'}}
|
|


grails create-plugin <<PLUGIN NAME>>
18 Plugins
Version: 3.2.11
Table of Contents
18 Plugins
Grails is first and foremost a web application framework, but it is also a platform. By exposing a number of extension points that let you extend anything from the command line interface to the runtime configuration engine, Grails can be customised to suit almost any needs. To hook into this platform, all you need to do is create a plugin.
Extending the platform may sound complicated, but plugins can range from trivially simple to incredibly powerful. If you know how to build a Grails application, you’ll know how to create a plugin for sharing a data model or some static resources.
18.1 Creating and Installing Plugins
Creating Plugins
Creating a Grails plugin is a simple matter of running the command:
This will create a plugin project for the name you specify. For example running grails create-plugin example
would create a new plugin project called example
.
In Grails 3.0 you should consider whether the plugin you create requires a web environment or whether the plugin can be used with other profiles. If your plugin does not require a web environment then use the "plugin" profile instead of the "web-plugin" profile:
grails create-plugin <<PLUGIN NAME>> --profile=plugin
Make sure the plugin name does not contain more than one capital letter in a row, or it won’t work. Camel case is fine, though.
Being a regular Grails project has a number of benefits in that you can immediately test your plugin by running (if the plugin targets the "web" profile):
grails run-app
Plugin projects don’t provide an index.gsp by default since most plugins don’t need it. So, if you try to view the plugin running in a browser right after creating it, you will receive a page not found error. You can easily create a grails-app/views/index.gsp for your plugin if you’d like.
|
The structure of a Grails plugin is very nearly the same as a Grails application project’s except that in the src/main/groovy
directory under the plugin package structure you will find a plugin descriptor class (a class that ends in "GrailsPlugin"). For example:
import grails.plugins.*
class ExampleGrailsPlugin extends Plugin {
...
}
All plugins must have this class under the src/main/groovy
directory, otherwise they are not regarded as a plugin. The plugin class defines metadata about the plugin, and optionally various hooks into plugin extension points (covered shortly).
You can also provide additional information about your plugin using several special properties:
-
title
- short one-sentence description of your plugin -
grailsVersion
- The version range of Grails that the plugin supports. eg. "1.2 > *" (indicating 1.2 or higher) -
author
- plugin author’s name -
authorEmail
- plugin author’s contact e-mail -
developers
- Any additional developers beyond the author specified above. -
description
- full multi-line description of plugin’s features -
documentation
- URL of the plugin’s documentation -
license
- License of the plugin -
issueManagement
- Issue Tracker of the plugin -
scm
- Source code management location of the plugin
Here is a slimmed down example from the Quartz Grails plugin:
package quartz
@Slf4j
class QuartzGrailsPlugin extends Plugin {
// the version or versions of Grails the plugin is designed for
def grailsVersion = "3.0.0.BUILD-SNAPSHOT > *"
// resources that are excluded from plugin packaging
def pluginExcludes = [
"grails-app/views/error.gsp"
]
def title = "Quartz" // Headline display name of the plugin
def author = "Jeff Brown"
def authorEmail =<EMAIL_ADDRESS>def description = '''\
Adds Quartz job scheduling features
'''
def profiles = ['web']
List loadAfter = ['hibernate3', 'hibernate4', 'hibernate5', 'services']
def documentation = "http://grails.org/plugin/quartz"
def license = "APACHE"
def issueManagement = [ system: "Github Issues", url: "http://github.com/grails3-plugins/quartz/issues" ]
def developers = [
[ name: "Joe Dev", email<EMAIL_ADDRESS>]
]
def scm = [ url: "https://github.com/grails3-plugins/quartz/" ]
Closure doWithSpring()......
Installing Local Plugins
To make your plugin available for use in a Grails application run the install
command:
grails install
This will install the plugin into your local Maven cache. Then to use the plugin within an application declare a dependency on the plugin in your build.gradle
file:
compile "org.grails.plugins:quartz:0.1"
| In Grails 2.x plugins were packaged as ZIP files, however in Grails 3.x plugins are simple JAR files that can be added to the classpath of the IDE. |
Plugins and Multi-Project Builds
If you wish to setup a plugin as part of a multi project build then follow these steps.
Step 1: Create the application and the plugin
Using the grails
command create an application and a plugin:
$ grails create-app myapp
$ grails create-plugin myplugin
Step 2: Create a settings.gradle file
In the same directory create a settings.gradle
file with the following contents:
include "myapp", "myplugin"
The directory structure should be as follows:
PROJECT_DIR
- settings.gradle
- myapp
- build.gradle
- myplugin
- build.gradle
Step 3: Declare a project dependency on the plugin
Within the build.gradle
of the application declare a dependency on the plugin within the plugins
block:
grails {
plugins {
compile project(':myplugin')
}
}
You can also declare the dependency within the dependencies block, however you will not get subproject reloading if you do this!
|
Step 4: Run the application
Now run the application using the grails run-app
command from the root of the application directory, you can use the verbose
flag to see the Gradle output:
$ cd myapp
$ grails run-app -verbose
You will notice from the Gradle output that plugins sources are built and placed on the classpath of your application:
:myplugin:compileAstJava UP-TO-DATE
:myplugin:compileAstGroovy UP-TO-DATE
:myplugin:processAstResources UP-TO-DATE
:myplugin:astClasses UP-TO-DATE
:myplugin:compileJava UP-TO-DATE
:myplugin:configScript UP-TO-DATE
:myplugin:compileGroovy
:myplugin:copyAssets UP-TO-DATE
:myplugin:copyCommands UP-TO-DATE
:myplugin:copyTemplates UP-TO-DATE
:myplugin:processResources
:myapp:compileJava UP-TO-DATE
:myapp:compileGroovy
:myapp:processResources UP-TO-DATE
:myapp:classes
:myapp:findMainClass
:myapp:bootRun
Grails application running at http://localhost:8080 in environment: development
Notes on excluded Artefacts
Although the create-plugin command creates certain files for you so that the plugin can be run as a Grails application, not all of these files are included when packaging a plugin. The following is a list of artefacts created, but not included by package-plugin:
-
grails-app/build.gradle
(although it is used to generatedependencies.groovy
) -
grails-app/conf/application.yml
(renamed to plugin.yml) -
grails-app/conf/spring/resources.groovy
-
grails-app/conf/logback.groovy
-
Everything within
/src/test/*\*
-
SCM management files within
*\*/.svn/*\*
and*\*/CVS/*\*
Customizing the plugin contents
When developing a plugin you may create test classes and sources that are used during the development and testing of the plugin but should not be exported to the application.
To exclude test sources you need to modify the pluginExcludes
property of the plugin descriptor AND exclude the resources inside your build.gradle
file. For example say you have some classes under the com.demo
package that are in your plugin source tree but should not be packaged in the application. In your plugin descriptor you should exclude these:
// resources that should be loaded by the plugin once installed in the application
def pluginExcludes = [
'**/com/demo/**'
]
And in your build.gradle
you should exclude the compiled classes from the JAR file:
jar {
exclude "com/demo/**/**"
}
Inline Plugins in Grails 3.0
In Grails 2.x it was possible to specify inline plugins in BuildConfig
, in Grails 3.x this functionality has been replaced by Gradle’s multi-project build feature.
To set up a multi project build create an appliation and a plugin in a parent directory:
$ grails create-app myapp
$ grails create-plugin myplugin
Then create a settings.gradle
file in the parent directory specifying the location of your application and plugin:
include 'myapp', 'myplugin'
Finally add a dependency in your application’s build.gradle
on the plugin:
compile project(':myplugin')
Using this technique you have achieved the equivalent of inline plugins from Grails 2.x.
18.2 Plugin Repositories
Distributing Plugins in the Grails Central Plugin Repository
The preferred way to distribute plugin is to publish to the official Grails Central Plugin Repository. This will make your plugin visible to the list-plugins command:
grails list-plugins
which lists all plugins that are in the central repository. Your plugin will also be available to the plugin-info command:
grails plugin-info [plugin-name]
which prints extra information about it, such as its description, who wrote, etc.
| If you have created a Grails plugin and want it to be hosted in the central repository, you’ll find instructions for getting an account on the plugin portal website. |
18.3 Providing Basic Artefacts
Add Command Line Commands
A plugin can add new commands to the Grails 3.0 interactive shell in one of two ways. First, using the create-script you can create a code generation script which will become available to the application. The create-script
command will create the script in the src/main/scripts
directory:
+ src/main/scripts <-- additional scripts here
+ grails-app
+ controllers
+ services
+ etc.
Code generation scripts can be used to create artefacts within the project tree and automate interactions with Gradle.
If you want to create a new shell command that interacts with a loaded Grails application instance then you should use the create-command
command:
$ grails create-command MyExampleCommand
This will create a file called grails-app/commands/PACKAGE_PATH/MyExampleCommand.groovy
that extends ApplicationCommand:
import grails.dev.commands.*
class MyExampleCommand implements ApplicationCommand {
boolean handle(ExecutionContext ctx) {
println "Hello World"
return true
}
}
An ApplicationCommand
has access to the GrailsApplication
instance and is subject to autowiring like any other Spring bean.
You can also inform Grails to skip the execution of Bootstrap.groovy
files with a simple property in your command:
class MyExampleCommand implements ApplicationCommand {
boolean skipBootstrap = true
boolean handle(ExecutionContext ctx) {
...
}
}
For each ApplicationCommand
present Grails will create a shell command and a Gradle task to invoke the ApplicationCommand
. In the above example you can invoke the MyExampleCommand
class using either:
$ grails my-example
Or
$ gradle myExample
The Grails version is all lower case hyphen separated and excludes the "Command" suffix.
The main difference between code generation scripts and ApplicationCommand
instances is that the latter has full access to the Grails application state and hence can be used to perform tasks that interactive with the database, call into GORM etc.
In Grails 2.x Gant scripts could be used to perform both these tasks, in Grails 3.x code generation and interacting with runtime application state has been cleanly separated.
Adding a new grails-app artifact (Controller, Tag Library, Service, etc.)
A plugin can add new artifacts by creating the relevant file within the grails-app
tree.
+ grails-app
+ controllers <-- additional controllers here
+ services <-- additional services here
+ etc. <-- additional XXX here
Providing Views, Templates and View resolution
When a plugin provides a controller it may also provide default views to be rendered. This is an excellent way to modularize your application through plugins. Grails' view resolution mechanism will first look for the view in the application it is installed into and if that fails will attempt to look for the view within the plugin. This means that you can override views provided by a plugin by creating corresponding GSPs in the application’s grails-app/views
directory.
For example, consider a controller called BookController
that’s provided by an 'amazon' plugin. If the action being executed is list
, Grails will first look for a view called grails-app/views/book/list.gsp
then if that fails it will look for the same view relative to the plugin.
However if the view uses templates that are also provided by the plugin then the following syntax may be necessary:
<g:render template="fooTemplate" plugin="amazon"/>
Note the usage of the plugin
attribute, which contains the name of the plugin where the template resides. If this is not specified then Grails will look for the template relative to the application.
Excluded Artefacts
By default Grails excludes the following files during the packaging process:
-
grails-app/conf/logback.groovy
-
grails-app/conf/application.yml
(renamed toplugin.yml
) -
grails-app/conf/spring/resources.groovy
-
Everything within
/src/test/*\*
-
SCM management files within
*\*/.svn/*\*
and*\*/CVS/*\*
In addition, the default UrlMappings.groovy
file is excluded to avoid naming conflicts, however you are free to add a UrlMappings definition under a different name which will be included. For example a file called grails-app/controllers/BlogUrlMappings.groovy
is fine.
The list of excludes is extensible with the pluginExcludes
property:
// resources that are excluded from plugin packaging
def pluginExcludes = [
"grails-app/views/error.gsp"
]
This is useful for example to include demo or test resources in the plugin repository, but not include them in the final distribution.
18.4 Evaluating Conventions
Before looking at providing runtime configuration based on conventions you first need to understand how to evaluate those conventions from a plugin. Every plugin has an implicit application
variable which is an instance of the GrailsApplication interface.
The GrailsApplication
interface provides methods to evaluate the conventions within the project and internally stores references to all artifact classes within your application.
Artifacts implement the GrailsClass interface, which represents a Grails resource such as a controller or a tag library. For example to get all GrailsClass
instances you can do:
for (grailsClass in application.allClasses) {
println grailsClass.name
}
GrailsApplication
has a few "magic" properties to narrow the type of artefact you are interested in. For example to access controllers you can use:
for (controllerClass in application.controllerClasses) {
println controllerClass.name
}
The dynamic method conventions are as follows:
-
*Classes
- Retrieves all the classes for a particular artefact name. For exampleapplication.controllerClasses
. -
get*Class
- Retrieves a named class for a particular artefact. For exampleapplication.getControllerClass("PersonController")
-
is*Class
- Returnstrue
if the given class is of the given artefact type. For exampleapplication.isControllerClass(PersonController)
The GrailsClass
interface has a number of useful methods that let you further evaluate and work with the conventions. These include:
-
getPropertyValue
- Gets the initial value of the given property on the class -
hasProperty
- Returnstrue
if the class has the specified property -
newInstance
- Creates a new instance of this class. -
getName
- Returns the logical name of the class in the application without the trailing convention part if applicable -
getShortName
- Returns the short name of the class without package prefix -
getFullName
- Returns the full name of the class in the application with the trailing convention part and with the package name -
getPropertyName
- Returns the name of the class as a property name -
getLogicalPropertyName
- Returns the logical property name of the class in the application without the trailing convention part if applicable -
getNaturalName
- Returns the name of the property in natural terms (e.g. 'lastName' becomes 'Last Name') -
getPackageName
- Returns the package name
For a full reference refer to the javadoc API.
18.5 Hooking into Runtime Configuration
Grails provides a number of hooks to leverage the different parts of the system and perform runtime configuration by convention.
Hooking into the Grails Spring configuration
First, you can hook in Grails runtime configuration overriding the doWithSpring
method from the Plugin class and returning a closure that defines additional beans. For example the following snippet is from one of the core Grails plugins that provides i18n support:
import org.springframework.web.servlet.i18n.CookieLocaleResolver
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor
import org.springframework.context.support.ReloadableResourceBundleMessageSource
import grails.plugins.*
class I18nGrailsPlugin extends Plugin {
def version = "0.1"
Closure doWithSpring() {{->
messageSource(ReloadableResourceBundleMessageSource) {
basename = "WEB-INF/grails-app/i18n/messages"
}
localeChangeInterceptor(LocaleChangeInterceptor) {
paramName = "lang"
}
localeResolver(CookieLocaleResolver)
}}
}
This plugin configures the Grails messageSource
bean and a couple of other beans to manage Locale resolution and switching. It using the Spring Bean Builder syntax to do so.
Customizing the Servlet Environment
In previous versions of Grails it was possible to dynamically modify the generated web.xml
. In Grails 3.x there is no web.xml
file and it is not possible to programmatically modify the web.xml
file anymore.
However, it is possible to perform the most commons tasks of modifying the Servlet environment in Grails 3.x.
Adding New Servlets
If you want to add a new Servlet instance the simplest way is simply to define a new Spring bean in the doWithSpring
method:
Closure doWithSpring() {{->
myServlet(MyServlet)
}}
If you need to customize the servlet you can use Spring Boot’s ServletRegistrationBean:
Closure doWithSpring() {{->
myServlet(ServletRegistrationBean, new MyServlet(), "/myServlet/*") {
loadOnStartup = 2
}
}}
Adding New Servlet Filters
Just like Servlets, the simplest way to configure a new filter is to simply define a Spring bean:
Closure doWithSpring() {{->
myFilter(MyFilter)
}}
However, if you want to control the order of filter registrations you will need to use Spring Boot’s FilterRegistrationBean:
myFilter(FilterRegistrationBean) {
filter = bean(MyFilter)
urlPatterns = ['/*']
order = Ordered.HIGHEST_PRECEDENCE
}
Grails' internal registered filters (GrailsWebRequestFilter , HiddenHttpMethodFilter etc.) are defined by incrementing HIGHEST_PRECEDENCE by 10 thus allowing several filters to be inserted before or between Grails' filters.
|
Doing Post Initialisation Configuration
Sometimes it is useful to be able do some runtime configuration after the Spring ApplicationContext has been built. In this case you can define a doWithApplicationContext
closure property.
class SimplePlugin extends Plugin{
def name = "simple"
def version = "1.1"
@Override
void doWithApplicationContext() {
def sessionFactory = applicationContext.sessionFactory
// do something here with session factory
}
}
18.6 Adding Methods at Compile Time
Grails 3.0 makes it easy to add new traits to existing artefact types from a plugin. For example say you wanted to add methods for manipulating dates to controllers. This can be done by defining a trait in src/main/groovy
:
package myplugin
@Enhances("Controller")
trait DateTrait {
Date currentDate() {
return new Date()
}
}
The @Enhances
annotation defines the types of artefacts that the trait should be applied to.
As an alternative to using the @Enhances
annotation above, you can implement a TraitInjector to tell Grails which artefacts you want to inject the trait into at compile time:
package myplugin
@CompileStatic
class ControllerTraitInjector implements TraitInjector {
@Override
Class getTrait() {
SomeTrait
}
@Override
String[] getArtefactTypes() {
['Controller'] as String[]
}
}
The above TraitInjector
will add the SomeTrait
to all controllers. The getArtefactTypes
method defines the types of artefacts that the trait should be applied to.
Applying traits conditionally
A TraitInjector
implementation can also implement the SupportsClassNode interface to apply traits to only those artefacts which satisfy a custom requirement.
For example, if a trait should only be applied if the target artefact class has a specific annotation, it can be done as below
package myplugin
@CompileStatic
class AnnotationBasedTraitInjector implements TraitInjector, SupportsClassNode {
@Override
Class getTrait() {
SomeTrait
}
@Override
String[] getArtefactTypes() {
['Controller'] as String[]
}
boolean supports(ClassNode classNode) {
return GrailsASTUtils.hasAnnotation(classNode, SomeAnnotation)
}
}
Above TraitInjector
will add the SomeTrait
to only those controllers which has the SomeAnnotation
declared.
The framework discovers trait injectors by way of a META-INF/grails.factories
descriptor that is in the .jar file. This descriptor is automatically generated. The descriptor generated for the code shown above would look like this:
#Grails Factories File
grails.compiler.traits.TraitInjector=myplugin.ControllerTraitInjector,myplugin.DateTraitTraitInjector
That file is generated automatically and added to the .jar file at build time. If for any reason the application defines its own grails.factories
file at src/main/resources/META-INF/grails.factories
, it is important that the trait injectors be explicitly defined in that file. The auto-generated metadata is only reliable if the application does not define its own src/main/resources/META-INF/grails.factores
file.
18.7 Adding Dynamic Methods at Runtime
The Basics
Grails plugins let you register dynamic methods with any Grails-managed or other class at runtime. This work is done in a doWithDynamicMethods
method.
Note that Grails 3.x features newer features such as traits that are usable from code compiled with CompileStatic . It is recommended that dynamic behavior is only added for cases that are not possible with traits.
|
class ExamplePlugin extends Plugin {
void doWithDynamicMethods() {
for (controllerClass in grailsApplication.controllerClasses) {
controllerClass.metaClass.myNewMethod = {-> println "hello world" }
}
}
}
In this case we use the implicit application object to get a reference to all of the controller classes' MetaClass instances and add a new method called myNewMethod
to each controller. If you know beforehand the class you wish the add a method to you can simply reference its metaClass
property.
For example we can add a new method swapCase
to java.lang.String
:
class ExamplePlugin extends Plugin {
@Override
void doWithDynamicMethods() {
String.metaClass.swapCase = {->
def sb = new StringBuilder()
delegate.each {
sb << (Character.isUpperCase(it as char) ?
Character.toLowerCase(it as char) :
Character.toUpperCase(it as char))
}
sb.toString()
}
assert "UpAndDown" == "uPaNDdOWN".swapCase()
}
}
Interacting with the ApplicationContext
The doWithDynamicMethods
closure gets passed the Spring ApplicationContext
instance. This is useful as it lets you interact with objects within it. For example if you were implementing a method to interact with Hibernate you could use the SessionFactory
instance in combination with a HibernateTemplate
:
import org.springframework.orm.hibernate3.HibernateTemplate
class ExampleHibernatePlugin extends Plugin{
void doWithDynamicMethods() {
for (domainClass in grailsApplication.domainClasses) {
domainClass.metaClass.static.load = { Long id->
def sf = applicationContext.sessionFactory
def template = new HibernateTemplate(sf)
template.load(delegate, id)
}
}
}
}
Also because of the autowiring and dependency injection capability of the Spring container you can implement more powerful dynamic constructors that use the application context to wire dependencies into your object at runtime:
class MyConstructorPlugin {
void doWithDynamicMethods()
for (domainClass in grailsApplication.domainClasses) {
domainClass.metaClass.constructor = {->
return applicationContext.getBean(domainClass.name)
}
}
}
}
Here we actually replace the default constructor with one that looks up prototyped Spring beans instead!
18.8 Participating in Auto Reload Events
Monitoring Resources for Changes
Often it is valuable to monitor resources for changes and perform some action when they occur. This is how Grails implements advanced reloading of application state at runtime. For example, consider this simplified snippet from the Grails ServicesPlugin
:
class ServicesGrailsPlugin extends Plugin {
...
def watchedResources = "file:./grails-app/services/**/*Service.groovy"
...
void onChange( Map<String, Object> event) {
if (event.source) {
def serviceClass = grailsApplication.addServiceClass(event.source)
def serviceName = "${serviceClass.propertyName}"
beans {
"$serviceName"(serviceClass.getClazz()) { bean ->
bean.autowire = true
}
}
}
}
}
First it defines watchedResources
as either a String or a List of strings that contain either the references or patterns of the resources to watch. If the watched resources specify a Groovy file, when it is changed it will automatically be reloaded and passed into the onChange
closure in the event
object.
The event
object defines a number of useful properties:
-
event.source
- The source of the event, either the reloadedClass
or a SpringResource
-
event.ctx
- The SpringApplicationContext
instance -
event.plugin
- The plugin object that manages the resource (usuallythis
) -
event.application
- TheGrailsApplication
instance -
event.manager
- TheGrailsPluginManager
instance
These objects are available to help you apply the appropriate changes based on what changed. In the "Services" example above, a new service bean is re-registered with the ApplicationContext
when one of the service classes changes.
Influencing Other Plugins
In addition to reacting to changes, sometimes a plugin needs to "influence" another.
Take for example the Services and Controllers plugins. When a service is reloaded, unless you reload the controllers too, problems will occur when you try to auto-wire the reloaded service into an older controller Class.
To get around this, you can specify which plugins another plugin "influences". This means that when one plugin detects a change, it will reload itself and then reload its influenced plugins. For example consider this snippet from the ServicesGrailsPlugin
:
def influences = ['controllers']
Observing other plugins
If there is a particular plugin that you would like to observe for changes but not necessary watch the resources that it monitors you can use the "observe" property:
def observe = ["controllers"]
In this case when a controller is changed you will also receive the event chained from the controllers plugin.
It is also possible for a plugin to observe all loaded plugins by using a wildcard:
def observe = ["*"]
The Logging plugin does exactly this so that it can add the log
property back to any artefact that changes while the application is running.
18.9 Understanding Plugin Load Order
Controlling Plugin Dependencies
Plugins often depend on the presence of other plugins and can adapt depending on the presence of others. This is implemented with two properties. The first is called dependsOn
. For example, take a look at this snippet from the Hibernate plugin:
class HibernateGrailsPlugin {
def version = "1.0"
def dependsOn = [dataSource: "1.0",
domainClass: "1.0",
i18n: "1.0",
core: "1.0"]
}
The Hibernate plugin is dependent on the presence of four plugins: the dataSource
, domainClass
, i18n
and core
plugins.
The dependencies will be loaded before the Hibernate plugin and if all dependencies do not load, then the plugin will not load.
The dependsOn
property also supports a mini expression language for specifying version ranges. A few examples of the syntax can be seen below:
def dependsOn = [foo: "* > 1.0"]
def dependsOn = [foo: "1.0 > 1.1"]
def dependsOn = [foo: "1.0 > *"]
When the wildcard * character is used it denotes "any" version. The expression syntax also excludes any suffixes such as -BETA, -ALPHA etc. so for example the expression "1.0 > 1.1" would match any of the following versions:
-
1.1
-
1.0
-
1.0.1
-
1.0.3-SNAPSHOT
-
1.1-BETA2
Controlling Load Order
Using dependsOn
establishes a "hard" dependency in that if the dependency is not resolved, the plugin will give up and won’t load. It is possible though to have a weaker dependency using the loadAfter
and loadBefore
properties:
def loadAfter = ['controllers']
Here the plugin will be loaded after the controllers
plugin if it exists, otherwise it will just be loaded. The plugin can then adapt to the presence of the other plugin, for example the Hibernate plugin has this code in its doWithSpring
closure:
if (manager?.hasGrailsPlugin("controllers")) {
openSessionInViewInterceptor(OpenSessionInViewInterceptor) {
flushMode = HibernateAccessor.FLUSH_MANUAL
sessionFactory = sessionFactory
}
grailsUrlHandlerMapping.interceptors << openSessionInViewInterceptor
}
Here the Hibernate plugin will only register an OpenSessionInViewInterceptor
if the controllers
plugin has been loaded. The manager
variable is an instance of the GrailsPluginManager interface and it provides methods to interact with other plugins.
You can also use the loadBefore
property to specify one or more plugins that your plugin should load before:
def loadBefore = ['rabbitmq']
Scopes and Environments
It’s not only plugin load order that you can control. You can also specify which environments your plugin should be loaded in and which scopes (stages of a build). Simply declare one or both of these properties in your plugin descriptor:
def environments = ['development', 'test', 'myCustomEnv']
def scopes = [excludes:'war']
In this example, the plugin will only load in the 'development' and 'test' environments. Nor will it be packaged into the WAR file, because it’s excluded from the 'war' phase. This allows development-only
plugins to not be packaged for production use.
The full list of available scopes are defined by the enum BuildScope, but here’s a summary:
-
test
- when running tests -
functional-test
- when running functional tests -
run
- for run-app and run-war -
war
- when packaging the application as a WAR file -
all
- plugin applies to all scopes (default)
Both properties can be one of:
-
a string - a sole inclusion
-
a list - a list of environments or scopes to include
-
a map - for full control, with 'includes' and/or 'excludes' keys that can have string or list values
For example,
def environments = "test"
will only include the plugin in the test environment, whereas
def environments = ["development", "test"]
will include it in both the development and test environments. Finally,
def environments = [includes: ["development", "test"]]
will do the same thing.
18.10 The Artefact API
You should by now understand that Grails has the concept of artefacts: special types of classes that it knows about and can treat differently from normal Groovy and Java classes, for example by enhancing them with extra properties and methods. Examples of artefacts include domain classes and controllers. What you may not be aware of is that Grails allows application and plugin developers access to the underlying infrastructure for artefacts, which means you can find out what artefacts are available and even enhance them yourself. You can even provide your own custom artefact types.
18.10.1 Asking About Available Artefacts
As a plugin developer, it can be important for you to find out about what domain classes, controllers, or other types of artefact are available in an application. For example, the Elasticsearch plugin needs to know what domain classes exist so it can check them for any searchable
properties and index the appropriate ones. So how does it do it? The answer lies with the grailsApplication
object, and instance of GrailsApplication that’s available automatically in controllers and GSPs and can be injected everywhere else.
The grailsApplication
object has several important properties and methods for querying artefacts. Probably the most common is the one that gives you all the classes of a particular artefact type:
for (cls in grailsApplication.<artefactType>Classes) {
...
}
In this case, artefactType
is the property name form of the artefact type. With core Grails you have:
-
domain
-
controller
-
tagLib
-
service
-
codec
-
bootstrap
-
urlMappings
So for example, if you want to iterate over all the domain classes, you use:
for (cls in grailsApplication.domainClasses) {
...
}
and for URL mappings:
for (cls in grailsApplication.urlMappingsClasses) {
...
}
You need to be aware that the objects returned by these properties are not instances of Class. Instead, they are instances of GrailsClass that has some particularly useful properties and methods, including one for the underlying Class
:
-
shortName
- the class name of the artefact without the package (equivalent ofClass.simpleName
). -
logicalPropertyName
- the artefact name in property form without the 'type' suffix. SoMyGreatController
becomes 'myGreat'. -
isAbstract()
- a boolean indicating whether the artefact class is abstract or not. -
getPropertyValue(name)
- returns the value of the given property, whether it’s a static or an instance one. This works best if the property is initialised on declaration, e.g.static transactional = true
.
The artefact API also allows you to fetch classes by name and check whether a class is an artefact:
-
get<type>Class(String name)
-
is<type>Class(Class clazz)
The first method will retrieve the GrailsClass
instance for the given name, e.g. 'MyGreatController'. The second will check whether a class is a particular type of artefact. For example, you can use grailsApplication.isControllerClass(org.example.MyGreatController)
to check whether MyGreatController
is in fact a controller.
18.10.2 Adding Your Own Artefact Types
Plugins can easily provide their own artefacts so that they can easily find out what implementations are available and take part in reloading. All you need to do is create an ArtefactHandler
implementation and register it in your main plugin class:
class MyGrailsPlugin {
def artefacts = [ org.somewhere.MyArtefactHandler ]
...
}
The artefacts
list can contain either handler classes (as above) or instances of handlers.
So, what does an artefact handler look like? Well, put simply it is an implementation of the ArtefactHandler interface. To make life a bit easier, there is a skeleton implementation that can readily be extended: ArtefactHandlerAdapter.
In addition to the handler itself, every new artefact needs a corresponding wrapper class that implements GrailsClass. Again, skeleton implementations are available such as AbstractInjectableGrailsClass, which is particularly useful as it turns your artefact into a Spring bean that is auto-wired, just like controllers and services.
The best way to understand how both the handler and wrapper classes work is to look at the Quartz plugin:
Another example is the Shiro plugin which adds a realm artefact.