Module: When::Parts::Resource

Extended by:
Pool
Includes:
Namespace
Included in:
BasicTypes::M17n, BasicTypes::Object, Events::DataSets, TM::Position, TM::TemporalPosition
Defined in:
lib/when_exe/parts/resource.rb

Overview

Resource which has 'International Resource Identifier'

Defined Under Namespace

Modules: Navigation, Pool

Constant Summary

Constants included from Namespace

Namespace::DC, Namespace::DCQ, Namespace::DCT, Namespace::FOAF, Namespace::OWL, Namespace::RDF, Namespace::RDFC, Namespace::RDFS, Namespace::RSS, Namespace::XSD

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Pool

[]=, _setup_

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object (private)

その他のメソッド

When::Parts::Resource で定義されていないメソッドは
処理を @child (type: Array) に委譲する


1135
1136
1137
1138
1139
1140
1141
1142
1143
# File 'lib/when_exe/parts/resource.rb', line 1135

def method_missing(name, *args, &block)
  return __method_missing(name, *args, &block) if When::Parts::MethodCash::Escape.key?(name)
  self.class.module_eval %Q{
    def #{name}(*args, &block)
      @child.send("#{name}", *args, &block)
    end
  } unless When::Parts::MethodCash.escape(name)
  @child.send(name, *args, &block)
end

Instance Attribute Details

#childArray<When::Parts::Resource>

self が has-a 関係で包含するオブジェクト



749
750
751
# File 'lib/when_exe/parts/resource.rb', line 749

def child
  @child
end

#keysArray<String> (readonly)

strftime で有効な locale

Returns:



777
778
779
# File 'lib/when_exe/parts/resource.rb', line 777

def keys
  @keys
end

#localeArray<String> (readonly)

Resource包含階層で使用する locale

When::BasicTypes::M17n の生成に使用する locale を定義する。
RFC 5545 に対する拡張である。

Returns:



771
772
773
# File 'lib/when_exe/parts/resource.rb', line 771

def locale
  @locale
end

#namespaceHash (readonly)

Resource包含階層で使用する namespace

When::BasicTypes::M17n の生成に使用する namespace を定義する。
RFC 5545 に対する拡張である。
xml で記述する場合には、本ライブラリ以外でも namespace を定義している。

Returns:

  • (Hash)

    { prefix => prefix文字列 }



761
762
763
# File 'lib/when_exe/parts/resource.rb', line 761

def namespace
  @namespace
end

Class Method Details

._instance(iri, namespace = nil, &block) ⇒ When::Parts::Resource

オブジェクト生成&参照

指定した iri の When::Parts::Resource オブジェクトを取得する。 当該オブジェクトが未登録であれば生成する。

Parameters:

  • iri (String)

    International Resource Identifier

  • namespace (String) (defaults to: nil)

    (デフォルトの名前空間, 指定がないときは名前空間を省略しない)

  • block (Block)

    オブジェクトやパスが見つからない場合の代替処理

Returns:



341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
# File 'lib/when_exe/parts/resource.rb', line 341

def _instance(iri, namespace=nil, &block)
  _setup_ unless @_pool

  case iri
  when Array    ; return iri.map {|e| _instance(e, namespace)}                  # 配列は個別に処理
  when Resource ; return iri                                                    # 登録済みはそのまま
  when String   ;                                                               # 解析処理へ
  else          ; raise ArgumentError, "can't convert #{iri.class} to String"   # 例外
  end

  # 内部文字列化
  iri = When::EncodingConversion.to_internal_encoding(iri)

  # 階層がある場合は、階層をたどる
  iri = Resource._decode(iri)
  iri = $1 while iri =~ /\A\((.*)\)\z/
  iri = namespace + iri if namespace && iri !~ IRIHeader
  root, *leaves= Resource._encode(iri).split(/::/)
  if leaves.size > 0
    return leaves.inject(_instance(Resource._decode(root))) {|obj,leaf| obj[Resource._decode(leaf)]}
  end

  # 登録ずみなら、参照
  iri = _extract_prefix(iri)
  path, query = iri.split(/\?/, 2)
  if When.multi_thread
    my_mutex = nil
    @_lock_.synchronize do
      @_pool ||= {}
      unless @_pool[iri]
        my_mutex    = Mutex.new
        @_pool[iri] = my_mutex
      end
    end
    case @_pool[iri]
    when my_mutex
      my_mutex.synchronize do
        begin
          @_pool[iri] = _create_object(iri, path, query, &block)
        rescue => exception
          @_pool[iri] = nil
          raise exception
        end
      end
    when Mutex
      @_pool[iri].synchronize do
        @_pool[iri]
      end
    else
      @_pool[iri]
    end
  else
    @_pool      ||= {}
    @_pool[iri] ||= _create_object(iri, path, query, &block)
  end
end

._setup_(options = {}) ⇒ void

Note:

本メソッドでマルチスレッド対応の管理変数の初期化を行っている。 このため、本メソッド自体はスレッドセーフでない。

This method returns an undefined value.

初期化

Parameters:

  • options (Hash) (defaults to: {})

    以下の通り

Options Hash (options):

  • :base_uri (String)

    Base URI for When_exe Resources (Default When::SourceURI)

  • :additional_namespaces (Hash<String(namespace)=>String(URI)>)

    User defined namespaces (Default {})

  • :root_dir (String)

    Root Directory for When_exe Resources Cash data (Default When::RootDir)

  • :leave_const (Boolean)

    If true, leave Constants of When module defined



287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
# File 'lib/when_exe/parts/resource.rb', line 287

def _setup_(options={})
  super()
  @_prefix = {
    '_wp'  => 'https://en.wikipedia.org/wiki/',
    '_w'   => base_uri + '/',
    '_p'   => base_uri + 'Parts/',
    '_b'   => base_uri + 'BasicTypes/',
    '_m'   => base_uri + 'BasicTypes/M17n/',
    '_co'  => base_uri + 'Coordinates/',
    '_l'   => base_uri + 'Coordinates/Spatial?',
    '_v'   => base_uri + 'V/',
    '_rs'  => base_uri + 'RS/',
    '_ex'  => base_uri + 'EX/',
    '_tm'  => base_uri + 'TM/',
    '_e'   => base_uri + 'TM/CalendarEra/',
    '_t'   => base_uri + 'TimeStandard/',
    '_ep'  => base_uri + 'Ephemeris/',
    '_c'   => base_uri + 'CalendarTypes/',
    '_n'   => base_uri + 'CalendarNote/',
    '_sc'  => base_uri + 'Ephemeris/V50/'
  }
  @base_uri       = options[:base_uri] || When::SourceURI
  @root_dir       = options[:root_dir] || When::RootDir
  @_prefix        = options[:additional_namespaces].merge(@_prefix) if options[:additional_namespaces].kind_of?(Hash)
  @_prefix_values = @_prefix.values.sort.reverse
  @_prefix_index  = @_prefix.invert
  unless options[:leave_const] || ConstList.empty?
    ConstList.delete_if do |constant|
      When.send(:remove_const, constant) if When.const_defined?(constant)
      true
    end
    When._define_common_calendar_types
  end
end

._setup_infoHash

設定情報を取得する

Returns:

  • (Hash)

    設定情報



326
327
328
# File 'lib/when_exe/parts/resource.rb', line 326

def _setup_info
  {:base_uri => base_uri, :root_dir => root_dir}
end

.base_uriString

Base URI for When_exe Resources

Returns:



236
237
238
# File 'lib/when_exe/parts/resource.rb', line 236

def base_uri
  @base_uri ||= When::SourceURI
end

.root_dirString

Root Directory for When_exe Resources

Returns:



244
245
246
# File 'lib/when_exe/parts/resource.rb', line 244

def root_dir
  @root_dir ||= When::RootDir
end

Instance Method Details

#[](iri) ⇒ When::parts::Resource

IRI または child の番号によるオブジェクト参照

Parameters:

  • iri (String)

    オブジェクトの IRI

  • iri (Numeric)

    child の index

Returns:

  • (When::parts::Resource)


806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
# File 'lib/when_exe/parts/resource.rb', line 806

def [](iri)
  case iri
  when Numeric
    return child[iri * 1]
  when String
    obj = self
    Resource._encode(iri).split(/::/).each do |label|
      return obj.child if label == '*'
      if obj == Resource
        obj = Resource._instance(Resource._decode(label))
      else
        case label
        when ''  ; obj = Resource
        when '.' # obj = obj
        else     ; obj = obj._pool[Resource._decode(label)]
        end
      end
      raise ArgumentError, "IRI not found: #{iri}" unless obj
    end
    return obj
  else
    super(iri)
    #raise ArgumentError, "IRI not found: #{iri}"
  end
end

#^(other) ⇒ Enumerator

Enumerator 生成のダミー

Parameters:

  • other (Object)

Returns:



942
943
944
# File 'lib/when_exe/parts/resource.rb', line 942

def ^(other)
  return nil
end

#each(*args, &block) ⇒ Enumerator

順次実行

Parameters:

  • args (Array)

    各サブクラスの enum_for にそのまま渡す

  • block (Block)

    実行するブロック

Returns:



953
954
955
956
957
# File 'lib/when_exe/parts/resource.rb', line 953

def each(*args, &block)
  enum = enum_for(*args)
  return enum unless block
  enum.each(&block)
end

#enum_forObject Also known as: to_enum

子オブジェクトを順に取り出す enumerator



931
932
933
# File 'lib/when_exe/parts/resource.rb', line 931

def enum_for
  @child.enum_for
end

#hierarchy(klass = self.class) ⇒ When::Parts::Resource

self を包含するオブジェクト階層

Parameters:

  • klass (Class) (defaults to: self.class)

    階層を遡るクラス

Returns:



846
847
848
849
850
851
852
853
854
# File 'lib/when_exe/parts/resource.rb', line 846

def hierarchy(klass=self.class)
  hierarchy = []
  parent    = self
  while parent.kind_of?(klass)
    hierarchy << parent
    parent = parent.parent
  end
  hierarchy.reverse
end

#include?(other) ⇒ Boolean

self が other を包含するか

Returns:

  • (Boolean)
    true - 包含する
    false - 包含しない


862
863
864
865
866
867
868
869
# File 'lib/when_exe/parts/resource.rb', line 862

def include?(other)
  c = other
  while c.kind_of?(Resource)
    return true if c.equal?(self)
    c = c.parent
  end
  return false
end

#included?(other) ⇒ Boolean

other が self を包含するか

Returns:

  • (Boolean)
    true - 包含される
    false - 包含されない


877
878
879
# File 'lib/when_exe/parts/resource.rb', line 877

def included?(other)
  other.include?(self)
end

#iri(prefix = false) ⇒ Sring

オブジェクトの IRI

Parameters:

  • prefix (Boolean) (defaults to: false)

    true ならIRI の先頭部分を簡約表現にする

Returns:

  • (Sring)


785
786
787
788
789
790
791
792
793
794
795
796
797
# File 'lib/when_exe/parts/resource.rb', line 785

def iri(prefix=false)
  return nil unless @_pool
  unless @iri
    root = @_pool['..']
    path = root.instance_of?(String) ? root : label.to_s
    if root.respond_to?(:iri)
      root_iri = root.iri
      path = root_iri + '::' + path.gsub(/[<>]/) {|char|'%' + char.ord.to_s(16)} if root_iri
    end
    @iri = path
  end
  prefix ? Resource._simplify_path(@iri) : @iri
end

#leaf?Boolean

オブジェクト包含階層の末端か?

Returns:

  • (Boolean)
    true - IRIが付与された他のオブジェクトを包含していない
    false - IRIが付与された他のオブジェクトを包含している


887
888
889
# File 'lib/when_exe/parts/resource.rb', line 887

def leaf?
  !@child || (@child.length==0)
end

#m17n(source, namespace = nil, locale = nil, options = {}) ⇒ When::BasicTypes::M17n or Array<them>

When::BasicTypes::M17n の生成/参照

Parameters:

  • source (When::BasicTypes::M17n)

    処理を行わず、そのままsourceを返す

  • source (String)

    locale と 文字列の対応

  • source (Array)

    要素を個別に解釈して生成したオブジェクトのArrayを返す

  • namespace (Hash) (defaults to: nil)

    prefix の指定

  • locale (Array) (defaults to: nil)

    locale の定義順序の指定

  • options (Hash) (defaults to: {})

Returns:



918
919
920
921
922
923
924
925
926
927
# File 'lib/when_exe/parts/resource.rb', line 918

def m17n(source, namespace=nil, locale=nil, options={})
  case source
  when Array                  ; When::BasicTypes::M17n.new(source, namespace, locale, options)
  when When::BasicTypes::M17n ; source
  when String
    return self[$1] if source =~ /\A\s*\[((\.{1,2}|::)+[^\]]+)\]/
    When::BasicTypes::M17n.new(source, namespace, locale, options)
  else ; raise TypeError, "Invalid Type: #{source.class}"
  end
end

#map(&block) ⇒ Array Also known as: collect

map, collect の再定義

has-a 関係の子 Resource に対して map/collect を行う

Parameters:

  • block (Block)

    実行するブロック

Returns:



967
968
969
# File 'lib/when_exe/parts/resource.rb', line 967

def map(&block)
  @child.map(&block)
end

#parentWhen::Parts::Resource

self を直接に包含するオブジェクト



836
837
838
# File 'lib/when_exe/parts/resource.rb', line 836

def parent
  @_pool['..'].kind_of?(Resource) ? @_pool['..'] : nil
end

#registered?Boolean

IRIが付与されているか?

Returns:

  • (Boolean)
    true - IRIが付与されている
    false - IRIが付与されていない


897
898
899
900
901
902
903
904
905
# File 'lib/when_exe/parts/resource.rb', line 897

def registered?
  leaf = self
  while leaf._pool && leaf._pool['..'].respond_to?(:_pool)
    root = leaf._pool['..']
    return false unless leaf.equal?(root._pool[leaf.label])
    leaf = root
  end
  Resource._pool.values.map {|resource| resource.object_id}.include?(leaf.object_id)
end