|  | 1 | # redMine - project management software | 
  |  | 2 | # Copyright (C) 2006-2010  Jean-Philippe Lang | 
  |  | 3 | # Copyright (C) 2010 Yuya Nishihara <yuya@tcha.org> | 
  |  | 4 | # | 
  |  | 5 | # This program is free software; you can redistribute it and/or | 
  |  | 6 | # modify it under the terms of the GNU General Public License | 
  |  | 7 | # as published by the Free Software Foundation; either version 2 | 
  |  | 8 | # of the License, or (at your option) any later version. | 
  |  | 9 | # | 
  |  | 10 | # This program is distributed in the hope that it will be useful, | 
  |  | 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | 
  |  | 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
  |  | 13 | # GNU General Public License for more details. | 
  |  | 14 | # | 
  |  | 15 | # You should have received a copy of the GNU General Public License | 
  |  | 16 | # along with this program; if not, write to the Free Software | 
  |  | 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. | 
  |  | 18 |  | 
  |  | 19 | require 'delegate' | 
  |  | 20 | require 'iconv' | 
  |  | 21 |  | 
  |  | 22 | module Redmine | 
  |  | 23 |   module Scm | 
  |  | 24 |     module Adapters | 
  |  | 25 |       # wraps scm adapter to convert path encodings | 
  |  | 26 |       class PathEncodableWrapper < SimpleDelegator  # :nodoc: | 
  |  | 27 |         def initialize(scm, path_encoding) | 
  |  | 28 |           super(scm) | 
  |  | 29 |           @path_encoding = path_encoding | 
  |  | 30 |         end | 
  |  | 31 |  | 
  |  | 32 |         def entry(path=nil, identifier=nil) | 
  |  | 33 |           convert_entry!(super(to_scm_path(path), identifier)) | 
  |  | 34 |         end | 
  |  | 35 |  | 
  |  | 36 |         def entries(path=nil, identifier=nil) | 
  |  | 37 |           convert_entries!(super(to_scm_path(path), identifier)) | 
  |  | 38 |         end | 
  |  | 39 |  | 
  |  | 40 |         def properties(path, identifier=nil) | 
  |  | 41 |           super(to_scm_path(path), identifier) | 
  |  | 42 |         end | 
  |  | 43 |  | 
  |  | 44 |         def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={}) | 
  |  | 45 |           convert_revisions!(super(to_scm_path(path), identifier_from, identifier_to, options)) | 
  |  | 46 |         end | 
  |  | 47 |  | 
  |  | 48 |         def diff(path, identifier_from, identifier_to=nil) | 
  |  | 49 |           super(to_scm_path(path), identifier_from, identifier_to) | 
  |  | 50 |         end | 
  |  | 51 |  | 
  |  | 52 |         def cat(path, identifier=nil) | 
  |  | 53 |           super(to_scm_path(path), identifier) | 
  |  | 54 |         end | 
  |  | 55 |  | 
  |  | 56 |         def annotate(path, identifier=nil) | 
  |  | 57 |           super(to_scm_path(path), identifier) | 
  |  | 58 |         end | 
  |  | 59 |  | 
  |  | 60 |         private | 
  |  | 61 |  | 
  |  | 62 |         def convert_entry!(entry) | 
  |  | 63 |           return unless entry | 
  |  | 64 |           entry.name = from_scm_path(entry.name) | 
  |  | 65 |           entry.path = from_scm_path(entry.path) | 
  |  | 66 |           entry | 
  |  | 67 |         end | 
  |  | 68 |  | 
  |  | 69 |         def convert_entries!(entries) | 
  |  | 70 |           return unless entries | 
  |  | 71 |           entries.each { |e| convert_entry!(e) } | 
  |  | 72 |           entries | 
  |  | 73 |         end | 
  |  | 74 |  | 
  |  | 75 |         def convert_revisions!(revisions) | 
  |  | 76 |           return unless revisions | 
  |  | 77 |           revisions.each do |rev| | 
  |  | 78 |             next unless rev.paths | 
  |  | 79 |             rev.paths.each do |e| | 
  |  | 80 |               e[:path] = from_scm_path(e[:path]) | 
  |  | 81 |               e[:from_path] = from_scm_path(e[:from_path]) | 
  |  | 82 |             end | 
  |  | 83 |           end | 
  |  | 84 |           revisions | 
  |  | 85 |         end | 
  |  | 86 |  | 
  |  | 87 |         # convert repository path string to utf-8 | 
  |  | 88 |         def from_scm_path(s) | 
  |  | 89 |           return unless s | 
  |  | 90 |           begin | 
  |  | 91 |             Iconv.conv('UTF-8', @path_encoding, s) | 
  |  | 92 |           rescue Iconv::Failure => err | 
  |  | 93 |             raise CommandFailed, "failed to convert path from #{@path_encoding} to UTF-8. #{err}" | 
  |  | 94 |           end | 
  |  | 95 |         end | 
  |  | 96 |  | 
  |  | 97 |         # convert utf-8 path string to repository encoding | 
  |  | 98 |         def to_scm_path(s) | 
  |  | 99 |           return unless s | 
  |  | 100 |           begin | 
  |  | 101 |             Iconv.conv(@path_encoding, 'UTF-8', s) | 
  |  | 102 |           rescue Iconv::Failure => err | 
  |  | 103 |             raise CommandFailed, "failed to convert path from UTF-8 to #{@path_encoding}. #{err}" | 
  |  | 104 |           end | 
  |  | 105 |         end | 
  |  | 106 |       end | 
  |  | 107 |     end | 
  |  | 108 |   end | 
  |  | 109 | end |