WITNESS LIST International Relations and Trade Committee April 9, 2003 - 1:30P SB 309 FOR: Dunkelberg, Anne Senior Policy Analyst (Center for Public Policy Priorities), Austin, TX Garcia, Sylvia Harris County Commissioner (Harris County), Houston, TX Hillier, King Director, Legislative Relations (Harris County Commissioners Court), Houston, TX Sanchez, Joe (Mexican American Legal Defense and Educational Fund (MALDEF)), San Antonio, TX Stone, Nancy Government Relations Coordinator (Harris County Hospital District), Houston, TX Urrutia, Marcela Policy Analyst (National Council of La Raza (NCLR)), Austin, TX Registering, but not testifying: For: Crowe, Michael Attorney/Lobbyist (El Paso County Hospital District), El Paso, TX Dowe, Tammy (Greater Houston Partnership), Houston, TX Peters, Richard Consultant (Texas Association of Public & Nonprofit Hospitals), Austin, TX Villarreal, Armando (United Farm Workers of America), San Antonio, TX Whitehurst, Darren Legislative Director (Texas Hospital Association), Austin, TX Providing written testimony: For: Bodden, Rosa (Texas IAF Organizations), Mercedes, TX SCR 7 FOR: Barraza, Santa (Self), Kingsville, TX Staudt, Kathleen Professor of Political Science, UTEP (Coalition Against Violence Toward Women and Families at the U.S.-Mexico Border), El Paso, TX Registering, but not testifying: For: Calvert, Hannah (Self), Austin, TX Canchola, Maria Travis County Constable, Precint 4 (Self), Austin, TX Cotera, Martha (Austin Coalition Against Violence Toward Women in Ciudad Juarez), Austin, TX Jimenez, Maria (National Movement for Legalization & Immigrant Rights), Houston, TX Orta, Lucia Board Member (Allego), Austin, TX Perez, Cynthia (Mujeres Sin Fronteras), Austin, TX Rios, Andrea Administrator (La Pena), Austin, TX SCR 21 Registering, but not testifying: For: Sanchez, Joe (MALDEF), San Antonio, TX Urrutia, Marcela Policy Analyst (National Council of La Raza), Austin, TX Villarreal, Armando (United Farm Workers of America, AFL-CIO), San Antonio, TX


The <wm-exclusive-content>
component
The <wm-exclusive-content>
is a web component that
you can use to show exclusive content if it determines the user is
sending payments via web monetization.
The component only activates if the Web Monetization API is available, otherwise it will show nothing.
The component has 1 attribute you can use:
-
template
-
A CSS selector for a
<template>
element. The component will find the template, hydrate it and use it as the exclusive contents. This overrides nesting a template element within the custom element.
Examples
If you are using a browser that supports the Web Monetization API then you will see the text "Thank you for supporting this site with Web Monetization" below once you start sending payments. If your browser supports Web Monetization and you choose not to send a payment to the page then the text will not appear. If your browser doesn't support Web Monetization then you will not see the text at all.
Thank you for supporting this site with Web Monetization
<wm-exclusive-content>
<template>

Thank you for supporting this site with Web
Monetization

</template>
</wm-exclusive-content>


Festive winter wonderland for your dog to open this Christmas at Scots heritage centre
Take your dog to see Santa Paws this Christmas.
by Jennifer Russell, https://www.dailyrecord.co.uk/authors/jennifer-russell/A Scots heritage centre is putting on a festive winter wonderland with a difference this Christmas .
Almond Valley Heritage Centre, in West Lothian , is giving visitors the chance to bring their beloved pets to see Santa Paws.
As always the family attraction is opening its doors to excited children to meet Santa Claus, but now dogs are invited too.
This year, the whole family can get involved as guests can buy a ticket for their pet pooches.
Each weekend in December, canine friends can enjoy meeting Mrs Santa Paws where they will receive a special festive treat under the shelter of a giant festive kennel from only £4 per dog.
Craig Holmes, Farm Manager of Almond Valley said: "We have lots of families that come to Almond Valley with their canine companions over the festive period, so this year we thought that we would offer something a little bit different.
"‘Santa Paws’ invites visitors with their four legged friends to come and receive their own gift in the shape of a toy or a treat, as animal lovers ourselves, we felt it was only right to offer our dogs a special Christmas experience too."
Visitors can also meet Santa in his magical winter cottage in Almond Valley’s famous Christmas experiences.
The West Lothian family attraction will also run a brand new after hours winter event, The Winter Realm of the Paraffin Pixie, where guests can experience an enchanting world of twinkling lights, woodland trails and festive delights.
Tickets for Santa Paws can be bought on arrival at Almond Valley with daily admission.


--- layout: default ---
Developed a content-based “comparison shopping tool” car recommender using an approximate nearest neighbor algorithm. It is a tool to make
car hunting less of daunting endeavor for users. The shopper enters their favorite or budgeted-for car brand and model and the recommender
will provide cars with similar characteristics such as fuel economy, performance, cost and size.
Try it out for yourself by clicking on this link: Car Recommender StreamLit App
The CORD 19 research challenge dataset contains a large collection of literature on coronaviruses that are made avilable for data mining. Part of the data is 85,000+ PMC papers- the project aims to classify the papers according to their topics in alignment with WHO's Research and Development Blueprint COVID 19 Public Health Emergency of International Concern (PHEIC) research topics to tackle the spread of COVID-19. LDA is applied using Genisim's core estimation which is based on the onlineldavb.py script, by Hoffman, Blei, Bach: Online Learning for Latent Dirichlet Allocation and an estimation using an (optimized version of) collapsed Gibbs sampling from MALLET to model the topics and compare their performance.
Google's BERT pre-trained model is recognized for being one of the most powerful tools used for NLP. One incredibly useful task it can be fine-tuned to do is to classify whether a pair of passages have a high lexical overlap or not. This could be used in applications where a question-answering platform, such as stack-overflow, wishes to use machine learning to determine if the answers given to a question contain relevant context to answer it. In this project I used Tensorflow tutorial and adapted it to carry out the classification task on MS MACRO question answering dataset
The aim of this project is to Try different classification models on the provided by fake news datasets kaggle. These models can be used on various datasets for the same purpose. I have tried those same models on various similar datasets and have always scored high in terms of accuracy. The models that were used are: 1. Neural Network model with Bi-directional recurrent LSTM cell layer. Stanford's Glove-300d embeddings were used in the input layer. 2. Neural Network model with convolutional, max-pooling and recurrent/LSTM-cell layers. Stanford's Glove-300d embeddings were used in the input layer. 3. Pre-trained NNLM 128 Model (https://tfhub.dev/google/nnlm-en-dim128/2) embedding layer with dense classifier layer. 4. Naive Bayes.
The classifier determines what genre a movie is based on its script. Web-scraped scripts of movies from 3 different genres. * Romance * Horror * Fantasy These were chosen because it was deemed they would have the least overlap. Using Multinomial Naive Bayes model, accuracy acheived was 32% above the baseline model.
This project aims to assess the accuracy of a built-from-scratch CNN model and a ResNet50 pre-trained transfer learning CNN model in distinguishing leukemic B-lymphoblast cells from healthy B-lymphoid precursors. The images are microscopic images of blood smear samples for patients who are healthy and others who have been diagnosed with Leukemia.
CNN model to recognize images for either being that of dogs or cars.
The project aims to build Univariate models to forecast NASDAQ stock index’s price using Python programming language. The data and its source are first introduced and the need for such tool is explored. The target variable is set as the close stock price. The data is then is made stationary by differencing the log of the close stock price. Through time decomposition, it is determined that the data has a strong trend and weak seasonality. The data is then modeled using Average, Naïve, Simple Exponential Smoothening, Holt’s linear, Holt-Winter Seasonal, ARMA and ARIMA methods. At the end of experimenting with each model, the best one-step forecast is determined to be Holt Linear method and the best h-step predictor is ARIMA with order (3,1,4).
Created an ensemble decision tree classification algorithm that helps entrepreneurs seeking funds from crowdfunding website to predict whether their project will succeed or fail on Kickstarter. The users enter the project’s category (Film, Music, Fashion etc..), country where project is based in, dates of creation and deadline and the budget desired. I am currently in the process of apply the similar algorithm to gofundme.com and indiegogo.com order to create a comparison tool that helps users pick the right website for their project.
Predicts price of used cars for 43 brands for models between 2014-2018 using linear regression.


C L U E L E S S ~~~~~~~~~~~~~ (1995) US, 90 mins Directed by Jonathan Lynn Starring Alicia Silverstone, Dan Hedaya, Stacey Dash, Brittany Murphy, Wallace Shawn
5 Star Rating: * * * *
In Brief: An awful lot better than I thought it would be. Definitely designed to appeal to an elite taste, but it's well written, well performed and quite charming nonetheless.
Just the other week I reviewed ROMY AND MICHELLE'S HIGH SCHOOL REUNION, and this week it's CLUELESS. You might well worry about the fact I've been watching too many "chick flicks", but the main reason is it's cheaper to watch and review videos that my sister has hired than it is to pay for my own ones! So, that's my reasoning. :-) To be honest, I didn't think CLUELESS sounded particularly interesting, and I wasn't expecting a great deal from it.
I was actually pleasantly surprised with what I saw. This could easily have been a feature film version of the dreaded CLARISSA EXPLAINS IT ALL -- a rather excruciating US 'sitcom', for those of you blissfully ignorant, about an annoying all-American teen girl stereotype. One first glance the two looked startlingly similar. CLUELESS is about…yup, an all-American teen girl stereotype, living in Beverly Hills. But, mercifully, the film is a full hundred-percent less irritating and stilted than the aforementioned series, and actually quite well-written and acted. But like I said, it was treading near potentially dangerous territory. Films about airhead American teenagers who have a lot more money than brains have become something of a cliché, based on some sort of parody of American teenagers in general. It was a novelty when this whole sub-genre began (a lot inspired by BILL AND TED, perhaps?) but as with all things cinematic, over-use tends to generate boredom. Luckily Clueless is a cut above the rest, largely due to clever, sharp scripting with just the right degree of self-indulgence to draw you into the story.
That said, it's not a film that'll appeal to everyone. It's obviously targeted at teenage girls (my seventeen year old sister loves it), and I don't suppose anyone over twenty-five will get much out of the film. I'm not a girl, but I am a teenager, so I guess I fall into part of that demographic! And I did, as I said, rather enjoy the film. I've certainly been exposed to far worse in my time.
Alicia Silverstone does a marvellous job breathing charm and wit into a potentially unsympathetic role, and she's a joy to watch. Other standout performances include that of Dan Hedaya as Cher's grumpy father, who's a delight to watch (Cher: "Daddy, this is my new friend Tai…" Daddy: "Get out my chair!") and veteran character actor Wallace Shawn as Cher's lovelorn teacher.
The last twenty minutes or so get a bit too bogged-down by focussing too much Cher's love-life, forsaking the happy-go-lucky wit of the film's first hour or so, but it still remains an enjoyable, well-performed and rather endearing diversion. Worth a look, though - not to be ageist or anything - it'll probably appeal more to the younger generation.
~~~~~~~~~~~~~~ For more Film and TV Reviews check out my site! http://www.geocities.com/Hollywood/Bungalow/4960
Written and (c) by Rory B Mackay -<EMAIL_ADDRESS>The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


(Ongoing) {{totals.ongoing}} of {{totals.total}}
(Complete) {{totals.complete}} of {{totals.total}}
(Incomplete) {{totals.incomplete}} of {{totals.total}}
Are you sure you want to delete?


Education
An investment in knowledge pays the best interest. – Benjamin Franklin
Formal Education
MOOCs
Awards and Prizes
+
Badges


I was born and raise in Colombia, South America. I lived most of my life in Medellin, the second biggest city in Colombia.
I love british rock, and with some good friends, we have a rock band. We only perform in our basements!
I find knitting crochet fascinating. I really like to knit stuffies for my kids.


Ezekiel 1:15
Now as I beheld the living creatures, behold one wheel upon the earth by the living creatures, with his four faces.


Fully dynamic and interactive multi-level grouping with filtering and aggregates over 50'000
items
Each grouping level can have its own aggregates (over child rows, child groups, or all descendant rows).
Personally, this is just the coolest slickest thing I've ever seen done with DHTML grids!


UICollectionViewAdapter
open class UICollectionViewAdapter : NSObject, Adapter
An adapter for UICollectionView
.
It can be inherited to implement customized behavior or give some unimplemented
methods of delegate or dataSource.
Attention : In UIKit, if inheriting the @objc class which using generics, the delegate and dataSource are don’t work properly, so this class doesn’t use generics, and also the class inherited this class shouldn’t use generics.
-
The data to be rendered in the list UI.
Declaration
Swift
public var data: [Section]
-
A closure that to handle selection events of cell.
Declaration
Swift
open var didSelect: ((UICollectionViewAdapter.SelectionContext) -> Void)?
-
Create an adapter with initial data.
Declaration
Swift
public init(data: [Section] = [])
Parameters
data
An initial data to be rendered.
-
Returns a registration info for register each cells.
Declaration
Swift
open func cellRegistration(collectionView: UICollectionView, indexPath: IndexPath, node: CellNode) -> CellRegistration
Parameters
collectionView
A collection view to register cell.
indexPath
An index path for the cell.
node
A node representing cell.
Return Value
A registration info for each cells.
-
Returns a registration info for register each header views.
Declaration
Swift
open func supplementaryViewRegistration(forElementKind kind: String, collectionView: UICollectionView, indexPath: IndexPath, node: ViewNode) -> ViewRegistration
Parameters
kind
The kind of element for supplementary view.
collectionView
A collection view to register supplementary view.
indexPath
An index path for the supplementary view.
node
A node representing supplementary view.
Return Value
A registration info for each supplementary views.
-
Returns a node for supplementary view for arbitrary element of kind.
Declaration
Swift
open func supplementaryViewNode(forElementKind kind: String, collectionView: UICollectionView, at indexPath: IndexPath) -> ViewNode?
Parameters
kind
The kind of element for supplementary view.
collectionView
A collection view to display supplementary view.
indexPath
An index path for the supplementary view.
node
A node representing supplementary view.
Return Value
A node for supplementary view for arbitrary element of kind.
-
Return the number of sections.
Declaration
Swift
open func numberOfSections(in collectionView: UICollectionView) -> Int
-
Return the number of items in specified section.
Declaration
Swift
open func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
-
Resister and dequeue the cell at specified index path.
Declaration
Swift
open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
-
Resister and dequeue the header or footer in specified section.
Declaration
Swift
open func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView
-
Callback the selected event of cell to the
didSelect
closure.Declaration
Swift
open func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
-
The event that the cell will display in the visible rect.
Declaration
Swift
open func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath)
-
The event that the cell did left from the visible rect.
Declaration
Swift
open func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath)
-
The event that the header or footer will display in the visible rect.
Declaration
Swift
open func collectionView(_ collectionView: UICollectionView, willDisplaySupplementaryView view: UICollectionReusableView, forElementKind elementKind: String, at indexPath: IndexPath)
-
The event that the header or footer did left from the visible rect.
Declaration
Swift
open func collectionView(_ collectionView: UICollectionView, didEndDisplayingSupplementaryView view: UICollectionReusableView, forElementOfKind elementKind: String, at indexPath: IndexPath)


SIDE EVENTS
Along with our main conference schedule on September 22nd, we will have several side events, provided and presented by community members.
UNCONFERENCE
Lightning talk track - chosen by attendees
Step up and put your lightning talk on the flip chart. Attendees will vote a schedule for a side-track of unconference talks.
Got a talk idea? Send it to<EMAIL_ADDRESS>PHP DEV RADIO
The podcast for PHP
We're very happy that Michael Döhler & Claudio Zizza from PHP DEV RADIO are joining us to do some interviews and put your #PHPDD18 experience on tape.
PHP DEV RADIO is a free german podcast from PHP devs for PHP devs.
GPG SIGNING SESSION
Building a circle of trust in the community
Mr. Andreas Heigl will guide you through the process of verifying & signing GPG keys from other community members.
Use trusted GPG keys to sign your git commits, encrypt your emails or verify your identity.
PRO-TIP: You'll need your laptop with your GPG keyring to participate.

Learn. Make. Repeat.
WURSTCON
You never sausage a conference.
We will serve awesome creations of Hot-Dog after the conference.
So grab yourself a bib and post-install your require-dev package!


Applied Economics Research Institute. Data Analyst, collecting, processing and generating storyboards of historical data for the new public big data platform, Atlas of Brazilian State Project (http://www.ipea.gov.br/atlasestado/), to provide queries and analysis about civil servants, public companies, services, and organizations more feasible. Main activities consist of data engineering and analysis, capturing, cleaning and processing all sorts of content for loading into databases, through custom ETL processes to correlate the information between datasets to generate reports of exploratory data analysis. Public assets research related to how organizations and classifications of Brazilian bureaucracy are also made, creating a continuous work between research and data analysis, culminating in reports exposed to the website. A wide variety of technology shapes the project, to name a few: Python, R, Git, Jupyter Notebook, Pandas, Seaborn, Plotly, Folium, Postgis, PostgreSQL, MongoDB, and Hadoop.
System Analyst and PL/SQL Programmer, which consisted of developing database routines based on use-cases and business rules. Queries, procedures, and functions based on Oracle PL/SQL for the SINCAD Project, a system to manage public assets for the State Treasure Institution.
The integration analysis function had the main objective to propose a solution based on Service Oriented Architecture for the legacy systems of the OI Telecom Company. The research consisted in derive adapted directives on solid concepts of international telecom solutions, following the TM Forum. Activities varied from designing new architecture to creation of reference documents, all technical guides for components and integrated applications, proof of concepts of designed architecture, unity and performance tests using JMeter in all Linux environments. Database modeling for audit reports, reference data and error management. Integration and customization for Oracle solutions, like, BPEL, Service Bus, Enterprise Repository were also created.
The job consisted of different system analysis based on diverse production environments, such as VITRIA BusinessWare, Oracle ALSB, OSB, WLI, and DSP. All mentioned were integration systems from different areas, like CRM, Financial, Web Portal and others. The SLA varied from 4 to 168 continue hours to describe a solution. Great production database structure knowledge developed, creating procedures to reduce errors, and optimizing queries to prioritize activities of highest importance SLAs. Service-Oriented Architecture document proposals, such as functional, technical, data mappings, XML Schemas, and WSDLs. Developed training for the Brasilia site team. Involved learning of daily basis technologies, for at least 4 months. Close contact with the OI Contractor's team, and different areas inside Accenture.


Toggle navigation
List Note Application
Add a Note!
×
×
Input Note
Subject:
Author Name:
Message:
×
Update Note
Subject:
Author Name:
Message:


Drink Water!
Goal: 2L
Remained
0%
Select how many glasses of water that you have to drank
250ml
250ml
250ml
250ml
250ml
250ml
250ml
250ml


Plot No. 18, Shop No. A/1-0, Ground Floor, Status Plaza Building, Old Padra Road, Near Akshar Chowk, Muj Mahuda, Vadodara, Gujarat 390020<EMAIL_ADDRESS>Phone:(0265) 233 3768


The white leaderboard on the left has the overall standings. The black leaderboards on the right contain the individual team rankings for each of the problems. You may switch between the leaderboards by clicking on the problem names. You may highlight the entries for a particular team by clicking on the team name.
| Overall Standings | Variant | Problem | Problem Leaderboards |
|---|---|---|---|


public class ParticleHandler
extends java.lang.Object
| Modifier and Type | Field and Description |
|---|---|
static int |
SIZE_LARGE |
static int |
SIZE_NORMAL |
static int |
SIZE_SMALL |
| Constructor and Description |
|---|
ParticleHandler() |
| Modifier and Type | Method and Description |
|---|---|
static void |
clear()
Clear all particles
|
static void |
kill(Particle p)
Kill an individual particle
|
static void |
render(Graphic g)
Render all particles
|
static void |
spawn(int amount,
Vector position,
int size,
Color from,
Color to,
double slowdown,
double angle,
double dAngle,
double speed,
double dSpeed,
double lifetime,
double dLifetime)
Creates multiple particles at a position
|
static void |
update(double dt)
Update all particles and remove those that has expired
|
public static final int SIZE_SMALL
public static final int SIZE_NORMAL
public static final int SIZE_LARGE
public static void spawn(int amount, Vector position, int size, Color from, Color to, double slowdown, double angle, double dAngle, double speed, double dSpeed, double lifetime, double dLifetime)
amount
- of particles to createposition
- start positionsize
- size of the particlesfrom
- first color, a color is randomized between this..to
- second color, .. and this colorslowdown
- how much the speed slowdown factor is per second (under 1 yields slow down,
over yields speed up)angle
- middle angle the particles can move towards, in radiansdAngle
- how much the angle can vary in radiansspeed
- the speed of which particles movedSpeed
- the amount of which the speed can varylifetime
- the lifetime in seconds of this particledLifetime
- how much the lifetime can varypublic static void kill(Particle p)
p
- public static void update(double dt)
dt
- public static void render(Graphic g)
g
- public static void clear()


Dear {{ lab_name }} Admin,
{{ researcher_name }} has requested to join your lab, {{ lab_name }}, on Lookit. You can approve the request and set their permissions here.


{{ rp_mouseover_cash_payment_price }}
{{ rp_mouseover_service_charge }}
{{ rp_mouseover_effective_rate }}
{{ rp_mouseover_debit_rate }}
{{ rp_mouseover_interest_amount }}
{{ rp_mouseover_duration_month }}
{{ rp_mouseover_duration_month }}
{{ rp_mouseover_last_rate }}
{{ rp_mouseover_total_amount }}


Gateway
BOT
29-Oct-19 04:34 PM
[dscrd-prt] <jl777c> and as we saw with CB, getting on the wrong exchange can be very damaging
[dscrd-prt] <jl777c> i rather get on a single top 10 real exchange than on 100 fake volume exchanges
(edited)
[dscrd-prt] <cryptoclueless> i never heard of dp, cryptobridge, graviex, until I found arrr
[dscrd-prt] <cryptoclueless> finding arrr led to an exchange that could be used to purchase
[dscrd-prt] <jl777c> so the exchange didnt bring you to arrr, arrr brought you to the exchange
[dscrd-prt] <cryptoclueless> yes
[dscrd-prt] <Llama> If we build a larger community and raise volume on the exchanges that we are already on then real exchanges will be more inclined to list us
[dscrd-prt] <jl777c> how many people will lbank bring to arrr. likely less than 3
[dscrd-prt] <jl777c> we are already on CMC exchanges, there is no desperate need for any more, unless they are in the list of the 10 real volume exchanges
[dscrd-prt] <jl777c> get on the reputable media sites, start getting the bitcoin mixing crowd excited about ZatomicDEX
[dscrd-prt] <jl777c> PIRATE has limited resources, use it to dominate the trustless mixing market
[dscrd-prt] <mrlynch> i have contacted artem to get the ball rolling on arrr integration (or at least see what else is needed) in atomicdex
[dscrd-prt] <scubapanda> So perhaps Pirate won't be a store of value but 'just' a means to use atomicdex?
(edited)
[dscrd-prt] <jl777c> he is already aware of the tech side
[dscrd-prt] <mrlynch> i've been testing lightwalletd (hacky zSPV) and cli lite wallet for the past few days and the rustlang code for the lite wallet could be ported if i understood the process correctly
[dscrd-prt] <Llama> I've been leaning towards a bounty program but it's hard to get enough funds for that
[dscrd-prt] <mrlynch> (i could be very wrong though)
[dscrd-prt] <jl777c> @scubapanda assuming we succeed in making ARRR the most used coin for trustless mixing, what is the natural outcome of that
[dscrd-prt] <jl777c> when people understand that ARRR has the largest privacy set and can be atomic swapped to basically any other coin, then some percentage of the BTC mixing crowd will decide to keep some ARRR around
[dscrd-prt] <Llama> where does the BTC mixing crowd reside?
[dscrd-prt] <jl777c> no idea
[dscrd-prt] <jl777c> find them, communicate how ARRR will have the best mixing, and it is trustless
[dscrd-prt] <Llama> once its implemented, bitcointalk could be a good place to get a thread going
[dscrd-prt] <jl777c> back it up with an infographic that explains how it is much more private
[dscrd-prt] <jl777c> yes bitcointalk used to be a good place for this, not sure anymore as it has changed over the years
[dscrd-prt] <jl777c> maybe a signature campaign there might be worth exploring
[dscrd-prt] <kp> @Llama they reside in the Wasabi vs Samourai wallet beefs on twitter
[dscrd-prt] <kp> those are the main mixers in the btc community, and they fight constantly
[dscrd-prt] <jl777c> both of those have pathetically small anon sets
[dscrd-prt] <mrlynch> ZatomicDEX donations accepted @here
zs1zcvuz4gf826yp8trncj9l86a6xracrf2jk8lwz5v6xz7zntgmgahwrxw9rxu9jtthscex4aanpe
[dscrd-prt] <jl777c> someone should research the size of wasabi and samurai anon sets, compare it to ARRR
[dscrd-prt] <Oszy> ^^ this is what we should raise money for not some crap exchange
(edited)
[dscrd-prt] <scubapanda> @jl777c If ARRR very much more volatile than lets say BTC then people could just use ARRR to go through the atomicdex? Like BTC-ARRR-ETH with two swaps on the atomicdex, without actually holding it.
[dscrd-prt] <jl777c> ARRR price is volatile, but over a span of an hour it wont change that much and on average will go up as much as down
[dscrd-prt] <jl777c> but yes, you can do a BTC -> ARRR -> ETH and basically get a private BTC/ETH trade
[dscrd-prt] <jl777c> or private BTC/ANYCOIN trade
[dscrd-prt] <scubapanda> Good point
[dscrd-prt] <Llama> whoever finds the size of the anon sets let me know in DM and I'll make an infographic of sorts
[dscrd-prt] <jl777c> and if you have a stockpile of ARRR, it is even more private as the timing of the swap isnt correlated to a small window in tme
[dscrd-prt] <mrlynch> also, in regards to marketing, i have reached out to an experienced PR manager that is currently making a plan for us to tackle marketing, social media awareness, etc - it's a 2 stage approach spanning over a few months.
i didn't want to make this public until we had some results, but justin has taken over me
[dscrd-prt] <Cryptoon> Hahaha
[dscrd-prt] <Cryptoon> Channel your inner Justin to make more pumpy announcements
[dscrd-prt] <Cryptoon> !kmdtip @mrlynch 1.777
[dscrd-prt] <mrlynch> note: the PR manager is NOT justin
[dscrd-prt] <Cryptoon> To pump arrr that wouldnt completely be a bad thing offcourse
[dscrd-prt] <subjectX> Hi all
[dscrd-prt] <subjectX> I've been lurking in here for a while now and reading this conversation made me rethink a business approach.
I've been building a device for the past few months with input from some Pirate and Kmd community members and we have now decided to sell it for ARRR only for a limited period of time.
[dscrd-prt] <Llama> justin sun?
[dscrd-prt] <subjectX> It is still in testing phase and we're waiting on feedback and have a security audit in mind as well, but basically the device, Cerberus, is a UTM (unified threat management) that is easy to use by anyone. With an integrated firewall, intrusion detection system, network wide ad/tracker blocking, 1 year free VPN and a TOR port it is as easy to use as connecting it to your internet cable and then connect your devices via LAN or WiFi.
[dscrd-prt] <subjectX> I'm sorry, I'm not that familiar with crypto slang. I have an information security background
(edited)
[dscrd-prt] <mrlynch> hi @subjectX
[dscrd-prt] <subjectX> Hi
[dscrd-prt] <mrlynch> @Llama lol, no, he's been cooking something really cool
[dscrd-prt] <scubapanda> @ComputerGenie 👴👴👴 Missed the point your educational quote again. I can stop participating in these discussions if it makes you feel strong.
[dscrd-prt] <mrlynch> don't
[dscrd-prt] <ComputerGenie > My point is that the term is overused and misapplied
[dscrd-prt] <SHossain> Hello @subjectX. Welcome!
[dscrd-prt] <subjectX> Hi. Glad to be here.
[dscrd-prt] <SHossain> Nice to see you finally posted
[dscrd-prt] <ComputerGenie > yes, we need new community members
[dscrd-prt] <SHossain> subjectX been here for a while now
[dscrd-prt] <SHossain> the thing he is cooking is really nice. i'm waiting to use that soon.
[dscrd-prt] <subjectX> It's almost ready and I was thinking long and hard on a way to give back to this community and I believe the best way at this point is to sell Cerberus only for ARRR for a period of time and then open the other payment processors.
[dscrd-prt] <ComputerGenie > "new" meaning new to conversations
I'm tired of having the same 3 conversations with the same 9 people :trollface:
(edited)
[dscrd-prt] <Zafer> @SHossain hey there, how is goin
[dscrd-prt] <subjectX> Waiting to hear back from legal on order information retention as I don't want to keep that any longer than necessary, which is order processing and shipping.
[dscrd-prt] <SHossain> I'm good. Thanks @Zafer
[dscrd-prt] <SHossain> how about you?
[dscrd-prt] <Zafer> @SHossain thanks bro, normal mood, just monitoring btc, so creepy
[dscrd-prt] <ComputerGenie > so....
[dscrd-prt] <ComputerGenie > wen polo?
[dscrd-prt] <kp> speaking of polo, justin sun bought it
[dscrd-prt] <kp>
[dscrd-prt] <SHossain> i stopped looking at CMC long time ago
[dscrd-prt] <mrlynch> wen polo??
[dscrd-prt] <SHossain> you wont have peace of mind if you keep looking at prices
[dscrd-prt] <SHossain> wen ARRR $10?
(edited)
[dscrd-prt] <SHossain>
[dscrd-prt] <ComputerGenie > why ' ' @mrlynch ?
It's on the list
[dscrd-prt] <mrlynch> is polo still at thing?
[dscrd-prt] <ComputerGenie > it would seem so
[dscrd-prt] <Zafer> when bakkt?
[dscrd-prt] <ComputerGenie > doesn't understand whatever language that is (Tagalog?)
(edited)
[dscrd-prt] <mrlynch> pirateSV
[dscrd-prt] <SHossain> raise funds, help developing ZatomicDEX. i believe you don't need anything else. when that is ready, i guess ARRR can be the highest liquidity on Z/atomicDEX
(edited)
[dscrd-prt] <ComputerGenie > longs for Z/atomicDEX
[dscrd-prt] <mrlynch> donation address for that is pinned
[dscrd-prt] <mrlynch> we only accept ARRR, so if you have BTC feel free to exchange on tradeogre
[dscrd-prt] <kp> how about we use the ARRR we raised for the exchange airdrop that got cancelled?
[dscrd-prt] <Zafer> is't better altsbit?
[dscrd-prt] <ComputerGenie > as far as hot wallets, my WLC wallet holds more value than my BTC wallet
[dscrd-prt] <jl777c> @mrlynch as the Z bounty grows, please post the total when it gains some significant amounts, i think if we can get it to 300,000 ARRR we could see a version in testing early next year, or maybe a bit sooner
[dscrd-prt] <mrlynch> of course. i can post weekly/daily updates regardless of amount
[dscrd-prt] <jl777c> we can make it a 150000 bounty on completion, with all amounts above that a bonus if it is completed by Q1 2020
[dscrd-prt] <mrlynch> wow.. looks like we already have close to 80k ARRR.. thank you, whoever donated!
(edited)
[dscrd-prt] <SHossain> nice
[dscrd-prt] <Flint> What about TradeOgre?
[dscrd-prt] <SHossain> is that a top 10 exchange with real volume?


Hello, and welcome to our site.
Click me to see a string
Click to see a list of the players
Click me to see the weather
Click me to log in
Click me to register


Class Agent
Extends
Element.
Defined in: agent.js.
| Constructor Attributes | Constructor Name and Description |
|---|---|
|
Agent(opt_options)
Creates a new Agent.
|
| Method Attributes | Method Name and Description |
|---|---|
|
align(elements)
Loops through a passed elements array and calculates a force to apply
to align with all elements.
|
|
|
applyForce(force)
Applies a force to this object's acceleration.
|
|
|
attract(attractor)
Calculates a force to apply to simulate attraction on an object.
|
|
|
checkCameraEdges(world)
Moves the world in the opposite direction of the Camera's controlObj.
|
|
|
checkWorldEdges(world)
Determines if this object is outside the world bounds.
|
|
|
cohesion(elements)
Loops through a passed elements array and calculates a force to apply
to stay close to all elements.
|
|
|
drag(target)
Calculates a force to apply to simulate drag on an object.
|
|
|
flee(target)
Calculates a force to apply to flee a target.
|
|
|
flock(elements)
Bundles flocking behaviors (separate, align, cohesion) into one call.
|
|
|
follow(target)
Calculates a steering force to apply to an object following another object.
|
|
|
getLocation(type)
Returns this object's location.
|
|
|
getVelocity(type)
Returns this object's velocity.
|
|
|
isInside(container)
Determines if this object is inside another.
|
|
|
seek(target)
Calculates a steering force to apply to an object seeking another object.
|
|
|
separate(elements)
Loops through a passed elements array and calculates a force to apply
to avoid all elements.
|
|
|
step()
Called every frame, step() updates the instance's properties.
|
Class Detail
Agent(opt_options)
Creates a new Agent.
Agents are autonomous objects affected by World forces (gravity, wind) and Proximity forces (Attractors, Repellers, Liquid).
Because their primary purpose is to navigate their World, they carry navigational properties like 'avoidEdges',
'maxSteeringForce' or 'turningRadius' which can be manipulated to adjust their observed behavior. They can also carry
Sensors which react to Stimuli and return information about the World.
- Parameters:
- {Object} opt_options Optional
- Agent options.
- {number} opt_options.mass Optional, Default: 10
- Mass
- {number} opt_options.maxSpeed Optional, Default: 10
- Maximum speed
- {number} opt_options.minSpeed Optional, Default: 0
- Minimum speed
- {number} opt_options.motorSpeed Optional, Default: 2
- Motor speed
- {number} opt_options.lifespan Optional, Default: -1
- Life span. Set to -1 to live forever.
- {number} opt_options.offsetDistance Optional, Default: 30
- The distance from the center of the agent's parent.
- {number} opt_options.offsetAngle Optional, Default: 30
- The angle of rotation around the parent carrying the agent.
- {boolean} opt_options.pointToDirection Optional, Default: true
- If true, object will point in the direction it's moving.
- {boolean} opt_options.followMouse Optional, Default: false
- If true, object will follow mouse.
- {boolean} opt_options.seekTarget Optional, Default: null
- An object to seek.
- {boolean} opt_options.isStatic Optional, Default: false
- If true, object will not move.
- {boolean} opt_options.checkEdges Optional, Default: true
- Set to true to check the object's location against the world's bounds.
- {boolean} opt_options.wrapEdges Optional, Default: false
- Set to true to set the object's location to the opposite side of the world if the object moves outside the world's bounds.
- {boolean} opt_options.avoidEdges Optional, Default: false
- Set to true to calculate a steering force away from the world's bounds.
- {number} opt_options.avoidEdgesStrength Optional, Default: 200
- Sets the strength of the steering force when avoidEdges = true.
- {number} opt_options.bounciness Optional, Default: 0.75
- Set the strength of the rebound when an object is outside the world's bounds and wrapEdges = false.
- {number} opt_options.maxSteeringForce Optional, Default: 10
- Set the maximum strength of any steering force.
- {number} opt_options.turningRadius Optional, Default: 60
- Used to calculate steering force with key control.
- {number} opt_options.thrust Optional, Default: 5
- Used to apply forward motion with key control.
- {boolean} opt_options.flocking Optional, Default: false
- Set to true to apply flocking forces to this object.
- {number} opt_options.desiredSeparation Optional, Default: Twice the object's default width
- Sets the desired separation from other objects when flocking = true.
- {number} opt_options.separateStrength Optional, Default: 1
- The strength of the force to apply to separating when flocking = true.
- {number} opt_options.alignStrength Optional, Default: 1
- The strength of the force to apply to aligning when flocking = true.
- {number} opt_options.cohesionStrength Optional, Default: 1
- The strength of the force to apply to cohesion when flocking = true.
- {Object} opt_options.flowField Optional, Default: null
- If a flow field is set, object will use it to apply a force.
- {function} opt_options.beforeStep Optional, Default: ''
- A function to run before the step() function.
- {function} opt_options.afterStep Optional, Default: ''
- A function to run after the step() function.
Method Detail
{Object}
align(elements)
Loops through a passed elements array and calculates a force to apply
to align with all elements.
- Parameters:
- {array} elements
- An array of Flora elements.
- Returns:
- {Object} A force to apply.
applyForce(force)
Applies a force to this object's acceleration.
- Parameters:
- {Object} force
- The force to be applied (expressed as a vector).
{Object}
attract(attractor)
Calculates a force to apply to simulate attraction on an object.
- Parameters:
- {Object} attractor
- The attracting object.
- Returns:
- {Object} A force to apply.
{boolean}
checkCameraEdges(world)
Moves the world in the opposite direction of the Camera's controlObj.
- Parameters:
- {Object} world
- The world object.
- Returns:
- {boolean} Returns true if the object is outside the world.
{boolean}
checkWorldEdges(world)
Determines if this object is outside the world bounds.
- Parameters:
- {Object} world
- The world object.
- Returns:
- {boolean} Returns true if the object is outside the world.
{Object}
cohesion(elements)
Loops through a passed elements array and calculates a force to apply
to stay close to all elements.
- Parameters:
- {array} elements
- An array of Flora elements.
- Returns:
- {Object} A force to apply.
{Object}
drag(target)
Calculates a force to apply to simulate drag on an object.
- Parameters:
- {Object} target
- The object that is applying the drag force.
- Returns:
- {Object} A force to apply.
{Object}
flee(target)
Calculates a force to apply to flee a target. The force is the inverse
of the object's maximum speed.
- Parameters:
- {Object} target
- The object to flee from.
- Returns:
- {Object} A force to apply.
flock(elements)
Bundles flocking behaviors (separate, align, cohesion) into one call.
- Parameters:
- elements
{Object}
follow(target)
Calculates a steering force to apply to an object following another object.
- Parameters:
- {Object} target
- The object to follow.
- Returns:
- {Object} The force to apply.
{boolean}
getLocation(type)
Returns this object's location.
- Parameters:
- {string} type Optional
- If no type is supplied, returns a clone of this object's location. Accepts 'x', 'y' to return their respective values.
- Returns:
- {boolean} Returns true if the object is outside the world.
{boolean}
getVelocity(type)
Returns this object's velocity.
- Parameters:
- {string} type Optional
- If no type is supplied, returns a clone of this object's velocity. Accepts 'x', 'y' to return their respective values.
- Returns:
- {boolean} Returns true if the object is outside the world.
{boolean}
isInside(container)
Determines if this object is inside another.
- Parameters:
- {Object} container
- The containing object.
- Returns:
- {boolean} Returns true if the object is inside the container.
{Object}
seek(target)
Calculates a steering force to apply to an object seeking another object.
- Parameters:
- {Object} target
- The object to seek.
- Returns:
- {Object} The force to apply.
{Object}
separate(elements)
Loops through a passed elements array and calculates a force to apply
to avoid all elements.
- Parameters:
- {array} elements
- An array of Flora elements.
- Returns:
- {Object} A force to apply.
step()
Called every frame, step() updates the instance's properties.


Please contribute with better data and add your favourite mountainbike trails to openstreetmap! If you haven't contributed to Openstreetmap before start here.
Site and custom style sheet is developed by zvenzzon.
Update interval: ~monthly or worse =)
Software used:
License information:
mtbmap layer is a derived work from openstreetmap data. (C) Openstreetmap Contributors. More information can be found under Copyright information.
stefanocudini-leaflet-gps (C) Stefano Cudini
shramov-leaflet-plugins Copyright (c) 2011-2015, Pavel Shramov, Bruno Bergot. Full license information
Map Legend:
| Trail Wide | |
| Trail Normal | |
| Trail Minor | |
| Trail Bad | |
| Track | |
| Unpaved road | |
| MTB Beginner (0) | |
| MTB Basic (1) | |
| MTB Advanced (2) | |
| MTB Technical (3) | |
| MTB Route | |
| Foot Route | |
| Cycleway | |
| Foot/Pedestrian way | |
| Bridleway | |
| High speed road | |
| Major road | |
| Paved road | |
| Unknown road | |
| Railway | |
| Cliff | |
| Water | |
| Forest | |
| Low vegetation | |
| Grass | |
| Recreation | |
| Farmland | |
| Protected nature | |
| Residential | |
| Industrial | |
| Commercial | |
| Other landuse |
Social:
The operation of this site requires a lot of time, dedicated rendering computer hardware, hard disks, electricity, bandwidth, domain name registration etc. Please donate so the site can be kept online. Thanks!


We offer a variety of menu options to customize any event with your own
personal selections. Just ask for us, set up an appointment to help plan your event and leave the rest to us. We personalize your event.
Whether it is a graduation party, formal wedding, holiday party, or back yard picnic,
we can do it all just give us a call and we'll assist you with the rest. Zaika catering can provide you with delivery or you can simply pick up your order and go.


{% extends "template.html" %} {% block content %}
Form to add a new member to the training
Add a new member:
{% endblock %}


A B C D E F G H I L M N O P Q R S T U V W
All Classes All Packages
All Classes All Packages
All Classes All Packages
S
- search_algorithm - package search_algorithm
- searchAlgorithm(long, long, Map<WeightedPoint, WeightedPoint>) - Method in class search_algorithm.AnalysableAlgorithm
-
Implementation of the search algorithm During this call handleReportWriting needs to be called with given parameters to get rest of analysis done.
- searchAlgorithm(long, long, Map<WeightedPoint, WeightedPoint>) - Method in class search_algorithm.AStar
-
Runs A* with a heap and uses double[][] for upkeeping current know distances.
- searchAlgorithm(long, long, Map<WeightedPoint, WeightedPoint>) - Method in class search_algorithm.BreathSearch
-
Runs breath search by adding neighbours of start to que and comparing them to target node in order.
- searchAlgorithm(long, long, Map<WeightedPoint, WeightedPoint>) - Method in class search_algorithm.DepthSearch
-
Runs depth search by using stack and adding neighbours to it and then comparing popped neightbour wit target.
- searchAlgorithm(long, long, Map<WeightedPoint, WeightedPoint>) - Method in class search_algorithm.Dijkstra
-
Runs CustomDijkstra with a heap and uses double[][] for upkeeping current know distances.
- setAlgorithmImplementationType(String) - Method in class model.report.ReportMeta
- setAlgorithmMap(Map<AlgorithmCodeKey, AnalysableAlgorithm>) - Method in class app.App
-
setter for testing
- setAlgorithmName(String) - Method in class model.report.ReportMeta
- setAnalysisInspector(AnalysisInspector) - Method in class app.App
-
setter for testing
- setCurrentMap(WebMap) - Method in class app.App
-
setter for testing
- setDistance(Point, double) - Method in class model.structure.custom_structure.DistanceMapAsA2DTable
-
To keep it lightweight no error checks are done.
- setDistance(Point, double) - Method in class model.structure.custom_structure.DistanceMapAsASingleTable
-
To keep it lightweight no error checks are done.
- setDistance(Point, double) - Method in interface model.structure.structure_interface.DistanceMap
- setMap(int[][]) - Method in class model.web.WebMap
- setMapClean(WebMap) - Method in class search_algorithm.AnalysableAlgorithm
-
Directory is based on map name as well and gets cleaned when a map is set for upkeepin reporting structure.
- setMapGenerators(Map<String, MapGenerator>) - Method in class app.App
-
setter for testing
- setMapLocator(RootFileLister) - Method in class map_generator.MapGeneratorFromFiles
-
testing setter
- setName(String) - Method in class model.web.WebMap
- setReportFilePath(String) - Method in class search_algorithm.AnalysableAlgorithm
-
for testing
- setScanner(Scanner) - Method in class app.App
-
setter for testing
- setTestMaxSteps(Long) - Method in class model.report.ReportMeta
- setTestPathWeight(Double) - Method in class model.report.ReportMeta
- setTestSpace(Double) - Method in class model.report.ReportMeta
- setTestTime(Double) - Method in class model.report.ReportMeta
- setTestUsedSteps(Double) - Method in class model.report.ReportMeta
- setTileStart(int, int) - Method in class model.web.WebMap
-
Sets starting coordinates.
- setTileTarget(int, int) - Method in class model.web.WebMap
-
Sets target coordinates.
- setValueOf(ReportCodeKey, String) - Method in class model.report.Report
- SPACE_USED - model.report.ReportCodeKey
- Stack<T> - Interface in model.structure.structure_interface
-
Stack interface.
- StackType - Enum in model.structure.structure_type_enum
-
Types of stacks used in search algorithms
- START_LOCATION - search_algorithm.NodeHandlingType
- STATISTICS - file_operations.common.FileClassification
- StatisticTemplateKey - Enum in file_operations.common
-
Keys to overview-template for replacement Used by AnalysisOverviewWriter
- STEPS_USED - model.report.ReportCodeKey
- system_tools - package system_tools
- SystemSpecReader - Class in system_tools
-
Helper to get information on some system specifications
- SystemSpecReader() - Constructor for class system_tools.SystemSpecReader
-
Initializes few internal helpers Not really testable since results vary by hardware / os / java
All Classes All Packages


JavaScript Object Notation (aka JSON) is a very popular alternative to XML for transmitting data to the web browser. Flexjson is a lightweight library for serializing and deserializing Java objects into and from JSON. What's different about Flexjson is it's control over what gets serialized allowing both deep and shallow copies of objects. Most JSON serializers mimic object serialization libraries and try to serialize the entire object graph from the object being turned into JSON. This causes problems when you want a connected object model in your server, but you can't send that object model to the client because the serialization library will try to send the entire object graph. This makes it very hard to create object oriented models and serialize pieces of that model to the client without sending everything. Other JSON libraries require you to create a lot of boiler plate code to translate your object representation into a JSON object. In this regard I shouldn't have to explain myself, but to keep it short let's me just say I hate boiler plate translation code! Flexjson tries to solve both of these problems by offering a higher level API or dare I say DSL for specifying your intent.
In order to explore Flexjson we will be using the following model. Let's say we're building a PIM or contact management application. Here are some classes we might see in an application like this along with the relationships between them.
In the above diagram you can see Person has many instances of Phone, and has many Addresses. While this is a trival object model it will help us demostrate the ideas behind Flexjson.
Serialization
The Basics
Flexjson takes a different approach allowing you to control the depth to which it will serialize. It's very similiar in concept to lazy loading in Hibernate which allows you to have a connected object model, but control what objects are loaded out of your database for performance. Let's look at a simple example first to get a feel for how the library works. Say we are serializing an instance of Person. We might do the following:
public String doSomething( Object arg1, ... ) { Person p = ...load a person...; JSONSerializer serializer = new JSONSerializer(); return serializer.serialize( p ); }
The above would produce the following output:
{ "class": "Person", "name": "William Shakespeare", "birthday": -12802392000000, "nickname": "Bill" }
Working With Includes
Looks pretty much like you'd expect. However, our Person object contains more fields than name, birthday, and nickname so what happened to phoneNumbers, and addresses? By default Flexjson serializes the immediate fields of that object. It's just a shallow representation of the object. All collections are not serialized by default. Or said another way any one to many, and many to many relationships are not serizialized by default. Object references are serialized by default. That being many to one and one to one relationships will be serialized by default. This is consistent with other libraries like hibernate and JPA which will eagerly load these relationships by default. But, let's say we wanted to include the phoneNumbers field in our output then we could do the following:
public String doSomething( Object arg1, ... ) { Person p = ...load a person...; return new JSONSerializer().include("phoneNumbers").serialize(p); }
In this example, we're telling the serializer to include the following fields from the target object. Collections are serialized in full including the shallow copy of the objects they contain. So in our example, Person has a List field called phoneNumbers, and that List contains Phone instances. This means Flexjson will send a shallow copy of Person, the List of phoneNumbers, and a shallow copy of each Phone instance within the List. So the output might look like:
{ "class": "Person", "name": "William Shakespeare", "birthday": -12802392000000, "nickname": "Bill" "phoneNumbers": [ { "class": "Phone", "name": "cell", "number": "555-123-4567" }, { "class": "Phone", "name": "home", "number": "555-987-6543" }, { "class": "Phone", "name": "work", "number": "555-678-3542" } ] }
Getting the hang of it? It's pretty simple. If you wanted to send both phoneNumbers and addresses you can call include method twice, or you can include two parameters to the include method using Java's new vararg feature. Personally I prefer the later since I think it makes it shorter and easier to read. But, it's your choice.
public String doSomething( Object arg1, ... ) { Person p = ...load a person...; return new JSONSerializer().include("phoneNumbers", "addresses").serialize(p); }
So in this case we'll only get the street, city, and state, but not the zipcode because that is an object reference. It's an easy fix using the dot notation. Here is an example to include the zipcode with each Address instance.
public String doSomething( Object arg1, ... ) { Person p = ...load a person...; return new JSONSerializer().include("phoneNumbers", "addresses.zipcode").serialize(p); }
Flexjson is smart enough to know you mean the object contained with this collection and not the collection itself. It's also smart enough to know that the addresses reference has to be included in order to include zipcode so you don't have to specify it twice. You can use the dot notation to trace over your object graph very easily.
More on Includes
There is an alternate form of serialize() method that allows you to specify an outer object for collections. There are some javascript libraries like EXTJS (previously known as YUI-EXT) that require this for their JSON data models. However, I haven't found any JSON libraries that offer this type of serialization. Here is an example:
public String getPeople( Object arg1, ... ) { List people = ...load a person...; return new JSONSerializer().include("phoneNumbers").serialize("people", people); }
The resulting JSON would look like the following:
{ "people" : [ { "class": "Person", "name": "Warren Buffet", "birthday": -1241467200000, "nickname": "Oracle of Omaha", "phonNumbers" : [ ... ], }, { "class": "Person", "name": "Steven Jobs", "birthday": -468702000000, "nickname": "Steve", "phonNumbers" : [ ... ], } ] }
Working With Excludes
Not only can you include, but you can specify it in terms of exclude as well. The exclude() method allows you to exclude certain fields from serilization. This can come in handy if you have special fields that you don't want sent to the client like passwords, or secret data that should remain on the server.
public String doSomething( Object arg1, ... ) { User u = ...load a user...; return new JSONSerializer().exclude("password").include("hobbies").serialize(p); }
Using dot notation with exludes has a subtle difference in it's use when compared with includes. If you exclude a
nested field it implies that the rest of the parent object is included. So if I say
exclude("head.rightEye.retinalScan")
.
The retinalScan member of rightEye field will be excluded, but both rightEye and head field will be included.
The reason is in order to exclude retinalScan field you have to include the rightEye member. If you didn't then
it doesn't change anything because retinalScan wasn't going to be included in the first place. Said another way
it's only the last field that is excluded all other parent fields are included.
Excluding Using Annotations
Always having to do your excludes in this manner can be cumbersome especially if you always intend something to be excluded or included. Flexjson provides a way to express this using annotations. The JSON annotation can be used to mark a field in the object as included by default. Annotations can be placed on the methods or fields. A good example of this might be the Address object that contains a reference to Zipcode object. Since Zipcode is an integral part of every Address (in the US) then it might make more sense for us to default this with the annotation. So in our Address object we could do the following:
public class Address { private String name; private String street; private String city; private String state; private Zipcode zipcode; @JSON public Zipcode getZipcode() { } }
Annotations can improve your security so that fields that shouldn't be sent over the wire ever can be fixed in one place. That way you keep your code more DRY, and that prevents accidental security flaws. Consider if we store the a hashed version of a password in our User object.
public class User { private String login; private String hashedPassword; private Date lastLogin; @JSON(include=false) public String getHashedPassword() { } }
Code Gone Wildcard
In 1.5 you can now specify wildcards in your include() and exclude() method calls. This makes it easy to include or exclude several fields very easily. It's very common for people to want to remove the class attribute written to the stream. With wildcards it becomes very easy to accomplish this. For example:
public String doSomething( Object arg1, ... ) { User u = ...load a user...; return new JSONSerializer().exclude("*.class").serialize(p); }
Any path ending with class will now be excluded from the output. Wildcards match any depth you specify. So it doesn't matter how deep your object path has gotten. An exclude of *.class will match to any path depth. So if flexjson is serializing the field with path of "foo.bar.class" the "*" in "*.class" will match foo.bar.
Wildcards do not expand the depth to which you are serializing in most cases. They only operate in the depth you have specified. That means if you specify *.list, paths like foo.list would be serialized, but foo.bar.list would not. If you wanted foo.bar.list you would need have an include for foo.bar from another statement. Same goes for things like *.class. Every object has a class member because of Object.getClass(). However, *.class won't extend the depth of your serialization. There are cases where serialization depth will be expanded. You have to be careful when doing specifying wildcards with recursive structures. If you had a tree structure and did an include on *.children it will expand the depth of your serialization all the way. The other case where wildcards will expand your serialization is "*". That is the same as doing a deep serialization so be careful using it.
Order of Evaluation
Now that we've discussed includes and excludes let's talk about order of evaluation. What happens if I include a field then I exclude that same field later? What will Flexjson do? The answer is includes and excludes are evaluated in order they were added. This is important with the introduction of wildcards. Say I want to serialize just two fields of an object. I can do the following:
public String doSomething( Object arg1, ... ) { User u = ...load a user...; return new JSONSerializer().include("username").exclude("*").serialize(p); }
The above code would serialize just the username field from the user object, but it would exclude all other fields. If I reversed the order of the include and exclude calls it would exclude all of the fields, and the username field wouldn't be included? Why is that? That's because internally flexjson would have a list of expressions. Think of it like a list where the order is the following:
[ "*", "username" ];
Flexjson would visit each field in the User object, and evaluate it against all of the rules in the list. It starts the head of the list and stops once it finds the first match. In this case "*" would match all fields of User object, and it would exclude it thus never reaching the "username" entry.
Direct Serialization To a Stream
For simplicity Flexjson allows you to work with String objects, but but it's more efficient to work directly with the stream we want to send the json data over. You can supply a java.io.Writer as the destination for the json output. Now we can go directly to the stream bypassing the conversion to String. Here is a simple example:
new JSONSerializer().serialize(myObject, response.getPrintWriter());This method returns void so there is no need to handle the return type.
Deep Serialization
In 1.2 there was a new feature added to perform a deep serialization of the object using the deepSerialize() method. As with serialize() method deepSerialize() method will use includes, excludes, and annotations to figure out what you want sent. However, includes are generally redundant except in the case where you want override an excluding annotation on a field. Deep serialization will not serialize cycles in your graph so if you have a bi directional relationship say parent has a child and child has a parent. The back reference from child to parent won't be included in the JSON output. This is the same for shallow serialization as well. Here is a quick example:
public String doSomething( Object arg1, ... ) { Person p = ...load a person...; return new JSONSerializer().deepSerialize(p); // send the entire graph starting at person }
Deep serialization should be used sparingly, and reserved for only cases where you really understand what is being serialized. Deep serialization can send a lot more data that you anticipated if you use it frivolously.
Transformers More Than Meets the Eye
Flexjson 2.0 has been completely rewritten to make Transformers central to how processing Java into JSON works. With this core restructuring, Transformers have much more flexibility and power.
What is a transformer?
Transformers are classes that are used to handle the actual transformation of Java objects into JSON.
How to configure a transformer
There are 2 ways you can configure a transformer. You can specify the property name (dot notation is respected) or you can specify a class.
Configuring a Transformer Using a String to Identify a Property
This will only apply the transformer to the specified property/properties identified by the String varargs that are provided after the first parameter on the tranform method.
JSONSerializer serializer = new JSONSerializer() .transform(new BasicDateTransformer(), "person.birthday");
or you can specify as many more properties to be handled by this Transformer as you want.
JSONSerializer serializer = new JSONSerializer() .transform(new BasicDateTransformer(), "person.birthday", "person.hireDate");
Configuring a Transformer Using A Class Identifier
Using a class will apply the transformer to any object of that type.
JSONSerializer serializer = new JSONSerializer() .transform(new BasicDateTransformer(), Date.class);
Using String Identifiers with Class Identifiers
It should be noted that there is a precedence to the use of combined transformer identifiers. The String property identifiers will override the class identifiers.
JSONSerializer serializer = new JSONSerializer() .transform(new BasicDateTransformer(), Date.class) .transform(new DateTransformer("MM/dd/yyyy"), "person.birthday");
The property identified by "person.birthday" would use the DateTransformer only. Any other Date objects would use the BasicDateTransformer.
Overriding Flexjson default Transformers
It is possible to override the default Transformers Flexjson uses. If you wanted to override the default StringTransformer that Flexjson uses for Strings you could write configure in the following manner:
JSONSerializer serializer = new JSONSerializer() .transform(new MyCustomStringTransformer(), String.class);
Basic Transformer
Flexjson comes with several basic Transformers that are used to meet the majority of your Java-to-JSON needs.
Flexjson comes with the following default Transformers:
- ArrayTransformer - used to produce JSON from a Java array
- BasicDateTransformer - will translate the value of Date object's getTime() into JSON
- BooleanTransformer - will translate a primitive boolean or a Boolean object into JSON
- CharacterTransformer - will translate a primitive char or a Character object into JSON
- ClassTransformer - will translate a class the value of the Class object's getName() into JSON
- DateTransformer - will translate a Date objet into JSON based on a date pattern that is passed into the constructor of the DateTransformer
- EnumTransformer - will translate then Enum's getName() into JSON
- HibernateTransformer - will properly return the correct object when the JSON translation encounters a org.hibernate.proxy.HibernateProxy
- HtmlEncoderTransformer - encodes a string for display in HTML. This transformer will not work on HTML because it will encode < and >. The value is written to JSON output.
- IterableTransformer - will translate a List, Set, Collection, Queue, etc... into JSON
- MapTransformer - will translate a Map into JSON
- NullTransformer - will translate null values into JSON
- NumberTransformer - will translate BigDecimal, BigInteger, Byte, Double, Float, Integer, Long, Short, etc.. into JSON
- ObjectTransformer - this Transformer works more as a distribution point and passes oebjects on to their more specific type and path transformers to produce the appropriate JSON.
- StringTransformer - will translate a String object to JSON
How Transformers Work
In order to understand the role that Transformers play it is important for us to understand what the JSONSerializer and the JSONContext do as well.
JSONSerializer
The JSONSerializer works as a configuration object. Once serialize/deepSerialize is called on the JSONSerializer it retrieves a ThreadLocal version of a JSONContext and configures it for use specific to the calling Thread.
JSONContext
The JSONContext facilitates several aspects of the transformation process and keeps the Transformers as simple as possible.
The JSONContext performs the following major functions:
- Initializes the transformation process.
- Handles the traversal of the Java Objects being translated.
- Calls the correct Transformer for the object being translated.
- Hosts and outputs the resulting JSON
- Maintainins state and information about the object(s) being transformed.
- Provides common utility methods for tailoring the JSON output.
Transformers
In the end the Transfomer is responsible for deciding how to translate the passed in object to JSON, making the appropriate calls on the JSONContext object to output the JSON, and/or passing the object along the transformation process.
Simple Transfomer
The StringTransformer provides a simple example of a Transformer.
package flexjson.transformer; public class StringTransformer extends AbstractTransformer { public void transform(Object object) { getContext().writeQuoted((String) object); } }
In the StringTranformer the Object passed in is a String which gets quoted by calling a method (getContext().writeQuoted()) on the JSONContext. The JSONContext takes care of all the string escaping that needs to occur. Pretty simple eh?
As a side note you may notice that the Transformer extends AbstractTranformer. It is recommended that custom transformers extend the AbstractTransformer although it is not required. Feel free to take a look in the AbstractTransformer to see what it does. There isn't much to it.
Transforming a Collection
In this example we'll take a look at the IterableTransformer which transforms collections.
public class IterableTransformer extends AbstractTransformer { public void transform(Object object) { Iterable iterable = (Iterable) object; TypeContext typeContext = getContext().writeOpenArray(); for (Object item : iterable) { if (!typeContext.isFirst()) getContext().writeComma(); typeContext.setFirst(false); getContext().transform(item); } getContext().writeCloseArray(); } }
You will notice that this transformer makes use of a TypeContext. The TypeContext is just a way to keep track of whether the current context is an ARRAY (Collection or Array) or a BASIC (Any Object other than Collection or Array) object. Additional information on the current object context is also held in the TypeContext. Behind the scenes in the JSONContext.writeOpenArray() method the JSONContext creates the TypeContext as BasicType.ARRAY, pushes it on the typeContextStack, and then returns the type context from the writeOpenArray() method. This context is then made available to all downstream transformations via the getContext().peekTypeContext() method.
Custom Transformer using Inline functionality
This example of the FlatDateTransformer (found in the Flexjson unit tests) is more complex than the last. What it illustrates is the flexibility that Transformers have when needing to meet various requirements.
Let's take some time to understand what the FlatDateTransformer does and then we'll discuss how it does it. In this particular case a java.util.Date is transformed into 3 separate properties on a JSON object. If we were to pass a Date object into this transformer the resulting JSON would look like:
{ "month":11, "day":13, "year":2007 }
This transformer "inlines" the Date properties with the other properties of the current object. For example, if I had an object named Task with a Date property (named doOn) along side name and description this Transformer would render the date inline with the other properties when the JSON is generated.
public class Task { private String name; private String description; private Date doOn; // setter/getters left out for brevity }
Would result in:
{ "name":"some name", "description":"some description", "doOnMonth":11, "doOnDay":13, "doOnYear":2007 }
As you can see the doOnMonth, doOnDay, and doOnYear are next to the other properties rather than in a nested JSON object. You may also notice that each one was automatically prefixed with the Date properties' name of doOn. This brings me to the prefix property that can be passed into the FlatDateTransformer. The prefix allows us to alter the generated property name to whatever we like when inlining. Lets look at our Task example again but this time we'll provide a prefix.
public class Task { private String name; private String description; private Date doOn; // setter/getters left out for brevity }
If we did not specify a prefix in the JSONSerializer it automatically picks up the name of the property being transformed in Java and uses it to prefix the month, day, and year JSON properties. However, if we were to specify our own in the JSONSerializer it would look different.
JSONSerializer serializer = new JSONSerializer() .transform(new FlatDateTransformer("shazam"), "doOn"); Task task = new Task(); // set properties serializer.deepSerialize(task);
would result in:
{ "name":"some name", "description":"some description", "shazamMonth":11, "shazamDay":13, "shazamYear":2007 }
In summary the FlatDateTransformer is a clear example on how to make use of the inline functionality to take greater control over the generated JSON. In order to accomplish this the FlatDateTransformer extends the AbstractTransformer and overrides the isInline method.
@Override public Boolean isInline() { return Boolean.TRUE; }
If isInline() is overridden and returns Boolean.TRUE it tells the JSONContext that we will be handling the writing of our own property name. This allows us full control over the generated JSON instead of relying on the standard reflection to lookup the property name or key name and use it as the JSON property name. As a result we need to handle every aspect of the JSON generation for this object now.
Once the transform() method is called on the FlatDateTransformer it first checks to see if a TypeContext exists. If a type context exists it checks to see if a property name exists on the TypeContext and sets it. Afterwards it checks to see if a prefix has been specified. If a prefix does not exist it is replaced with the propertyName. Otherwise prefix is left as is.
TypeContext typeContext = getContext().peekTypeContext(); String propertyName = typeContext != null ? typeContext.getPropertyName() : ""; if(prefix.trim().equals("")) prefix = propertyName;
Afterwards the TypeContext is checked. If the JSONContext does not yet contain a JSONContext or is not currently in a BasicType that is equal to BasicType.OBJECT then we will need to start writing a new JSON Object. Hence we call the writeOpenObject() method on the JSONContext. This creates a TypeContext that has a BasicType of OBJECT inside the writeOpenObject() method and pushes it onto the context stack in the JSONContext. If a TypeContext with a BasicType of OBJECT already exists on the stack then the properties are output as part of the currently generating JSON object.
if (typeContext == null || typeContext.getBasicType() != BasicType.OBJECT) { typeContext = getContext().writeOpenObject(); setContext = true; }
After this we just need to generate the JSON output.
Date date = (Date) o; Calendar c = Calendar.getInstance(); c.setTime(date); if (!typeContext.isFirst()) getContext().writeComma(); typeContext.setFirst(false); getContext().writeName(fieldName("Month")); getContext().transform(c.get(Calendar.MONTH)); getContext().writeComma(); getContext().writeName(fieldName("Day")); getContext().transform(c.get(Calendar.DAY_OF_MONTH)); getContext().writeComma(); getContext().writeName(fieldName("Year")); getContext().transform(c.get(Calendar.YEAR));
All of this is fairly self explanatory. But, I'll draw special attention to the use of typeContext.isFirst(). This is used to check if the currently generating property is the first one to be created for this JSON object. If it is then we avoid writing the comma and then immediately set the typeContext.setFirst(false) so that all subsequent property creation for this JSON object prefixes a comma. If we did not perform the isFirst check we could easily wind up with JSON that looks like this:
{,"month":11,"day":13,"year":2007} ^ notice the invalid comma at the beginning of the JSON
Finally, we close our JSON Object by checking if we created the TypeContext in this transformer.
if (setContext) { getContext().writeCloseObject(); }
Here is the full source for the FlatDateTransformer:
public class FlatDateTransformer extends AbstractTransformer { String prefix = ""; public FlatDateTransformer(String prefix) { this.prefix = prefix; } public void transform(Object o) { boolean setContext = false; TypeContext typeContext = getContext().peekTypeContext(); String propertyName = typeContext != null ? typeContext.getPropertyName() : ""; if(prefix.trim().equals("")) prefix = propertyName; if (typeContext == null || typeContext.getBasicType() != BasicType.OBJECT) { typeContext = getContext().writeOpenObject(); setContext = true; } Date date = (Date) o; Calendar c = Calendar.getInstance(); c.setTime(date); if (!typeContext.isFirst()) getContext().writeComma(); typeContext.setFirst(false); getContext().writeName(fieldName("Month")); getContext().transform(c.get(Calendar.MONTH)); getContext().writeComma(); getContext().writeName(fieldName("Day")); getContext().transform(c.get(Calendar.DAY_OF_MONTH)); getContext().writeComma(); getContext().writeName(fieldName("Year")); getContext().transform(c.get(Calendar.YEAR)); if (setContext) { getContext().writeCloseObject(); } } private String fieldName(String suffix) { if( prefix.trim().equals("")) { return suffix.toLowerCase(); } else { return prefix + suffix; } } @Override public Boolean isInline() { return Boolean.TRUE; } }
Thread safety and Reuse
Finally, JSONSerializer instances can be reused to serialize many objects of the same type. Once you instantiate the object you can reuse it across multiple threads so long as you don't call include or exclude methods. Typically this isn't an issue since you might follow this pattern of instantiation:
public class PersonController { JSONSerializer personSerializer; public PersonController() { personSerializer = new JSONSerializer().include("addresses.zipcdoe"); } public String listPerson() { Person p = ....; return personSerializer.serialize( p ); } public String editPerson() { Person p = ....; return personSerializer.serialize( p ); } }
Deserialization
Deserialization is the process of taking JSON text binding those values into Objects. This process can be quite complex as JSON text contains no typing information. Mapping JSON data types onto static Java objects is tricky. Flexjson supports doing this through the JSONDeserializer class.
JSONDeserializer takes as input a json string and produces a static typed object graph from that json representation. By default it uses the class property in the json data in order to map the untyped generic json data into a specific Java type. This works quite well for JSON generated from flexjson. Let's just look at the simplest case using the class attributes in your json, and how JSONSerializer and JSONDeserializer nicely pair together out of the box.
Say we have a simple object like Hero (see the superhero package under the test and mock). To create a json representation of Hero we'd do the following:
Hero harveyBirdman = new Hero("Harvey Birdman", new SecretIdentity("Attorney At Law"), new SecretLair("Sebben & Sebben") ); String jsonHarvey = new JSONSerialize().serialize(hero);
Now to reconstitute Harvey to fight for the law we'd use JSONDeserializer like so:
Hero hero = new JSONDeserializer<Hero>().deserialize( jsonHarvey );
Deserialize Without the Training Wheels
Pretty easy when all the type information is included with the JSON data. Now let's look at the more difficult case of how we might reconstitute something that is missing type info.
Let's exclude the class attribute from our json like so:
String jsonHarvey = new JSONSerialize().exclude("*.class").serialize(hero);
We need to replace the type information we just dropped when we instantiate the deserializer. To do that we'll pass the class we want to use into to flexjson.JSONDeserializer.deserialize(String, Class) method like so:
Hero hero = new JSONDeserializer<Hero>().deserialize( jsonHarvey, Hero.class );
Prior to 2.0 you have to use the following to specify the root level object by calling use() method passing null for the path.
Hero hero = new JSONDeserializer<Hero>().use( null, Hero.class ).deserialize( jsonHarvey );
In both cases, what is happening here is we've registered the Hero class onto a path in the json object graph. We use null here to mean the root of the json object. If we were naming our root we'd include that name as the path to our root in the JSON. The flexjson.JSONDeserializer.use(String, Class) method uses the object graph path to attach certain classes to those locations. So, when the deserializer is deserializing it knows where it is in the object graph, and uses that graph path to look up the java class it should use to gather type information from.
Notice that all we registered was Hero class how did it know to instantiate SecretLair and SecretIdentity too? Flexjson uses the target type (in this case Hero) to figure out the other types by inspecting that class. Meaning that we didn't have to tell it about SecretLair or SecretIdentity because it can figure that out by inspecting the properties in the Hero class. Pretty cool.
Polymorphism, Subclasses, and Interfaces
Where we run into trouble is when we starting working with interfaces, abstract classes, and subclasses. Our friend polymorphism has rained on our parade. Why? Let's say our target type has a member with a type of java.util.List. Is that an ArrayList, LinkedList, or something else? By looking at the target type alone we don't know. The next section we're going to discuss how to handle these tricky problems.
Before we showed how the flexjson.JSONDeserializer.use(String, Class) method would allow us to plug in a single class for a given path. That might work when you know exactly which class you want to instantiate, but when the class type depends on external factors we really need a way to specify several possibilities. That's where the second version of {@link flexjson.JSONDeserializer#use(String, ClassLocator)} comes into play. A ClassLocator allows you to define a strategy for finding which java Class you want to attach at a particular object path dynamically.
flexjson.JSONDeserializer.use(String, ClassLocator) has access to the intermediate form of the object as a Map. Given the Map at the object path the ClassLocator figures out which Class Flexjson will bind the parameters into that object.
Let's take a look at how this can be done using our Hero class. All Heros have a list of super powers. These super powers are things like X Ray Vision, Heat Vision, Flight, etc. Each super power is represented by a subclass of SuperPower. If we serialize a Hero without class information embedded we'll need a way to figure out which subclass to instantiate when we deserialize. In this example I'm going to use a Transformer during serialization to strip off the package on the class attribute. This is not normally how you might do this, but I'm being lazy and doing a quick example.
String json = new JSONSerializer() .include("powers.class") .transform( new SimpleTransformer(), "powers.class") .exclude("*.class") .serialize( superhero ); Hero hero = new JSONDeserializer<Hero>() .use("powers.class", new PackageClassLocator()) .deserialize( json );
That's a very contrived example because all I'm doing is stripping off the package and then adding back that missing package in my ClassLocator. A more typical case would be when there is some typing information included in your JSON objects that can be used as a discriminator between the various types of Classes you need. The good news is flexjson provides a ClassLocator out of the box that provides this so you don't have to rewrite this.
TypeLocator class uses a field in the JSON to select a particular class you want to use. Here is a quick example of this. Say for example, in our JSON we have a field called "type" that is either a square, circle, or triangle. Based on the value of that field we want to use Square, Circle, or Triangle classes to be instantiated.
String json = new JSONSerializer().serialize( shapeList, "shapes" ); ShapeList shapes = new JSONDeserializer<ShapeList>() .use("shapes", new TypeLocator<String>("type") .add("square", Square.class) ) .add("circle", Circle.class) ) .add("triangle", Triangle.class) ) ) .deserialize( json )
In this example the deserialization definition is a little longer, but not bad. We're creating a TypeLocator instance saying the field that controls the typing is called "type", and when the value is "square" we want to use Square class, when it's "circle" use Circle class, and so on. TypeLocator is a generic class that lets you specify the datatype of the discriminator field. In this case we're using strings, but you could use integers just the same.
In this example I'm serializing a list of shapes, and I'm naming my list "shapes" which means my root isn't null anymore. This is just to show how paths work, and doesn't really have any relation to the use of TypeLocator.
Collections, Maps, and Generics
Collections and Maps are somewhat special cases of interfaces because they contain objects within them that aren't accessible through setter and getter methods. Normally, if you use generics and specify a concrete class as the generic class contained then you won't have anything else to do. However, mix in an interface, abstract class, or root level object containing Generics and you'll have tell the deserializer the types contained within.
Starting with 1.9 you can specify both the concrete class used for the collection class as well as the contained concrete class. By appending "values" to the path of any collection you can configure the concrete class of the contained class.
For example, say a Group object contains a Collection of Groupable instances where Groupable is an interface. We'll need to specify what concrete class to use for the Groupable. For simplicity in this example we'll assume all Groupable instances can be represented by a single concrete class. If the path to the Group's instance variable members of type Collection<Groupable>. So we might do the following:
new JSONDeserializer().use( "group.members.values", ConcreteGroupable.class )
The path "group.members" refers to the actual Collection instance. If you wanted to specify the Collection's implementation you could do the following:
new JSONDeserializer().use("group.members", LinkedList.class ).use( "group.members.values", ConcreteGroupable.class )
Maps support specifying key by append "keys" to the path and the values by appending "values" just like Collections. You don't have to specify the keys of the Map if they are one of the JSON native types like: String, or Double.
ObjectFactory
ObjectFactory are the underpinnings of the JSONDeserializer. All object creation pass through some type of ObjectFactory. Starting with 1.9 you can specify your own implementation and attach these to either paths or classes. ObjectFactories can be thought of as companions to Transformers in JSONSerializer.
For example, say we want to export dates as yyyy.MM.dd using the DateTransformer. We can do that easily using transform() method on JSONSerializer. Now let's read this back in by registering a DateTransformer as an ObjectFactory for "person.birthdate".
new JSONDeserializer().use("person.birthdate", new DateTransformer("yyyy.MM.dd") ).deserialize( people );
To use this pattern for all Dates you can register on the Date class. For example:
new JSONDeserializer().use(Date.class, new DateTransformer("yyyy.MM.dd") ).deserialize( people );
Deserializing has Rules for your Java Objects
All objects that pass through the deserializer must have a no argument constructor. The no argument constructor does not have to be public. That allows you to maintain some encapsulation. JSONDeserializer will bind parameters using setter methods of the objects instantiated if available. If a setter method is not available it will using reflection to set the value directly into the field. You can use setter methods transform the any data from json into the internal object structure you want. That way the JSON structure can be different from your Java object structure. The works very much in the same way getters do for the JSONSerializer.
Direct Deserialization from a Stream
For simplicity Flexjson allows you to work with String objects, but it's more efficient to work directly with the stream the json data is coming through. Starting in 2.1 you can provide a java.io.Reader as a source of the json data. This cuts down the overhead of converting between String and whatever stream you want to use as the source of the json. Now it can go directly to the stream bypassing the conversion to String. Here is a simple example:
MyObject obj = new JSONDeserializer>MyObject>().deserialize( request.getReader() );
Deserializing into an Existing Object and Merging
The JSONDeserializer supports deserializing json into an already existing instance. This allows you to support a primitive version of merging so prior values will be overwritten with the values in the json string, but anything not included in the json will remain untouched. This follows fairly simplistic rules, and doesn't do anything more complex than copy the data from json into your existing instance object. Here is an example:
Person charlie = new Person("Charlie", "Hubbard", cal.getTime(), home, work ); Person charlieClone = new Person( "Chauncy", "Beauregard", null, null, null ); Phone fakePhone = new Phone( PhoneNumberType.MOBILE, "303 555 1234"); charlieClone.getPhones().add( fakePhone ); String json = new JSONSerializer().include("hobbies").exclude("firstname", "lastname").serialize( charlie ); Person p = new JSONDeserializer<Person>().deserializeInto(json, charlieClone);
The variable p will reference the same instance as charlieClone. After deserializing into that instance, some of the values in p will be overwritten with values from charlie instance. However, we excluded the firstname and lastname fields so p will still have values "Chauncy" and "Beauregard" in it. Those will not be touched by the deserializer.
This shows how existing instances can be populated with data from json without needing to manually merge data from new objects to existing objects. Thus keeping boiler plate code for copying between two instances to a minimum. You can think of refreshing objects from the server or data stores as being a valid use case for this.
There are somethings to keep in mind. The return value will always be the exact same reference passed as the 2nd parameter to deserializeInto(). If there is a valid field in the json it will always overwrite what's in memory this includes null values too. This only supports deserializing into Java beans not collections.
Thread safety and Reuse
Finally, JSONSerializer and JSONDeserializer instances can be reused to serialize/deserialize many objects of the same type. Once you instantiate the object you can reuse it across multiple threads so long as you don't call include or exclude, or use methods. Typically this isn't an issue since you might follow this pattern of instantiation:
public class PersonController { JSONSerializer personSerializer; public PersonController() { personSerializer = new JSONSerializer().include("addresses.zipcdoe"); } public String listPerson() { Person p = ....; return personSerializer.serialize( p ); } public String editPerson() { Person p = ....; return personSerializer.serialize( p ); } }
Android Support
Prior versions of the library did not work on Android because it used the very standard package java.beans.Introspector. Instead of waiting for Google to port that class over to become more compliant with the Java specification starting in 2.1 Introspector has been replaced so that we can enjoy using Flexjson on Android. For more ideas and information about how Flexjson can be used in Android see this post.
Maven 2
Release
FlexJson is avaialable on the central maven repository. In order to use flexjson in your maven enabled project simply add the following to your dependencies.
http://repo2.maven.org/maven2/net/sf/flexjson/flexjson/
<dependencies> ... <dependency> <groupId>net.sf.flexjson</groupId> <artifactId>flexjson</artifactId> <version>2.1</version> <!-- This may not be the current version. Check the above link --> </dependency> ... </dependencies>
Snapshot
If you wish to access a pre-release SNAPSHOT of flexjson you can add the following in the repositories section of your pom. Be sure to specify the SNAPSHOT version you wish to use in the version tag of the dependency.
https://oss.sonatype.org/content/repositories/snapshots/net/sf/flexjson/flexjson/
<repositories> ... <repository> <id>sonatype.oss.snapshots</id> <name>Sonatype OSS Snapshot Repository</name> <url>http://oss.sonatype.org/content/repositories/snapshots</url> <releases> <enabled>false</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> ... </repositories>
<dependencies> ... <dependency> <groupId>net.sf.flexjson</groupId> <artifactId>flexjson</artifactId> <version>2.1-SNAPSHOT</version> <!-- This may not be the most current SNAPSHOT version. Check the above link --> </dependency> ... </dependencies>
The End
That's really all you need to know about Flexjson. It's really just that simple and lightweight. Please give me some feedback. I'd love to hear about improvements or new features you would like added. Email me at charlie DOT hubbard ( I don't want spam so this is here to stop harvesters ) AT gmail DOT com.