codemodels 0.2.2-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +19 -0
 - data/Gemfile +3 -0
 - data/LICENSE +20 -0
 - data/README.md +23 -0
 - data/Rakefile +9 -0
 - data/codemodels.gemspec +29 -0
 - data/lib/codemodels/foreign_ast.rb +11 -0
 - data/lib/codemodels/info_extraction.rb +139 -0
 - data/lib/codemodels/language.rb +65 -0
 - data/lib/codemodels/metamodel.rb +11 -0
 - data/lib/codemodels/model_building.rb +81 -0
 - data/lib/codemodels/monkey_patching.rb +30 -0
 - data/lib/codemodels/parsing.rb +184 -0
 - data/lib/codemodels/query_serialized.rb +81 -0
 - data/lib/codemodels/rgen_ext.rb +186 -0
 - data/lib/codemodels/serialization.rb +142 -0
 - data/lib/codemodels/version.rb +3 -0
 - data/lib/codemodels.rb +5 -0
 - data/test/data/node_setCompleted.json +443 -0
 - data/test/test_foreign_ast.rb +28 -0
 - data/test/test_helper.rb +10 -0
 - data/test/test_info_extraction.rb +90 -0
 - data/test/test_language.rb +28 -0
 - data/test/test_monkey_patching.rb +38 -0
 - data/test/test_query_serialized.rb +40 -0
 - data/test/test_rgen_ext.rb +187 -0
 - data/test/test_serialization.rb +83 -0
 - metadata +167 -0
 
    
        data/.gitignore
    ADDED
    
    
    
        data/Gemfile
    ADDED
    
    
    
        data/LICENSE
    ADDED
    
    | 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            The MIT License (MIT)
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Copyright (c) 2013 ftomassetti
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            Permission is hereby granted, free of charge, to any person obtaining a copy of
         
     | 
| 
      
 6 
     | 
    
         
            +
            this software and associated documentation files (the "Software"), to deal in
         
     | 
| 
      
 7 
     | 
    
         
            +
            the Software without restriction, including without limitation the rights to
         
     | 
| 
      
 8 
     | 
    
         
            +
            use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
         
     | 
| 
      
 9 
     | 
    
         
            +
            the Software, and to permit persons to whom the Software is furnished to do so,
         
     | 
| 
      
 10 
     | 
    
         
            +
            subject to the following conditions:
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            The above copyright notice and this permission notice shall be included in all
         
     | 
| 
      
 13 
     | 
    
         
            +
            copies or substantial portions of the Software.
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         
     | 
| 
      
 16 
     | 
    
         
            +
            IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
         
     | 
| 
      
 17 
     | 
    
         
            +
            FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
         
     | 
| 
      
 18 
     | 
    
         
            +
            COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
         
     | 
| 
      
 19 
     | 
    
         
            +
            IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
         
     | 
| 
      
 20 
     | 
    
         
            +
            CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         
     | 
    
        data/README.md
    ADDED
    
    | 
         @@ -0,0 +1,23 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            codemodels
         
     | 
| 
      
 2 
     | 
    
         
            +
            ===========
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            codemodels is a library to create and manipulate models. A serialization format (based on JSON) is defined.
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            It is based on [RGen](http://github.com/mthiede/rgen) and it supportes the conversion of EMF models through [emf_jruby](http://github.com/ftomassetti/emf_jruby).
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            There are different gems which transform source code in models of the code. Currently they are:
         
     | 
| 
      
 9 
     | 
    
         
            +
            * [html-lightmodels](http://github.com/ftomassetti/html-lightmodels)
         
     | 
| 
      
 10 
     | 
    
         
            +
            * [java-lightmodels](http://github.com/ftomassetti/java-lightmodels)
         
     | 
| 
      
 11 
     | 
    
         
            +
            * [js-lightmodels](http://github.com/ftomassetti/js-lightmodels)
         
     | 
| 
      
 12 
     | 
    
         
            +
            * [properties-lightmodels](http://github.com/ftomassetti/properties-lightmodels)
         
     | 
| 
      
 13 
     | 
    
         
            +
            * [ruby-lightmodels](http://github.com/ftomassetti/ruby-lightmodels)
         
     | 
| 
      
 14 
     | 
    
         
            +
            * [xml-lightmodels](http://github.com/ftomassetti/xml-lightmodels)
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            Therefore it can be used to perform analysis on different languages.
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            Features
         
     | 
| 
      
 19 
     | 
    
         
            +
            ========
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            It handles also the case in which different languages are hosted in the same file (for example a Javascript script inside an HTML page).
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            Most of the parsers permit also to associate each node with a precise point in the source code, so thath they could be used to implement layout-preserving refactoring.
         
     | 
    
        data/Rakefile
    ADDED
    
    
    
        data/codemodels.gemspec
    ADDED
    
    | 
         @@ -0,0 +1,29 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # coding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
            lib = File.expand_path('../lib', __FILE__)
         
     | 
| 
      
 3 
     | 
    
         
            +
            $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'codemodels/version'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            Gem::Specification.new do |s|
         
     | 
| 
      
 7 
     | 
    
         
            +
              s.platform    = 'java'
         
     | 
| 
      
 8 
     | 
    
         
            +
              s.name        = 'codemodels'
         
     | 
| 
      
 9 
     | 
    
         
            +
              s.version     = CodeModels::VERSION
         
     | 
| 
      
 10 
     | 
    
         
            +
              s.date        = '2013-08-27'
         
     | 
| 
      
 11 
     | 
    
         
            +
              s.summary     = "Library to build models of code"
         
     | 
| 
      
 12 
     | 
    
         
            +
              s.description = "Library to build models of code of different languages in a uniform way."
         
     | 
| 
      
 13 
     | 
    
         
            +
              s.authors     = ["Federico Tomassetti"]
         
     | 
| 
      
 14 
     | 
    
         
            +
              s.email       = 'f.tomassetti@gmail.com'
         
     | 
| 
      
 15 
     | 
    
         
            +
              s.homepage    = 'https://github.com/ftomassetti/codemodels'
         
     | 
| 
      
 16 
     | 
    
         
            +
              s.license     = "APACHE 2"
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              s.files         = `git ls-files`.split($/)
         
     | 
| 
      
 19 
     | 
    
         
            +
              s.executables   = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
         
     | 
| 
      
 20 
     | 
    
         
            +
              s.test_files    = s.files.grep(%r{^(test|spec|features)/})
         
     | 
| 
      
 21 
     | 
    
         
            +
              s.require_paths = ["lib"]
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              s.add_dependency('json')
         
     | 
| 
      
 24 
     | 
    
         
            +
              s.add_dependency('rgen')
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              s.add_development_dependency "bundler", "1.3.5"
         
     | 
| 
      
 27 
     | 
    
         
            +
              s.add_development_dependency "rake"  
         
     | 
| 
      
 28 
     | 
    
         
            +
              s.add_development_dependency "simplecov"
         
     | 
| 
      
 29 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,139 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rgen/metamodel_builder'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module CodeModels
         
     | 
| 
      
 4 
     | 
    
         
            +
            module InfoExtraction
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            class TermsBreaker
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            	attr_accessor :sequences, :inv_sequences
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            	def initialize(language_specific_logic)
         
     | 
| 
      
 11 
     | 
    
         
            +
            		@language_specific_logic = language_specific_logic
         
     | 
| 
      
 12 
     | 
    
         
            +
            		@sequences = Hash.new {|h,k| 
         
     | 
| 
      
 13 
     | 
    
         
            +
            			h[k] = Hash.new {|h,k| 
         
     | 
| 
      
 14 
     | 
    
         
            +
            				h[k]=0
         
     | 
| 
      
 15 
     | 
    
         
            +
            			} 
         
     | 
| 
      
 16 
     | 
    
         
            +
            		}
         
     | 
| 
      
 17 
     | 
    
         
            +
            		@inv_sequences = Hash.new {|h,k| 
         
     | 
| 
      
 18 
     | 
    
         
            +
            			h[k] = Hash.new {|h2,k2| 
         
     | 
| 
      
 19 
     | 
    
         
            +
            				h2[k2]=0
         
     | 
| 
      
 20 
     | 
    
         
            +
            			} 
         
     | 
| 
      
 21 
     | 
    
         
            +
            		}
         
     | 
| 
      
 22 
     | 
    
         
            +
            	end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            	def self.from_context(language_specific_logic,context)
         
     | 
| 
      
 25 
     | 
    
         
            +
            		values_map = context.values_map
         
     | 
| 
      
 26 
     | 
    
         
            +
            		instance = new(language_specific_logic)	
         
     | 
| 
      
 27 
     | 
    
         
            +
            		values_map.each do |value,c|
         
     | 
| 
      
 28 
     | 
    
         
            +
            			value = value.to_s.strip
         
     | 
| 
      
 29 
     | 
    
         
            +
            			if language_specific_logic.terms_containing_value?(value)
         
     | 
| 
      
 30 
     | 
    
         
            +
            				words = language_specific_logic.to_words(value)				
         
     | 
| 
      
 31 
     | 
    
         
            +
            				first_words = words[0...-1]
         
     | 
| 
      
 32 
     | 
    
         
            +
            				instance.inv_sequences[words[0].downcase][:start] += c
         
     | 
| 
      
 33 
     | 
    
         
            +
            				first_words.each_with_index do |w,i|
         
     | 
| 
      
 34 
     | 
    
         
            +
            					instance.sequences[w.downcase][words[i+1].downcase] += c
         
     | 
| 
      
 35 
     | 
    
         
            +
            					instance.inv_sequences[words[i+1].downcase][w.downcase] += c
         
     | 
| 
      
 36 
     | 
    
         
            +
            				end
         
     | 
| 
      
 37 
     | 
    
         
            +
            				last_word = words.last
         
     | 
| 
      
 38 
     | 
    
         
            +
            				instance.sequences[last_word.downcase][:end] += c
         
     | 
| 
      
 39 
     | 
    
         
            +
            			else
         
     | 
| 
      
 40 
     | 
    
         
            +
            				# who cares, it will be never considered for composed names...
         
     | 
| 
      
 41 
     | 
    
         
            +
            			end
         
     | 
| 
      
 42 
     | 
    
         
            +
            		end
         
     | 
| 
      
 43 
     | 
    
         
            +
            		instance
         
     | 
| 
      
 44 
     | 
    
         
            +
            	end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            	def terms_in_value(value)
         
     | 
| 
      
 47 
     | 
    
         
            +
            		value = value.to_s.strip
         
     | 
| 
      
 48 
     | 
    
         
            +
            		if @language_specific_logic.terms_containing_value?(value)
         
     | 
| 
      
 49 
     | 
    
         
            +
            			words = @language_specific_logic.to_words(value)
         
     | 
| 
      
 50 
     | 
    
         
            +
            			group_words_in_terms(words).map{|w| w.downcase}			
         
     | 
| 
      
 51 
     | 
    
         
            +
            		else
         
     | 
| 
      
 52 
     | 
    
         
            +
            			[value]
         
     | 
| 
      
 53 
     | 
    
         
            +
            		end
         
     | 
| 
      
 54 
     | 
    
         
            +
            	end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
            	private
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
            	def frequent_straight_sequence?(w1,w2)
         
     | 
| 
      
 59 
     | 
    
         
            +
            		w1 = w1.downcase
         
     | 
| 
      
 60 
     | 
    
         
            +
            		w2 = w2.downcase
         
     | 
| 
      
 61 
     | 
    
         
            +
            		all_sequences_of_w1 = 0
         
     | 
| 
      
 62 
     | 
    
         
            +
            		@sequences[w1].each do |k,v|
         
     | 
| 
      
 63 
     | 
    
         
            +
            			all_sequences_of_w1 += v
         
     | 
| 
      
 64 
     | 
    
         
            +
            		end
         
     | 
| 
      
 65 
     | 
    
         
            +
            		sequences_w1_w2 = @sequences[w1][w2]
         
     | 
| 
      
 66 
     | 
    
         
            +
            		(sequences_w1_w2.to_f/all_sequences_of_w1.to_f)>0.5
         
     | 
| 
      
 67 
     | 
    
         
            +
            	end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
            	def frequent_inverse_sequence?(w1,w2)
         
     | 
| 
      
 70 
     | 
    
         
            +
            		w1 = w1.downcase
         
     | 
| 
      
 71 
     | 
    
         
            +
            		w2 = w2.downcase
         
     | 
| 
      
 72 
     | 
    
         
            +
            		all_inv_sequences_of_w1 = 0
         
     | 
| 
      
 73 
     | 
    
         
            +
            		@inv_sequences[w1].each do |k,v|
         
     | 
| 
      
 74 
     | 
    
         
            +
            			all_inv_sequences_of_w1 += v
         
     | 
| 
      
 75 
     | 
    
         
            +
            		end
         
     | 
| 
      
 76 
     | 
    
         
            +
            		inv_sequences_w1_w2 = @inv_sequences[w1][w2]
         
     | 
| 
      
 77 
     | 
    
         
            +
            		(inv_sequences_w1_w2.to_f/all_inv_sequences_of_w1.to_f)>0.5
         
     | 
| 
      
 78 
     | 
    
         
            +
            	end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
            	def frequent_sequence?(w1,w2)
         
     | 
| 
      
 81 
     | 
    
         
            +
            		return false unless w2
         
     | 
| 
      
 82 
     | 
    
         
            +
            		frequent_straight_sequence?(w1,w2) && frequent_inverse_sequence?(w2,w1)
         
     | 
| 
      
 83 
     | 
    
         
            +
            	end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
            	def group_words_in_terms(words)
         
     | 
| 
      
 86 
     | 
    
         
            +
            		# getNotSoGoodFieldName is not a term because
         
     | 
| 
      
 87 
     | 
    
         
            +
            		# notSoGoodFieldName is more frequently alone that preceded by get
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
            		return words if words.count==1
         
     | 
| 
      
 90 
     | 
    
         
            +
            		start_term = 0
         
     | 
| 
      
 91 
     | 
    
         
            +
            		end_term   = 0
         
     | 
| 
      
 92 
     | 
    
         
            +
            		term       = words[0]
         
     | 
| 
      
 93 
     | 
    
         
            +
            		while end_term < words.count && frequent_sequence?(words[end_term],words[end_term+1])
         
     | 
| 
      
 94 
     | 
    
         
            +
            			end_term += 1
         
     | 
| 
      
 95 
     | 
    
         
            +
            			term = @language_specific_logic.concat(term,words[end_term])
         
     | 
| 
      
 96 
     | 
    
         
            +
            		end
         
     | 
| 
      
 97 
     | 
    
         
            +
            		return [term] if end_term==(words.count-1)
         
     | 
| 
      
 98 
     | 
    
         
            +
            		[term] + group_words_in_terms(words[(end_term+1)..-1])
         
     | 
| 
      
 99 
     | 
    
         
            +
            	end
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
            end
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
            module InfoExtractionFunctionalities
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
            	def values_map
         
     | 
| 
      
 106 
     | 
    
         
            +
            		collect_values_with_count_subtree
         
     | 
| 
      
 107 
     | 
    
         
            +
            	end
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
            	def terms_map(language_specific_logic,context=nil)
         
     | 
| 
      
 110 
     | 
    
         
            +
            		# context default to root
         
     | 
| 
      
 111 
     | 
    
         
            +
            		unless context
         
     | 
| 
      
 112 
     | 
    
         
            +
            			context = self
         
     | 
| 
      
 113 
     | 
    
         
            +
            			while context.eContainer
         
     | 
| 
      
 114 
     | 
    
         
            +
            				context = context.eContainer
         
     | 
| 
      
 115 
     | 
    
         
            +
            			end		
         
     | 
| 
      
 116 
     | 
    
         
            +
            		end
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
            		# look into context to see how frequent are certain series of words,
         
     | 
| 
      
 119 
     | 
    
         
            +
            		# frequent series are recognized as composed terms
         
     | 
| 
      
 120 
     | 
    
         
            +
            		terms_breaker = TermsBreaker.from_context(language_specific_logic,context)
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
            		v_map = self.values_map
         
     | 
| 
      
 123 
     | 
    
         
            +
            		terms_map = Hash.new {|h,k| h[k]=0}
         
     | 
| 
      
 124 
     | 
    
         
            +
            		v_map.each do |v,n|
         
     | 
| 
      
 125 
     | 
    
         
            +
            			terms_breaker.terms_in_value(v).each do |t|
         
     | 
| 
      
 126 
     | 
    
         
            +
            				terms_map[t] += n
         
     | 
| 
      
 127 
     | 
    
         
            +
            			end
         
     | 
| 
      
 128 
     | 
    
         
            +
            		end
         
     | 
| 
      
 129 
     | 
    
         
            +
            		terms_map
         
     | 
| 
      
 130 
     | 
    
         
            +
            	end
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
            end
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
            class ::RGen::MetamodelBuilder::MMBase
         
     | 
| 
      
 135 
     | 
    
         
            +
            	include InfoExtractionFunctionalities
         
     | 
| 
      
 136 
     | 
    
         
            +
            end
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
            end
         
     | 
| 
      
 139 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,65 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module CodeModels
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            @@languages = []
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            class Parser
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            	def parse_file(path)
         
     | 
| 
      
 8 
     | 
    
         
            +
            		code = IO.read(path)
         
     | 
| 
      
 9 
     | 
    
         
            +
            		parse_code(code)
         
     | 
| 
      
 10 
     | 
    
         
            +
            	end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            module CodeModelsReflectionInfo
         
     | 
| 
      
 15 
     | 
    
         
            +
            	attr_accessor :source
         
     | 
| 
      
 16 
     | 
    
         
            +
            	attr_accessor :language
         
     | 
| 
      
 17 
     | 
    
         
            +
            end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            class Position
         
     | 
| 
      
 20 
     | 
    
         
            +
            	attr_accessor :line, :column
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            class SourceInfo
         
     | 
| 
      
 24 
     | 
    
         
            +
            	attr_accessor :filename
         
     | 
| 
      
 25 
     | 
    
         
            +
            	attr_accessor :begin_pos, :end_pos
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            	def to_code
         
     | 
| 
      
 28 
     | 
    
         
            +
            		raise "Unimplemented"
         
     | 
| 
      
 29 
     | 
    
         
            +
            	end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            class Language
         
     | 
| 
      
 34 
     | 
    
         
            +
            	attr_reader :name
         
     | 
| 
      
 35 
     | 
    
         
            +
            	attr_reader :extensions
         
     | 
| 
      
 36 
     | 
    
         
            +
            	attr_reader :parser
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            	def initialize(name)
         
     | 
| 
      
 39 
     | 
    
         
            +
            		@name = name
         
     | 
| 
      
 40 
     | 
    
         
            +
            		@extensions = []
         
     | 
| 
      
 41 
     | 
    
         
            +
            	end	
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            	def can_parse?(path)
         
     | 
| 
      
 44 
     | 
    
         
            +
            		extension = File.extname(path)
         
     | 
| 
      
 45 
     | 
    
         
            +
            		extension=extension[1..-1] if extension.length>0		
         
     | 
| 
      
 46 
     | 
    
         
            +
            		@extensions.include?(extension)
         
     | 
| 
      
 47 
     | 
    
         
            +
            	end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
            end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            def self.register_language(language)
         
     | 
| 
      
 52 
     | 
    
         
            +
            	@@languages << language
         
     | 
| 
      
 53 
     | 
    
         
            +
            end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            def self.registered_languages
         
     | 
| 
      
 56 
     | 
    
         
            +
            	@@languages
         
     | 
| 
      
 57 
     | 
    
         
            +
            end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            def self.parse_file(path)
         
     | 
| 
      
 60 
     | 
    
         
            +
            	l = @@languages.find {|l| l.can_parse?(path) }
         
     | 
| 
      
 61 
     | 
    
         
            +
            	raise "I don't know how to parse #{path}. Languages known: #{@@languages.map(&:name)}" unless l
         
     | 
| 
      
 62 
     | 
    
         
            +
            	l.parser.parse_file(path)
         
     | 
| 
      
 63 
     | 
    
         
            +
            end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,81 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'codemodels/serialization'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module CodeModels
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module ModelBuilding
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            class << self
         
     | 
| 
      
 8 
     | 
    
         
            +
            	attr_accessor :verbose
         
     | 
| 
      
 9 
     | 
    
         
            +
            end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            def self.verbose_warn(msg)
         
     | 
| 
      
 12 
     | 
    
         
            +
            	warn(msg) if verbose
         
     | 
| 
      
 13 
     | 
    
         
            +
            end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            def self.handle_serialized_models_in_dir(src,src_extension,error_handler=nil,model_handler,&model_creator)
         
     | 
| 
      
 16 
     | 
    
         
            +
            	Dir["#{src}/**/*.#{src_extension}"].each do |fd|
         
     | 
| 
      
 17 
     | 
    
         
            +
            		verbose_warn "== #{fd} =="
         
     | 
| 
      
 18 
     | 
    
         
            +
            		handle_serialized_model_per_file(fd,error_handler,model_handler,&model_creator)		
         
     | 
| 
      
 19 
     | 
    
         
            +
            	end
         
     | 
| 
      
 20 
     | 
    
         
            +
            end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            def self.handle_models_in_dir(src,src_extension,error_handler=nil,model_handler,&model_creator)
         
     | 
| 
      
 23 
     | 
    
         
            +
            	Dir["#{src}/**/*.#{src_extension}"].each do |fd|	
         
     | 
| 
      
 24 
     | 
    
         
            +
            		verbose_warn "== #{fd} =="			
         
     | 
| 
      
 25 
     | 
    
         
            +
            		handle_model_per_file(fd,error_handler,model_handler,&model_creator)		
         
     | 
| 
      
 26 
     | 
    
         
            +
            	end
         
     | 
| 
      
 27 
     | 
    
         
            +
            end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            def self.generate_models_in_dir(src,dest,src_extension,dest_extension,max_nesting=500,error_handler=nil,&model_creator)
         
     | 
| 
      
 30 
     | 
    
         
            +
            	verbose_warn "== #{src} -> #{dest} =="
         
     | 
| 
      
 31 
     | 
    
         
            +
            	Dir["#{src}/**/*.#{src_extension}"].each do |fd|		
         
     | 
| 
      
 32 
     | 
    
         
            +
            		if File.directory? fd
         
     | 
| 
      
 33 
     | 
    
         
            +
            			basename = File.basename(fd)
         
     | 
| 
      
 34 
     | 
    
         
            +
            			generate_models_in_dir("#{src}/#{basename}","#{dest}/#{basename}",src_extension,dest_extension,max_nesting,error_handler,&model_creator)
         
     | 
| 
      
 35 
     | 
    
         
            +
            		else
         
     | 
| 
      
 36 
     | 
    
         
            +
            			if File.extname(fd)==".#{src_extension}"
         
     | 
| 
      
 37 
     | 
    
         
            +
            				translated_simple_name = "#{File.basename(fd, ".#{src_extension}")}.#{dest_extension}"
         
     | 
| 
      
 38 
     | 
    
         
            +
            				translated_name = "#{dest}/#{translated_simple_name}"
         
     | 
| 
      
 39 
     | 
    
         
            +
            				verbose_warn "* #{fd} --> #{translated_name}"
         
     | 
| 
      
 40 
     | 
    
         
            +
            				generate_model_per_file(fd,translated_name,max_nesting,error_handler,&model_creator)
         
     | 
| 
      
 41 
     | 
    
         
            +
            			end
         
     | 
| 
      
 42 
     | 
    
         
            +
            		end
         
     | 
| 
      
 43 
     | 
    
         
            +
            	end
         
     | 
| 
      
 44 
     | 
    
         
            +
            end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            def self.handle_model_per_file(src,error_handler=nil,model_handler,&models_generator)
         
     | 
| 
      
 47 
     | 
    
         
            +
            	verbose_warn "<Model from #{src}>"
         
     | 
| 
      
 48 
     | 
    
         
            +
            	begin
         
     | 
| 
      
 49 
     | 
    
         
            +
            		m = models_generator.call(src)
         
     | 
| 
      
 50 
     | 
    
         
            +
            		model_handler.call(src,m)
         
     | 
| 
      
 51 
     | 
    
         
            +
            	rescue => e
         
     | 
| 
      
 52 
     | 
    
         
            +
            		if error_handler
         
     | 
| 
      
 53 
     | 
    
         
            +
            			error_handler.call(src,e)
         
     | 
| 
      
 54 
     | 
    
         
            +
            		else
         
     | 
| 
      
 55 
     | 
    
         
            +
            			raise e
         
     | 
| 
      
 56 
     | 
    
         
            +
            		end
         
     | 
| 
      
 57 
     | 
    
         
            +
            	end
         
     | 
| 
      
 58 
     | 
    
         
            +
            end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
            def self.generate_model_per_file(src,dest,max_nesting=500,error_handler=nil,&models_generator)
         
     | 
| 
      
 61 
     | 
    
         
            +
            	if not File.exist? dest 
         
     | 
| 
      
 62 
     | 
    
         
            +
            		verbose_warn "<Model from #{src}>"
         
     | 
| 
      
 63 
     | 
    
         
            +
            		
         
     | 
| 
      
 64 
     | 
    
         
            +
            		begin
         
     | 
| 
      
 65 
     | 
    
         
            +
            			m = models_generator.call(src)
         
     | 
| 
      
 66 
     | 
    
         
            +
            			LightModels::Serialization.save_model(m,dest,max_nesting)
         
     | 
| 
      
 67 
     | 
    
         
            +
            		rescue Exception => e
         
     | 
| 
      
 68 
     | 
    
         
            +
            			if error_handler
         
     | 
| 
      
 69 
     | 
    
         
            +
            				error_handler.call(src,e)
         
     | 
| 
      
 70 
     | 
    
         
            +
            			else
         
     | 
| 
      
 71 
     | 
    
         
            +
            				raise e
         
     | 
| 
      
 72 
     | 
    
         
            +
            			end
         
     | 
| 
      
 73 
     | 
    
         
            +
            		end		
         
     | 
| 
      
 74 
     | 
    
         
            +
            	else
         
     | 
| 
      
 75 
     | 
    
         
            +
            		verbose_warn "skipping #{src} because #{dest} found"
         
     | 
| 
      
 76 
     | 
    
         
            +
            	end
         
     | 
| 
      
 77 
     | 
    
         
            +
            end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
            end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,30 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Module
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
              def simple_name
         
     | 
| 
      
 4 
     | 
    
         
            +
                if (i = (r = name).rindex(':')) then r[0..i] = '' end
         
     | 
| 
      
 5 
     | 
    
         
            +
                r
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
              
         
     | 
| 
      
 8 
     | 
    
         
            +
            end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            class String
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            	def remove_postfix(postfix)
         
     | 
| 
      
 13 
     | 
    
         
            +
            		raise "'#{self}'' have not the right postfix '#{postfix}'" unless end_with?(postfix)
         
     | 
| 
      
 14 
     | 
    
         
            +
            		self[0..-(1+postfix.length)]
         
     | 
| 
      
 15 
     | 
    
         
            +
            	end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            	def remove_prefix(prefix)
         
     | 
| 
      
 18 
     | 
    
         
            +
            		raise "'#{self}'' have not the right prefix '#{prefix}'" unless start_with?(prefix)
         
     | 
| 
      
 19 
     | 
    
         
            +
            		self[prefix.length..-1]
         
     | 
| 
      
 20 
     | 
    
         
            +
            	end
         
     | 
| 
      
 21 
     | 
    
         
            +
            	
         
     | 
| 
      
 22 
     | 
    
         
            +
            	def proper_capitalize 
         
     | 
| 
      
 23 
     | 
    
         
            +
                	self[0, 1].upcase + self[1..-1]
         
     | 
| 
      
 24 
     | 
    
         
            +
              	end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            	def proper_uncapitalize 
         
     | 
| 
      
 27 
     | 
    
         
            +
                	self[0, 1].downcase + self[1..-1]
         
     | 
| 
      
 28 
     | 
    
         
            +
              	end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            end	
         
     | 
| 
         @@ -0,0 +1,184 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'codemodels/monkey_patching'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module CodeModels
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            class ParsingError < Exception
         
     | 
| 
      
 6 
     | 
    
         
            +
             	attr_reader :node
         
     | 
| 
      
 7 
     | 
    
         
            +
             	attr_reader :line
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
             	def initialize(node,msg,line=nil)
         
     | 
| 
      
 10 
     | 
    
         
            +
             		@node = node
         
     | 
| 
      
 11 
     | 
    
         
            +
             		@msg = msg
         
     | 
| 
      
 12 
     | 
    
         
            +
             		@line = lin
         
     | 
| 
      
 13 
     | 
    
         
            +
             	end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
             	def to_s
         
     | 
| 
      
 16 
     | 
    
         
            +
             		"#{@msg}, start line: #{@line}"
         
     | 
| 
      
 17 
     | 
    
         
            +
             	end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            class UnknownNodeType < ParsingError
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
             	def initialize(node,line=nil,node_type=nil,where=nil)
         
     | 
| 
      
 24 
     | 
    
         
            +
             		super(node,"UnknownNodeType: type=#{node_type} , where: #{where}")
         
     | 
| 
      
 25 
     | 
    
         
            +
             	end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            module ParserWrapper
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            @@verbose = false
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            JavaCollection = ::Java::JavaClass.for_name("java.util.Collection")
         
     | 
| 
      
 34 
     | 
    
         
            +
            	
         
     | 
| 
      
 35 
     | 
    
         
            +
            def adapter(model_class,ref)
         
     | 
| 
      
 36 
     | 
    
         
            +
            	if adapter_specific_class(model_class,ref)
         
     | 
| 
      
 37 
     | 
    
         
            +
            		adapter_specific_class(model_class,ref)
         
     | 
| 
      
 38 
     | 
    
         
            +
            	else
         
     | 
| 
      
 39 
     | 
    
         
            +
            		if model_class.superclass!=Object
         
     | 
| 
      
 40 
     | 
    
         
            +
            			adapter(model_class.superclass,ref) 
         
     | 
| 
      
 41 
     | 
    
         
            +
            		else
         
     | 
| 
      
 42 
     | 
    
         
            +
            			nil
         
     | 
| 
      
 43 
     | 
    
         
            +
            		end
         
     | 
| 
      
 44 
     | 
    
         
            +
            	end
         
     | 
| 
      
 45 
     | 
    
         
            +
            end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
            def reference_to_method(model_class,ref)
         
     | 
| 
      
 48 
     | 
    
         
            +
            	s = ref.name
         
     | 
| 
      
 49 
     | 
    
         
            +
            	#s = 'value' if s=='body'
         
     | 
| 
      
 50 
     | 
    
         
            +
            	adapted = adapter(model_class,ref)
         
     | 
| 
      
 51 
     | 
    
         
            +
            	s = adapted if adapted		
         
     | 
| 
      
 52 
     | 
    
         
            +
            	s.to_sym
         
     | 
| 
      
 53 
     | 
    
         
            +
            end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            def attribute_to_method(model_class,att)
         
     | 
| 
      
 56 
     | 
    
         
            +
            	s = att.name
         
     | 
| 
      
 57 
     | 
    
         
            +
            	adapted = adapter(model_class,att)
         
     | 
| 
      
 58 
     | 
    
         
            +
            	s = adapted if adapted		
         
     | 
| 
      
 59 
     | 
    
         
            +
            	s.to_sym
         
     | 
| 
      
 60 
     | 
    
         
            +
            end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
            def assign_ref_to_model(model,ref,value)
         
     | 
| 
      
 63 
     | 
    
         
            +
            	return unless value==nil # we do not need to assign a nil...
         
     | 
| 
      
 64 
     | 
    
         
            +
            	if ref.many
         
     | 
| 
      
 65 
     | 
    
         
            +
            		adder_method = :"add#{ref.name.capitalize}"
         
     | 
| 
      
 66 
     | 
    
         
            +
            		value.each {|el| model.send(adder_method,node_to_model(el))}
         
     | 
| 
      
 67 
     | 
    
         
            +
            	else
         
     | 
| 
      
 68 
     | 
    
         
            +
            		setter_method = :"#{ref.name}="
         
     | 
| 
      
 69 
     | 
    
         
            +
            		raise "Trying to assign an array to a single property. Class #{model.class}, property #{ref.name}" if value.is_a?(::Array)
         
     | 
| 
      
 70 
     | 
    
         
            +
            		model.send(setter_method,node_to_model(value))
         
     | 
| 
      
 71 
     | 
    
         
            +
            	end
         
     | 
| 
      
 72 
     | 
    
         
            +
            rescue Object => e
         
     | 
| 
      
 73 
     | 
    
         
            +
            	puts "Problem while assigning ref #{ref.name} (many? #{ref.many}) to #{model.class}. Value: #{value.class}"
         
     | 
| 
      
 74 
     | 
    
         
            +
            	puts "\t<<#{e}>>"
         
     | 
| 
      
 75 
     | 
    
         
            +
            	raise e
         
     | 
| 
      
 76 
     | 
    
         
            +
            end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
            def assign_att_to_model(model,att,value)
         
     | 
| 
      
 79 
     | 
    
         
            +
            	if att.many
         
     | 
| 
      
 80 
     | 
    
         
            +
            		adder_method = :"add#{att.name.capitalize}"
         
     | 
| 
      
 81 
     | 
    
         
            +
            		value.each {|el| model.send(adder_method,el)}
         
     | 
| 
      
 82 
     | 
    
         
            +
            	else
         
     | 
| 
      
 83 
     | 
    
         
            +
            		setter_method = :"#{att.name}="
         
     | 
| 
      
 84 
     | 
    
         
            +
            		raise "Trying to assign an array to a single property. Class #{model.class}, property #{att.name}" if value.is_a?(::Array)
         
     | 
| 
      
 85 
     | 
    
         
            +
            		model.send(setter_method,value)
         
     | 
| 
      
 86 
     | 
    
         
            +
            	end
         
     | 
| 
      
 87 
     | 
    
         
            +
            end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
            def populate_attr(node,att,model)	
         
     | 
| 
      
 90 
     | 
    
         
            +
            	value = get_feature_value(node,att)
         
     | 
| 
      
 91 
     | 
    
         
            +
            	model.send(:"#{att.name}=",value) if value!=nil
         
     | 
| 
      
 92 
     | 
    
         
            +
            rescue Object => e
         
     | 
| 
      
 93 
     | 
    
         
            +
            	puts "Problem while populating attribute #{att.name} of #{model} from #{node}. Value: #{value}"
         
     | 
| 
      
 94 
     | 
    
         
            +
            	raise e
         
     | 
| 
      
 95 
     | 
    
         
            +
            end
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
            def populate_ref(node,ref,model)
         
     | 
| 
      
 98 
     | 
    
         
            +
            	log("populate ref #{ref.name}, node: #{node.class}, model: #{model.class}")
         
     | 
| 
      
 99 
     | 
    
         
            +
            	value = get_feature_value(node,ref)
         
     | 
| 
      
 100 
     | 
    
         
            +
            	log("\tvalue=#{value.class}")
         
     | 
| 
      
 101 
     | 
    
         
            +
            	if value!=nil
         
     | 
| 
      
 102 
     | 
    
         
            +
            		if value==node
         
     | 
| 
      
 103 
     | 
    
         
            +
            			puts "avoiding loop... #{ref.name}, class #{node.class}" 
         
     | 
| 
      
 104 
     | 
    
         
            +
            			return
         
     | 
| 
      
 105 
     | 
    
         
            +
            		end
         
     | 
| 
      
 106 
     | 
    
         
            +
            		if JavaCollection.assignable_from?(value.java_class)
         
     | 
| 
      
 107 
     | 
    
         
            +
            			log("\tvalue is a collection")
         
     | 
| 
      
 108 
     | 
    
         
            +
            			capitalized_name = ref.name.proper_capitalize				
         
     | 
| 
      
 109 
     | 
    
         
            +
            			value.each do |el|
         
     | 
| 
      
 110 
     | 
    
         
            +
            				unless el.respond_to?(:parent)
         
     | 
| 
      
 111 
     | 
    
         
            +
            					class << el
         
     | 
| 
      
 112 
     | 
    
         
            +
            						attr_accessor :parent						
         
     | 
| 
      
 113 
     | 
    
         
            +
            					end
         
     | 
| 
      
 114 
     | 
    
         
            +
            				end
         
     | 
| 
      
 115 
     | 
    
         
            +
            				el.parent = node
         
     | 
| 
      
 116 
     | 
    
         
            +
            				model.send(:"add#{capitalized_name}",node_to_model(el))
         
     | 
| 
      
 117 
     | 
    
         
            +
            			end
         
     | 
| 
      
 118 
     | 
    
         
            +
            		else
         
     | 
| 
      
 119 
     | 
    
         
            +
            			log("\tvalue is not a collection")
         
     | 
| 
      
 120 
     | 
    
         
            +
            			unless value.respond_to?(:parent)
         
     | 
| 
      
 121 
     | 
    
         
            +
            				value.class.__persistent__ = true
         
     | 
| 
      
 122 
     | 
    
         
            +
            				class << value
         
     | 
| 
      
 123 
     | 
    
         
            +
            					attr_accessor :parent
         
     | 
| 
      
 124 
     | 
    
         
            +
            				end
         
     | 
| 
      
 125 
     | 
    
         
            +
            			end
         
     | 
| 
      
 126 
     | 
    
         
            +
            			value.parent = node
         
     | 
| 
      
 127 
     | 
    
         
            +
            			model.send(:"#{ref.name}=",node_to_model(value))
         
     | 
| 
      
 128 
     | 
    
         
            +
            		end
         
     | 
| 
      
 129 
     | 
    
         
            +
            	end
         
     | 
| 
      
 130 
     | 
    
         
            +
            end
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
            def log(msg)
         
     | 
| 
      
 133 
     | 
    
         
            +
            	puts msg if @@verbose
         
     | 
| 
      
 134 
     | 
    
         
            +
            end
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
            def node_to_model(node)
         
     | 
| 
      
 137 
     | 
    
         
            +
            	log("node_to_model #{node.class}")
         
     | 
| 
      
 138 
     | 
    
         
            +
            	metaclass = get_corresponding_metaclass(node)
         
     | 
| 
      
 139 
     | 
    
         
            +
            	instance = metaclass.new
         
     | 
| 
      
 140 
     | 
    
         
            +
            	metaclass.ecore.eAllAttributes.each do |attr|
         
     | 
| 
      
 141 
     | 
    
         
            +
            		populate_attr(node,attr,instance)
         
     | 
| 
      
 142 
     | 
    
         
            +
            	end
         
     | 
| 
      
 143 
     | 
    
         
            +
            	metaclass.ecore.eAllReferences.each do |ref|
         
     | 
| 
      
 144 
     | 
    
         
            +
            		populate_ref(node,ref,instance)
         
     | 
| 
      
 145 
     | 
    
         
            +
            	end
         
     | 
| 
      
 146 
     | 
    
         
            +
            	instance
         
     | 
| 
      
 147 
     | 
    
         
            +
            end
         
     | 
| 
      
 148 
     | 
    
         
            +
             
     | 
| 
      
 149 
     | 
    
         
            +
            def transform_enum_values(value)
         
     | 
| 
      
 150 
     | 
    
         
            +
            	if value.respond_to?(:java_class) && value.java_class.enum?
         
     | 
| 
      
 151 
     | 
    
         
            +
            		value.name
         
     | 
| 
      
 152 
     | 
    
         
            +
            	else
         
     | 
| 
      
 153 
     | 
    
         
            +
            		value
         
     | 
| 
      
 154 
     | 
    
         
            +
            	end
         
     | 
| 
      
 155 
     | 
    
         
            +
            end
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
            def get_feature_value_through_getter(node,feat_name)
         
     | 
| 
      
 158 
     | 
    
         
            +
            	capitalized_name = feat_name.proper_capitalize
         
     | 
| 
      
 159 
     | 
    
         
            +
            	methods = [:"get#{capitalized_name}",:"is#{capitalized_name}"]
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
            	methods.each do |m|
         
     | 
| 
      
 162 
     | 
    
         
            +
            		if node.respond_to?(m)
         
     | 
| 
      
 163 
     | 
    
         
            +
            			begin
         
     | 
| 
      
 164 
     | 
    
         
            +
            				return transform_enum_values(node.send(m))
         
     | 
| 
      
 165 
     | 
    
         
            +
            			rescue Object => e
         
     | 
| 
      
 166 
     | 
    
         
            +
            				raise "Problem invoking #{m} on #{node.class}: #{e}"
         
     | 
| 
      
 167 
     | 
    
         
            +
            			end
         
     | 
| 
      
 168 
     | 
    
         
            +
            		end
         
     | 
| 
      
 169 
     | 
    
         
            +
            	end
         
     | 
| 
      
 170 
     | 
    
         
            +
            	raise "how should I get this... #{feat_name} on #{node.class}. It does not respond to #{methods}"
         
     | 
| 
      
 171 
     | 
    
         
            +
            end
         
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
      
 173 
     | 
    
         
            +
            def get_feature_value(node,feat)
         
     | 
| 
      
 174 
     | 
    
         
            +
            	adapter = adapter(node.class,feat)		
         
     | 
| 
      
 175 
     | 
    
         
            +
            	if adapter
         
     | 
| 
      
 176 
     | 
    
         
            +
            		adapter[:adapter].call(node)
         
     | 
| 
      
 177 
     | 
    
         
            +
            	else
         
     | 
| 
      
 178 
     | 
    
         
            +
            		get_feature_value_through_getter(node,feat.name)
         
     | 
| 
      
 179 
     | 
    
         
            +
            	end
         
     | 
| 
      
 180 
     | 
    
         
            +
            end
         
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
      
 182 
     | 
    
         
            +
            end
         
     | 
| 
      
 183 
     | 
    
         
            +
             
     | 
| 
      
 184 
     | 
    
         
            +
            end
         
     |