Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # My first Ruby program
- # Author:: Zhybul Kiryl (mailto:lucifer4u@gmail.com)
- # Copyright:: Copyright (c) 2007 Zhybul Kiryl
- # Revision:: 8
- # Created:: 26.08.2007 4:07 (GMT+2)
- # Ideal module have set of tools to create validable structures which can be
- # easily transformed to other data types. Once the structure definition and
- # transformation tool was created - it can be used anytime with any data which
- # passed Ideal Structure validator
- module Ideal
- # Element is a helper for XML generation
- class Element
- attr_accessor(:content)
- def initialize name
- @name, @attributes, @content = name, {}, ''
- end
- def attributes= attributes
- @attributes.merge(attributes)
- end
- def to_s
- open_tag + @content + close_tag
- end
- def open_tag
- "<" + @name + delim_and_attr + ">"
- end
- def close_tag
- "<" + @name + ">"
- end
- def delim_and_attr
- attr_str = attributes_string
- attributes_delimiter(attr_str) + attr_str
- end
- def attributes_delimiter attr_s
- return ' ' if attr_s != ''
- ''
- end
- def attributes_string
- attr_s = ''
- @attributes.each do |key, value|
- attr_s << key + "=" + "'" + value + "'" + " "
- end
- attr_s.strip
- end
- end
- # IdealCollection - container to store Ideal objects with the ability of
- # generation to the specific format
- class IdealCollection
- def initialize
- @state = []
- end
- def << value
- @state << value if not @state.include?(value)
- end
- def each
- @state.each do |value| yield(value) end
- end
- def to_s
- @state.to_s
- end
- def generate
- result = []
- @state.each do |value| result << value.generate() end
- end
- def IdealCollection.is_ideal_collection_structure? structure
- structure.all? do |value| Ideal.is_ideal_structure? value end
- end
- end
- # Ideal - container to store information which can be generated to the special
- # format
- class Ideal
- def initialize
- @state = Hash.new {|h, k| h[k] = IdealCollection.new }
- end
- def []= name, value
- @state[name] << value
- end
- def [] name
- @state[name]
- end
- def to_s
- @state.to_s
- end
- def Ideal.is_ideal_structure? struct
- return true if (struct.is_a?(String) or struct.is_a?(Numeric))
- return false if not struct.is_a?(Hash)
- struct.each do |attribute, value|
- return false if not attribute.is_a?(String)
- return false if not value.is_a?(Array)
- return false if value != value.uniq
- value.each do |key|
- return false if not Ideal.is_ideal_structure?(key)
- end
- end
- true
- end
- def generate
- res = {}
- @state.each do |attribute, value|
- res[attribute] = []
- value.each do |key|
- if key.respond_to?(:generate)
- res[attribute] << key.generate
- else
- res[attribute] << key
- end
- end
- end
- res
- end
- end
- # Definition of Numeric structure
- # Should be used to generate structure definition of Numeric element
- class NumericIdealStructureDefinition
- attr_accessor(:more_then, :less_then, :regexp, :in, :not_in)
- def generate
- res = {}
- res["more_then"] = @more_then if @more_then != nil
- res["less_then"] = @less_then if @less_then != nil
- res["regexp" ] = @regexp if @regexp != nil
- res["in"] = @in if @in != nil
- res["not_in"] = @not_in if @not_in !=nil
- res = {Numeric => res}
- res
- end
- end
- # Definition of String structure
- # Should be used to generate structure definition of String element
- class StringIdealStructureDefinition
- attr_accessor(:min_length, :max_length, :regexp)
- def generate
- res = {}
- res['min_length'] = @min_length if @min_length != nil
- res['max_length'] = @max_length if @max_length != nil
- res['regexp'] = @regexp if @regexp != nil
- {String => res}
- end
- end
- # Definition of Hash structure
- # Should be used to generate structure definition of Hash element
- class HashIdealStructureDefinition
- def initialize
- @hash_ideal_structure = {}
- end
- def keys
- @hash_ideal_structure.keys
- end
- def []= key, value
- @hash_ideal_structure[key] = value
- end
- def generate
- res = {}
- @hash_ideal_structure.each do |key, value|
- res[key] = value.generate
- end
- {Hash => res}
- end
- end
- # Definition of Ideal Collection structure
- # Should be used to generate structure definition of Ideal Collection element
- class IdealCollectionStructureDefinition
- def min_number= min_number
- @min_number = min_number
- end
- def max_number= max_number
- @max_number = max_number
- end
- def number_array= number_array
- @number_array = number_array
- end
- def ideal_structure= ideal_structure
- @ideal_structure = ideal_structure
- end
- def generate
- raise "No ideal structure found." if @ideal_structure == nil
- res = {}
- res["min_number"] = @min_number if @min_number != nil
- res["max_number"] = @max_number if @max_number != nil
- res["number_array"] = @number_array if @number_array != nil
- res["ideal_structure"] = @ideal_structure.generate
- res
- end
- end
- # Simple helper to create XML information useing Element objects from
- # ideal data structure
- class IdealStructureXML
- def hash_representation structure
- res = ''
- structure.each do |key, value|
- value.each do |val|
- a = Element.new(key)
- a.content = render(val)
- res = res + a.to_s
- end
- end
- res
- end
- def render structure
- return hash_representation(structure) if structure.is_a?(Hash)
- structure.to_s
- end
- end
- # Validator of the ideal structure
- # Can tell you is your structure is valid idel structure according to its
- # definition
- class IdealStructureValidator
- def validate_hash hash, definition
- return false if hash.keys != definition.keys
- definition.all? do |key, collection|
- validate_collection(hash[key], collection)
- end
- end
- def validate_string string, definition
- min_length = definition['min_length']
- str_length = string.length
- max_length = definition['max_length']
- regexp = definition['regexp']
- return false if (min_length != nil and not str_length >= min_length)
- return false if (max_length != nil and not str_length <= max_length)
- return false if (regexp != nil and string.scan(regexp).length == 0)
- true
- end
- def validate_numeric numeric, definition
- more_then = definition['more_then']
- less_then = definition['less_then']
- regexp = definition['regexp']
- in_ = definition['in']
- not_in = definition['not_in']
- return false if (more_then != nil and not numeric >= more_then)
- return false if (less_then != nil and not numeric <= less_then)
- return false if (regexp != nil and numeric.to_s.scan(regexp).length == 0)
- return false if (in_ != nil and not in_.include?(numeric))
- return false if (not_in != nil and not_in.include?(numeric))
- true
- end
- def validate_collection collection, definition
- length = collection.length
- min_number = definition['min_number']
- max_number = definition['max_number']
- number_arr = definition['number_array']
- def_ideal_structure = definition['ideal_structure']
- return false if length != collection.uniq.length
- return false if (min_number != nil and not length >= min_number)
- return false if (max_number != nil and not length <= max_number)
- return false if (number_arr != nil and not number_arr.include?(length))
- return false if def_ideal_structure == nil
- collection.all? do |value| validate(value, def_ideal_structure) end
- end
- def validate input, ideal_structure
- ideal_structure.each do |key, value|
- return false if not [Hash, String, Numeric].include?(key)
- return false if (key == Hash and not validate_hash(input, value))
- return false if (key == String and not validate_string(input, value))
- return false if (key == Numeric and not validate_numeric(input, value))
- end
- true
- end
- end
- class IdealTransformation
- def delimiter info
- "<div class='delimiter'>" << info << ":</div>"
- end
- def header
- result = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN">'
- result << "<head>"
- result << "<title>"
- result << "Test of the Ideal structures"
- result << "</title>"
- result << "<style type='text/css'>"
- result << ".no_users{clear:both; border:1px solid #de7eff;background-color:#eeeeee;color:gray;padding:30px;width:610px;}"
- result << ".user_rating{padding:10px;margin:1px;float:left;width:100px;border:1px solid #de7eff;background-color:#eeeeee;color:gray;}"
- result << ".user_name{padding:10px;margin:1px;float:left;width:100px;border:1px solid #de7eff;background-color:#eeeeee;color:gray;}"
- result << ".user_emails{padding:10px;margin:1px;float:left;width:400px;margin-bottom:10px;border:1px solid #de7eff;background-color:#eeeeee;color:gray;}"
- result << ".user{float;left;width:700px;}"
- result << ".delimiter{clear:both;}"
- result << "</style>"
- result << "</head>"
- result
- end
- def transform users_data
- result = ''
- if users_data['users'].length == 0
- result << '<div class="no_users">There is no users in the system</div>'
- else
- result << '<div class="users">'
- users_data['users'].each do |user|
- result << '<div class="user">'
- result << '<div class="user_name">'
- result << user['username'].to_s
- result << '</div>'
- result << '<div class="user_rating">'
- result << user['rating'].to_s
- result << '</div>'
- result << '<div class="user_emails">'
- user['email'].each do |email|
- result << '<div class="user_email">'
- result << email
- result << '</div>'
- end
- result << '</div>'
- result << '</div>'
- end
- result << '</div>'
- end
- result
- end
- end
- end
- class Example
- def Example.test
- # Step 0. Including Ideal module
- include Ideal
- # Step 1. Creation of the ideal descriptor
- email_descriptor = StringIdealStructureDefinition.new
- email_descriptor.regexp = /[^@]+@[0-9_a-z]+\.[a-z]+/
- email_collection_descriptor = IdealCollectionStructureDefinition.new
- email_collection_descriptor.min_number = 1
- email_collection_descriptor.max_number = 4
- email_collection_descriptor.ideal_structure = email_descriptor
- user_rating_descriptor = NumericIdealStructureDefinition.new
- user_rating_descriptor.more_then = 0
- user_rating_collection_descriptor = IdealCollectionStructureDefinition.new
- user_rating_collection_descriptor.min_number = 1
- user_rating_collection_descriptor.max_number = 1
- user_rating_collection_descriptor.ideal_structure = user_rating_descriptor
- username_descriptor = StringIdealStructureDefinition.new
- username_descriptor.regexp = /[0-9A-Za-z_]+/
- username_collection_descriptor = IdealCollectionStructureDefinition.new
- username_collection_descriptor.min_number = 1
- username_collection_descriptor.max_number = 1
- username_collection_descriptor.ideal_structure = username_descriptor
- user_descriptor = HashIdealStructureDefinition.new
- user_descriptor['username'] = username_collection_descriptor
- user_descriptor['rating'] = user_rating_collection_descriptor
- user_descriptor['email'] = email_collection_descriptor
- user_collection_descriptor = IdealCollectionStructureDefinition.new
- user_collection_descriptor.min_number = 0
- user_collection_descriptor.max_number = 20
- user_collection_descriptor.ideal_structure = user_descriptor
- users_descriptor = HashIdealStructureDefinition.new
- users_descriptor['users'] = user_collection_descriptor
- users_structure_description = users_descriptor.generate
- # Step 2. Getting data
- users_data =
- {
- "users" =>
- [
- {
- "username" =>
- [
- "lucifer4u"
- ],
- "rating" =>
- [
- 213
- ],
- "email" =>
- [
- "lucifer4u@gmail.com",
- "lucifer4u@kings.com",
- "lucifer4u@swift.com"
- ]
- },
- {
- "username" =>
- [
- "niko"
- ],
- "rating" =>
- [
- 324
- ],
- "email" =>
- [
- "nikodimous@gmail.com"
- ]
- },
- ]
- }
- users_data_2 =
- {
- "users" =>
- [
- ]
- }
- users_data_3 =
- {
- "users" =>
- [
- {
- "username" =>
- [
- "niko1"
- ],
- "rating" =>
- [
- 3241
- ],
- "email" =>
- [
- "nikodimous1@gmail.com"
- ]
- },
- {
- "username" =>
- [
- "niko2"
- ],
- "rating" =>
- [
- 3242
- ],
- "email" =>
- [
- "nikodimous2@gmail.com"
- ]
- },
- {
- "username" =>
- [
- "niko3"
- ],
- "rating" =>
- [
- 3243
- ],
- "email" =>
- [
- "nikodimous3@gmail.com"
- ]
- },
- ]
- }
- # Alternative way using Ideal and Ideal Collection
- a = Ideal.new
- a['username'] = "nightwish"
- a['rating'] = 3299
- a['email'] = "some_email@gmail.com"
- a['email'] << "some_mail@gmail.com"
- a['email'] << "extra_mail@gmail.com"
- b = Ideal.new
- b['username'] = "rocky"
- b['rating'] = 3929
- b['email'] = "rocky@rick.com"
- b['email'] = "masters@rick.com"
- c = Ideal.new
- c['users'] = a
- c['users'] << b
- users_data_4 = c.generate
- # Step 3. Validating information
- ideal_structure_validator = IdealStructureValidator.new
- is_valid = ideal_structure_validator.validate(users_data,
- users_structure_description)
- is_valid_2 = ideal_structure_validator.validate(users_data_2,
- users_structure_description)
- is_valid_3 = ideal_structure_validator.validate(users_data_3,
- users_structure_description)
- is_valid_4 = ideal_structure_validator.validate(users_data_4,
- users_structure_description)
- # Step 4. Transformation of ideal to some other format
- ideal_transformation = IdealTransformation.new
- puts ideal_transformation.header
- puts ideal_transformation.delimiter("First data structure representation")
- if is_valid
- puts ideal_transformation.transform(users_data)
- end
- puts ideal_transformation.delimiter("Second data structure representation")
- if is_valid_2
- puts ideal_transformation.transform(users_data_2)
- end
- puts ideal_transformation.delimiter("Third data structure representation")
- if is_valid_3
- puts ideal_transformation.transform(users_data_3)
- end
- puts ideal_transformation.delimiter("Forth data structure representation")
- if is_valid_4
- puts ideal_transformation.transform(users_data_4)
- end
- end
- end
- Example.test
Add Comment
Please, Sign In to add comment