Skip to content
Browse files

new gem name

  • Loading branch information...
1 parent 0c6178b commit ca41ffac9364d07301221f779339b507857bdde8 @mkristian committed Jul 3, 2012
View
3 Mavenfile
@@ -4,5 +4,4 @@ properties['jruby.plugins.version']='0.29.0-SNAPSHOT'
properties['jruby.version']='1.6.7'
# just fixate the version
-gem 'bundler', '= 1.1.3'
-gem 'jruby-openssl', '= 0.7.4'
+#gem 'jruby-openssl', '= 0.7.4'
View
4 vellam.gemspec → ixtlan-babel.gemspec
@@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
Gem::Specification.new do |s|
- s.name = 'vellam'
+ s.name = 'ixtlan-babel'
s.version = '0.1.2'
s.summary = 'babel offers a filter for hashes and with that comes json/yaml/xml de/serialization of models which provides a hash representation'
s.description = 'babel offers a filter for hashes and with that comes json/yaml/xml de/serialization of models which provides a hash representationi. possible models are activerecord, activemodel, resources from datamapper, virtus'
- s.homepage = 'https://github.com/mkristian/babel'
+ s.homepage = 'https://github.com/mkristian/ixtlan-babel'
s.authors = ['Kristian Meier']
s.email = ['m.kristian@web.de']
View
2 lib/babel.rb
@@ -1,2 +0,0 @@
-require 'babel/serializer'
-require 'babel/deserializer'
View
63 lib/babel/deserializer.rb
@@ -1,63 +0,0 @@
-module Babel
- class Deserializer
-
- def initialize(model_class)
- @model_class = model_class
- end
-
- private
-
- def self.filter
- @filter ||= HashFilter.new
- end
-
- def filter
- @filter ||= self.class.filter.dup
- end
-
- protected
-
- def self.default_context_key(default)
- filter.default_context_key(default)
- end
-
- def self.add_context(key, options = {})
- filter[key] = options
- end
-
- public
-
- def use(context_or_options)
- filter.use(context_or_options)
- self
- end
-
- def from_hash(data, options = nil)
- filter.use(options) if options
- if root = filter.options[:root]
- if data.is_a? Array
- root = root.to_s
- data.collect{ |d| @model_class.new(filter.filter(d[root])) }
- else
- @model_class.new(filter.filter(data[root.to_s]))
- end
- else
- if data.is_a? Array
- data.collect{ |d| @model_class.new(filter.filter(d)) }
- else
- @model_class.new(filter.filter(data))
- end
- end
- end
-
- def from_json(json, options = nil)
- data = JSON.parse(json)
- from_hash(data, options)
- end
-
- def from_yaml(yaml, options = nil)
- data = YAML.load_stream(StringIO.new(yaml)).documents
- from_hash(data, options)
- end
- end
-end
View
127 lib/babel/hash_filter.rb
@@ -1,127 +0,0 @@
-module Babel
- class HashFilter
-
- def initialize(context_or_options = nil)
- use(context_or_options)
- end
-
- private
-
- def context
- @context ||= {}
- end
-
- public
-
- def default_context_key(default = nil)
- @default = default if default
- @default
- end
-
- def []=(key, options)
- context[key.to_sym] = options if key
- end
-
- def [](key)
- context[key.to_sym] if key
- end
-
- def use(context_or_options)
- if context_or_options
- case context_or_options
- when Symbol
- if opts = context[context_or_options]
- @options = opts.dup
- end
- when Hash
- @options = context_or_options
- end
- else
- @options = nil
- end
- self
- end
-
- NO_MODEL = Object.new
- def NO_MODEL.send(*args)
- self
- end
-
- def filter(hash = {}, model = NO_MODEL, &block)
- filter_data(model, hash, options, &block) if hash
- end
-
- def options
- @options || context[default_context_key] || {}
- end
-
- private
-
- def filter_data(model, data, options = {}, &block)
- only = options[:only].collect { |o| o.to_s } if options[:only]
- except = (options[:except] || []).collect { |e| e.to_s }
-
- include =
- case options[:include]
- when Array
- options[:include].collect { |i| i.to_s }
- when Hash
- Hash[options[:include].collect {|k,v| [k.to_s, v]}]
- else
- []
- end
- if model != NO_MODEL
- methods = (options[:methods] || []).collect { |e| e.to_s }
- methods.each do |m|
- data[m] = model.send(m.to_sym)
- end
-
- include_methods = include.is_a?(Array) ? include : include.keys
- include_methods.each do |m|
- unless data.include?(m)
- raise "no block given to calculate the attributes from model" unless block
- models_or_model = model.send(m)
- if models_or_model.respond_to?(:collect)
- data[m] = models_or_model.collect { |i| block.call(i) }
- else
- data[m]= block.call(model.send(m))
- end
- end
- end
- end
- methods ||= []
-
- result = {}
- data.each do |k,v|
- case v
- when Hash
- if include.include?(k)
- case include
- when Array
- result[k] = filter_data(model.send(k), v, &block)
- when Hash
- result[k] = filter_data(model.send(k), v, include[k], &block)
- end
- end
- when Array
- if include.include?(k)
- models = model.send(k)
- j = -1
- case include
- when Array
- result[k] = v.collect { |i| j += 1; filter_data(models[j], i, &block) }
- when Hash
- opts = include[k]
- result[k] = v.collect { |i| j += 1; filter_data(models[j], i, opts, &block) }
- end
- end
- else
- if methods.include?(k) || (only && only.include?(k)) || (only.nil? && !except.include?(k))
- result[k] = v
- end
- end
- end
- result
- end
- end
-end
View
101 lib/babel/serializer.rb
@@ -1,101 +0,0 @@
-require 'babel/hash_filter'
-module Babel
- class Serializer
-
- def initialize(model_or_models)
- @model_or_models = model_or_models
- end
-
- def respond_to?(method)
- @model_or_models.respond_to?(method)
- end
-
- def method_missing(method, *args, &block)
- @model_or_models.send(method, *args, &block)
- end
-
- private
-
- def self.filter
- @filter ||= HashFilter.new
- end
-
- def filter
- @filter ||= self.class.filter.dup
- end
-
- protected
-
- # for rails
- def self.model(model = nil)
- @model_class = model if model
- @model_class ||= self.to_s.sub(/Serializer$/, '').constantize
- end
-
- # for rails
- def self.model_name
- model.model_name
- end
-
- def self.default_context_key(default)
- filter.default_context_key(default)
- end
-
- def self.add_context(key, options = {})
- filter[key] = options
- end
-
- public
-
- def use(context_or_options)
- filter.use(context_or_options)
- self
- end
-
- def to_hash(options = nil)
- filter.use(filter.options.dup.merge!(options)) if options
- if @model_or_models.respond_to?(:collect) && ! @model_or_models.is_a?(Hash)
- @model_or_models.collect do |m|
- filter_model(attr(m), m)
- end
- else
- filter_model(attr(@model_or_models), @model_or_models)
- end
- end
-
- def to_json(options = nil)
- to_hash(options).to_json
- end
-
- def to_xml(options = {})
- opts = filter.options.dup.merge!(options)
- root = opts.delete :root
- fitler.use(opts)
- result = to_hash
- if root && result.is_a?(Array) && root.respond_to?(:pluralize)
- root = root.to_s.pluralize
- end
- result.to_xml :root => root
- end
-
- def to_yaml(options = nil)
- to_hash(options).to_yaml
- end
-
- protected
-
- def attr(model)
- model.attributes if model
- end
-
- private
-
- def filter_model(model, data)
- if root = filter.options[:root]
- {root.to_s => filter.filter(model, data){ |model| attr(model) } }
- else
- filter.filter(model, data){ |model| attr(model) }
- end
- end
- end
-end
View
4 lib/ixtlan-babel.rb
@@ -0,0 +1,4 @@
+require 'ixtlan/babel/serializer'
+require 'ixtlan/babel/deserializer'
+require 'ixtlan/babel/factory'
+require 'ixtlan/babel/no_timestamp_serializer'
View
65 lib/ixtlan/babel/deserializer.rb
@@ -0,0 +1,65 @@
+module Ixtlan
+ module Babel
+ class Deserializer
+
+ def initialize(model_class)
+ @model_class = model_class
+ end
+
+ private
+
+ def self.filter
+ @filter ||= HashFilter.new
+ end
+
+ def filter
+ @filter ||= self.class.filter.dup
+ end
+
+ protected
+
+ def self.default_context_key(default)
+ filter.default_context_key(default)
+ end
+
+ def self.add_context(key, options = {})
+ filter[key] = options
+ end
+
+ public
+
+ def use(context_or_options)
+ filter.use(context_or_options)
+ self
+ end
+
+ def from_hash(data, options = nil)
+ filter.use(options) if options
+ if root = filter.options[:root]
+ if data.is_a? Array
+ root = root.to_s
+ data.collect{ |d| @model_class.new(filter.filter(d[root])) }
+ else
+ @model_class.new(filter.filter(data[root.to_s]))
+ end
+ else
+ if data.is_a? Array
+ data.collect{ |d| @model_class.new(filter.filter(d)) }
+ else
+ @model_class.new(filter.filter(data))
+ end
+ end
+ end
+
+ def from_json(json, options = nil)
+ data = JSON.parse(json)
+ from_hash(data, options)
+ end
+
+ def from_yaml(yaml, options = nil)
+ data = YAML.load_stream(StringIO.new(yaml)).documents
+ from_hash(data, options)
+ end
+ end
+ end
+end
View
48 lib/ixtlan/babel/factory.rb
@@ -0,0 +1,48 @@
+module Ixtlan
+ module Babel
+ class Factory
+
+ class EmptyArraySerializer < Array
+ def use(arg)
+ self
+ end
+ end
+
+ def initialize(custom_serializers = {})
+ @map = {}
+ add('DateTime') do |dt|
+ dt.strftime('%Y-%m-%dT%H:%M:%S.') + ("%06d" % (dt.sec_fraction / Date::NANOSECONDS_IN_DAY / 1000)) + dt.strftime('%z')
+ end
+ add('ActiveSupport::TimeWithZone') do |tz|
+ tz.strftime('%Y-%m-%dT%H:%M:%S.') + ("%06d" % tz.usec) + tz.strftime('%z')
+ end
+ add('Time') do |t|
+ t.strftime('%Y-%m-%dT%H:%M:%S.') + ("%06d" % t.usec) + t.strftime('%z')
+ end
+ @map.merge!(custom_serializers)
+ end
+
+ def add(clazz, &block)
+ @map[clazz.to_s] = block
+ end
+
+ def new(resource)
+ if resource.respond_to?(:model)
+ model = resource.model
+ elsif resource.is_a? Array
+ if resource.empty?
+ return EmptyArraySerializer.new
+ else
+ r = resource.first
+ model = r.respond_to?(:model) ? r.model : r.class
+ end
+ else
+ model = resource.class
+ end
+ ser = Object.const_get("#{model}Serializer").new(resource)
+ ser.add_custom_serializers(@map)
+ ser
+ end
+ end
+ end
+end
View
148 lib/ixtlan/babel/hash_filter.rb
@@ -0,0 +1,148 @@
+module Ixtlan
+ module Babel
+ class HashFilter
+
+ def initialize(context_or_options = nil)
+ use(context_or_options)
+ end
+
+ private
+
+ def context
+ @context ||= {}
+ end
+
+ public
+
+ def add_custom_serializers(map)
+ @map = map
+ end
+
+ def default_context_key(default = nil)
+ @default = default if default
+ @default
+ end
+
+ def []=(key, options)
+ context[key.to_sym] = options if key
+ end
+
+ def [](key)
+ context[key.to_sym] if key
+ end
+
+ def use(context_or_options)
+ if context_or_options
+ case context_or_options
+ when Symbol
+ if opts = context[context_or_options]
+ @options = opts.dup
+ end
+ when Hash
+ @options = context_or_options
+ end
+ else
+ @options = nil
+ end
+ self
+ end
+
+ NO_MODEL = Object.new
+ def NO_MODEL.send(*args)
+ self
+ end
+ def NO_MODEL.[](*args)
+ self
+ end
+
+ def filter(hash = {}, model = NO_MODEL, &block)
+ filter_data(model, hash, options, &block) if hash
+ end
+
+ def options
+ @options || context[default_context_key] || {}
+ end
+
+ private
+
+ def filter_data(model, data, options = {}, &block)
+ model = NO_MODEL if model == data
+ only = options[:only].collect { |o| o.to_s } if options[:only]
+ except = (options[:except] || []).collect { |e| e.to_s }
+
+ include =
+ case options[:include]
+ when Array
+ options[:include].collect { |i| i.to_s }
+ when Hash
+ Hash[options[:include].collect {|k,v| [k.to_s, v]}]
+ else
+ []
+ end
+ if model != NO_MODEL
+ methods = (options[:methods] || []).collect { |e| e.to_s }
+ methods.each do |m|
+ data[m] = model.send(m.to_sym)
+ end
+
+ include_methods = include.is_a?(Array) ? include : include.keys
+ include_methods.each do |m|
+ unless data.include?(m)
+ raise "no block given to calculate the attributes from model" unless block
+ models_or_model = model.send(m)
+ if models_or_model.respond_to?(:collect)
+ data[m] = models_or_model.collect { |i| block.call(i) }
+ else
+ data[m]= block.call(model.send(m))
+ end
+ end
+ end
+ end
+ methods ||= []
+
+ result = {}
+ data.each do |k,v|
+ case v
+ when Hash
+ if include.include?(k.to_s)
+ case include
+ when Array
+ result[k.to_s] = filter_data(model.send(k), v, &block)
+ when Hash
+ result[k.to_s] = filter_data(model.send(k), v, include[k.to_s], &block)
+ end
+ end
+ when Array
+ if include.include?(k.to_s)
+ models = model.send(k)
+ j = -1
+ case include
+ when Array
+ result[k.to_s] = v.collect do |i|
+ j += 1
+ if i.is_a?(Array) || i.is_a?(Hash)
+ filter_data(models[j], i, &block)
+ else
+ i
+ end
+ end
+ when Hash
+ opts = include[k]
+ result[k.to_s] = v.collect { |i| j += 1; filter_data(models[j], i, opts, &block) }
+ end
+ end
+ else
+ if methods.include?(k.to_s) || (only && only.include?(k.to_s)) || (only.nil? && !except.include?(k.to_s))
+ if @map && ser = @map[v.class.to_s]
+ result[k.to_s] = ser.call(v)
+ else
+ result[k.to_s] = v
+ end
+ end
+ end
+ end
+ result
+ end
+ end
+ end
+end
View
24 lib/ixtlan/babel/no_timestamp_serializer.rb
@@ -0,0 +1,24 @@
+require 'ixtlan/babel/serializer'
+module Ixtlan
+ module Babel
+ class NoTimestampSerializer < Serializer
+
+ def self.add_defaults(root = nil)
+ if root
+ add_context(:default, :root => root)
+ add_no_timestamp_context(:collection, :root => root)
+ else
+ add_context(:default)
+ add_no_timestamp_context(:collection)
+ end
+ end
+
+ def self.add_no_timestamp_context(key, options = {})
+ except = (options[:except] || []).dup
+ except << :updated_at
+ except << :created_at
+ add_context(key, options.merge({:except => except}))
+ end
+ end
+ end
+end
View
115 lib/ixtlan/babel/serializer.rb
@@ -0,0 +1,115 @@
+require 'ixtlan/babel/hash_filter'
+module Ixtlan
+ module Babel
+ class Serializer
+
+ def id
+ if @model_or_models.is_a? Array
+ super
+ else
+ @model_or_models.id
+ end
+ end
+
+ def initialize(model_or_models)
+ @model_or_models = model_or_models
+ end
+
+ def respond_to?(method)
+ @model_or_models.respond_to?(method)
+ end
+
+ def method_missing(method, *args, &block)
+ @model_or_models.send(method, *args, &block)
+ end
+
+ def add_custom_serializers(map)
+ filter.add_custom_serializers(map)
+ end
+
+ private
+
+ def self.filter
+ @filter ||= HashFilter.new
+ end
+
+ def filter
+ @filter ||= self.class.filter.dup
+ end
+
+ protected
+
+ # for rails
+ def self.model(model = nil)
+ @model_class = model if model
+ @model_class ||= self.to_s.sub(/Serializer$/, '').constantize
+ end
+
+ # for rails
+ def self.model_name
+ model.model_name
+ end
+
+ def self.default_context_key(default)
+ filter.default_context_key(default)
+ end
+
+ def self.add_context(key, options = {})
+ filter[key] = options
+ end
+
+ public
+
+ def use(context_or_options)
+ filter.use(context_or_options)
+ self
+ end
+
+ def to_hash(options = nil)
+ filter.use(filter.options.dup.merge!(options)) if options
+ if @model_or_models.respond_to?(:collect) && ! @model_or_models.is_a?(Hash)
+ @model_or_models.collect do |m|
+ filter_model(attr(m), m)
+ end
+ else
+ filter_model(attr(@model_or_models), @model_or_models)
+ end
+ end
+
+ def to_json(options = nil)
+ to_hash(options).to_json
+ end
+
+ def to_xml(options = {})
+ opts = filter.options.dup.merge!(options)
+ root = opts.delete :root
+ fitler.use(opts)
+ result = to_hash
+ if root && result.is_a?(Array) && root.respond_to?(:pluralize)
+ root = root.to_s.pluralize
+ end
+ result.to_xml :root => root
+ end
+
+ def to_yaml(options = nil)
+ to_hash(options).to_yaml
+ end
+
+ protected
+
+ def attr(model)
+ model.attributes if model
+ end
+
+ private
+
+ def filter_model(model, data)
+ if root = filter.options[:root]
+ {root.to_s => filter.filter(model, data){ |model| attr(model) } }
+ else
+ filter.filter(model, data){ |model| attr(model) }
+ end
+ end
+ end
+ end
+end

0 comments on commit ca41ffa

Please sign in to comment.
Something went wrong with that request. Please try again.