/[cvs]/nfo/perl/libs/Data/Transfer/Sync/API.pm
ViewVC logotype

Diff of /nfo/perl/libs/Data/Transfer/Sync/API.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.2 by joko, Mon Jan 20 16:59:48 2003 UTC revision 1.3 by joko, Sun Feb 9 04:59:27 2003 UTC
# Line 6  Line 6 
6  ##  ##
7  ##    ----------------------------------------------------------------------------------------  ##    ----------------------------------------------------------------------------------------
8  ##    $Log$  ##    $Log$
9    ##    Revision 1.3  2003/02/09 04:59:27  joko
10    ##    + api versioning mechanism
11    ##    + major structure changes
12    ##    - refactored code to sister modules
13    ##
14  ##    Revision 1.2  2003/01/20 16:59:48  joko  ##    Revision 1.2  2003/01/20 16:59:48  joko
15  ##    + cosmetics and debugging  ##    + cosmetics and debugging
16  ##  ##
# Line 20  package Data::Transfer::Sync::API; Line 25  package Data::Transfer::Sync::API;
25  use strict;  use strict;
26  use warnings;  use warnings;
27    
28    use base qw( DesignPattern::Bridge );
29    
30  use mixin::with qw( Data::Transfer::Sync );  use mixin::with qw( Data::Transfer::Sync );
31    
32    
33  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -   main  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -   main
34    
35  use Data::Dumper;  use Data::Dumper;
36    use Hash::Merge qw( merge );
37    
38  use Data::Compare::Struct qw( getDifference isEmpty );  use Data::Compare::Struct qw( isEmpty );
 use Data::Transform::Deep qw( merge );  
39    
40  # get logger instance  # get logger instance
41  my $logger = Log::Dispatch::Config->instance;  my $logger = Log::Dispatch::Config->instance;
42    
43  sub _init {  
44    sub api_constructor {
45    my $self = shift;    my $self = shift;
46      $logger->debug( __PACKAGE__ . "->api_constructor: Loading API");
47      $self->_loadVersionExtensions();
48  }  }
49    
 sub checkOptions {  
   my $self = shift;  
   my $opts = shift;  
     
   my $result = 1;  
     
   # check - do we have a target node?  
   if (!$opts->{target_node}) {  
     $logger->warning( __PACKAGE__ . "->checkOptions: Error while resolving resource metadata - no 'target node' could be determined.");  
     $result = 0;  
   }  
50    
51    # check - do we have a mapping?  sub _loadVersionExtensions {
52    if (!$opts->{mapping} && !$opts->{mapping_module}) {    my $self = shift;
53      $logger->warning( __PACKAGE__ . "->checkOptions: Error while resolving resource metadata - no 'mapping' could be determined.");    my $syncVersion = $self->{sync_version};
54      $result = 0;    $syncVersion ||= '';
55    }    $logger->debug( __PACKAGE__ . "->loadVersionExtensions( version='$syncVersion' )");
56        #print Dumper($self);
57    return $result;    #exit;
58        my $module = "Version::$syncVersion";
59      $self->load($module);
60  }  }
61    
62  sub checkOptionsV2 {  
63    sub configure {
64    my $self = shift;    my $self = shift;
65    
66  #print Dumper($self->{options});  #print "YAI\n";
67    #print Dumper(@_);
68    #exit;
69    
70    my $result = 1;    $logger->debug( __PACKAGE__ . "->configure");
71    
72    # check - do we have a target node?    my @args = @_;
73    if (!$self->{options}->{target}->{nodeName}) {  
74      $logger->warning( __PACKAGE__ . "->checkOptionsV2: No target given - please check metadata declaration.");  #print Dumper(@args);
75      $result = 0;  
76    }    if (!isEmpty(\@args)) {
77          my %properties = @_;
78    # check - do we have a mapping?      # merge args to properties
79    if (!$self->{options}->{fieldmap}) {      #map { $self->{$_} = $properties{$_}; } keys %properties;
80      $logger->warning( __PACKAGE__ . "->checkOptionsV2: Error while resolving resource metadata - no 'fieldmap' could be determined.");  #print Dumper($self);
81      $result = 0;  #print Dumper(\%properties);
82        if ($self->{options}) {
83        my $options_new = merge($self->{options}, \%properties);
84    #print Dumper($options_new);
85        $self->{options} = $options_new;
86    #print Dumper($self->{options});
87        } else {
88          $self->{options} = \%properties;
89        }
90        $self->_init();
91        #$self->_initV1();
92      } else {
93        #print "no args!", "\n";
94    }    }
     
   # TODO: extend!  
95    
96    return $result;  #print Dumper($self);
97    #exit;
98    
99      $self->{state}->{configured} = 1;
100      return 1;
101  }  }
102    
103    
104  sub prepareOptions {  sub setArguments {
105      my $self = shift;
106      my $args_raw = shift;
107      $self->{args_raw} = $args_raw;
108    }
109    
110    sub readArguments {
111    my $self = shift;    my $self = shift;
   my $opts = shift;  
112    
113  #print Dumper($opts);      my %syncConfig;
114        tie %syncConfig, 'Tie::IxHash';
115        %syncConfig = (
116          map => {
117            moduleName => $self->{args_raw}->{'mapping-module'},
118          },
119          source => {
120            dbKey => $self->{args_raw}->{source},
121            nodeType => $self->{args_raw}->{'source-type'},
122            nodeName => $self->{args_raw}->{'source-node'},
123          },
124          target => {
125            dbKey => $self->{args_raw}->{target},
126            nodeName => $self->{args_raw}->{'target-node'},
127          },
128          process => {
129            mode => $self->{args_raw}->{mode},
130            erase => $self->{args_raw}->{erase},
131            import => $self->{args_raw}->{import},
132            prepare => $self->{args_raw}->{prepare},
133          },
134    #      metadata => {
135    #        config => $self->{config_metadata},
136    #      }
137        );
138    
139      $self->{args} = \%syncConfig;
140    
141    }
142    
143    
144    # TODO: some feature to show off the progress of synchronization (cur/max * 100)
145    sub syncNodes {
146    
147      my $self = shift;
148      my $args = shift;
149    
150      $logger->debug( __PACKAGE__ . "->syncNodes: starting" );
151    
152    #print Dumper($self);
153  #exit;  #exit;
154    
155    $opts->{mode} ||= '';  #print Dumper($self->{options});
156    $opts->{erase} ||= 0;    $self->_prepareOptions();
   $opts->{prepare} ||= 0;  
   #$opts->{import} ||= 0;  
     
   if (!$opts->{source_node}) {  
     $logger->error( __PACKAGE__ . "->prepareOptions failed: Please specify source-node!");  
     return;  
   }  
     
   $logger->notice( __PACKAGE__ . "->prepareOptions( source_node $opts->{source_node} mode $opts->{mode} erase $opts->{erase} prepare $opts->{prepare} )");  
157    
158    #if (!$opts->{mapping} || !$opts->{mapping_module}) {  #print Dumper($self->{options});
   if (!$opts->{mapping}) {  
     $logger->warning( __PACKAGE__ . "->prepareOptions: No mapping supplied - please check key 'mappings' in global configuration or specify additional argument '--mapping'.");  
     #return;  
   }  
159    
160    $opts->{mapping_module} ||= $opts->{mapping};    if (!$self->checkOptions()) {
161    my $evstring = "use $opts->{mapping_module};";      $logger->critical( __PACKAGE__ . "->syncNodes: 'Data::Transfer::Sync::checkOptions' failed.");
   eval($evstring);  
   if ($@) {  
     $logger->warning( __PACKAGE__ . "->prepareOptions: error while trying to access mapping - $@");  
162      return;      return;
163    }    }
164    
165    # resolve mapping metadata (returned from sub)    if (!$self->{state}->{configured}) {
166    my $mapObject = $opts->{mapping_module}->new();      $logger->critical( __PACKAGE__ . "->syncNodes: Synchronization object is not configured/initialized correctly." );
   #print Dumper($map);  
   my $source_node_name = $opts->{source_node};  
   # check if mapping for certain node is contained in mapping object  
   if (!$mapObject->can($source_node_name)) {  
     $logger->warning( __PACKAGE__ . "->prepareOptions: Can't access mapping for node \"$source_node_name\" - please check $opts->{mapping_module}.");  
167      return;      return;
168    }    }
   my $map = $mapObject->$source_node_name;  
169    
170  #print Dumper($map);    # remember arguments through the whole processing
171      $self->{args} = $args;
172    
173    # check here if "target" is actually a CODEref - in this case: resolve it - deprecated!!! ???    # hash to hold and/or fill in metadata required for the processing
174    if (ref $map->{target} eq 'CODE') {    $self->{meta} = {};
     $map->{target} = $map->{target}->($source_node_name);  
   }  
175        
176    # resolve expressions (on nodename-level) here    # hash to sum up results
177    if ($map->{target} =~ m/^(code|expr):(.+?)$/) {    # TODO: re-implement! (sync-statistics???)
     my $target_dynamic_type = $1;  
     my $target_dynamic_expression = $2;  
     if (lc $target_dynamic_type eq 'code') {  
 #      $map->{target} = $mapObject->$target_dynamic_expression($map);  
     }  
   }  
178    
179    # remove asymmetries from $map (patch keys)    # detect synchronization method to determine which optical symbol (directed arrow) to use
180    $map->{source_node} = $map->{source}; delete $map->{source};    my $mode = $self->{args}->{mode};   # V1
181    $map->{target_node} = $map->{target}; delete $map->{target};    $mode ||= $self->{options}->{process}->{mode};    # V2
182    $map->{mapping} = $map->{details}; delete $map->{details};    my $direction_arrow = $self->_getDirectedArrow($mode);
   $map->{direction} = $map->{mode}; delete $map->{mode};  
   
   # defaults (mostly for backward-compatibility)  
   $map->{source_node} ||= $source_node_name;  
   $map->{source_ident} ||= 'storage_method:id';  
   $map->{target_ident} ||= 'property:oid';  
   $map->{direction} ||= $opts->{mode};         # | PUSH | PULL | FULL  
   $map->{method} ||= 'checksum';                # | timestamp  
   $map->{source_exclude} ||= [qw( cs )];  
183    
184    # merge map to opts    # determine code versions
185    map { $opts->{$_} = $map->{$_}; } keys %$map;      my $code_metadata_version;
186            # first, try to use version supplied by mapping-metadata
187  #print Dumper($opts);      $code_metadata_version = $self->{options}->{metadata}->{version};
188        # if not set, inherit from global 'sync_version'
189        $code_metadata_version ||= $self->{sync_version};
190    
191      # load additional code from versioned namespace into current instance
192        my $dynModule = "Metadata::$code_metadata_version";
193        $self->load($dynModule);
194        
195      # build metadata using versioned code and stuff
196        $self->options2metadata();
197        $self->options2metadata_accessor();
198    
199      # tracing
200        #print Dumper($self);
201        #exit;
202    
203    # TODO: move this to checkOptions...    $logger->info( __PACKAGE__ . "->syncNodes: source=$self->{meta}->{source}->{dbKey}/$self->{meta}->{source}->{nodeName} [$self->{meta}->{source}->{nodeType}] $direction_arrow target=$self->{meta}->{target}->{dbKey}/$self->{meta}->{target}->{nodeName} [$self->{meta}->{target}->{nodeType}]" );
     
   # check - do we have a target?  
   if (!$opts->{target_node}) {  
     $logger->warning( __PACKAGE__ . "->prepareOptions: No target given - please check metadata declaration.");  
     return;  
   }  
204    
205      return if !$self->buildFieldmapping();
206      return if !$self->_touchNodeSet();
207      return if !$self->_prepare_sync();
208    
209    #return $opts;    # tracing
210    return 1;      #print Dumper($self);
211        #print Dumper($self->{args});
212        #print Dumper($self->{options});
213        #print Dumper($self->{meta});
214        #print Dumper($self->{metadata});
215        #exit;
216    
217      # finally, tell the core to start the synchronization process
218      $self->_run();
219      
220  }  }
221    
222  sub prepareOptionsV2 {  
223    sub _prepareOptions {
224    
225    my $self = shift;    my $self = shift;
226    my $opts = shift;    
227      my $opts = $self->{args};
228    
229    # patch options    # patch options
230        $opts->{source}->{nodeName} ||= '';
231        $opts->{target}->{nodeName} ||= '';
232      $opts->{process}->{mode} ||= '';      $opts->{process}->{mode} ||= '';
     $opts->{process}->{prepare} ||= 0;  
233      $opts->{process}->{erase} ||= 0;      $opts->{process}->{erase} ||= 0;
234        $opts->{process}->{prepare} ||= 0;
235    
236      # defaults (mostly for backward-compatibility to V1 -
237      # but code mungled here out of prepareOptions_V1 from Version::V1)
238        $opts->{metadata}->{syncMethod} ||= 'checksum';                # | timestamp
239        $opts->{source}->{ident} ||= 'storage_method:id';
240        $opts->{source}->{exclude} ||= [qw( cs )];
241        $opts->{target}->{ident} ||= 'property:oid';
242        #$map->{source_node} ||= $source_node_name;
243        #$map->{direction} ||= $opts->{mode};         # | PUSH | PULL | FULL
244    
245    # pre-check options    # pre-check options
246      if (!$self->_preCheckOptions($opts)) {      if (!$self->_preCheckOptions($opts)) {
247        $logger->error( __PACKAGE__ . "->prepareOptionsV2: _preCheckOptions failed.");        $logger->error( __PACKAGE__ . "->_prepareOptions: _preCheckOptions failed.");
248        return;        return;
249      }      }
250    
251    # inform user about option preparation    # inform user about option preparation
252    $logger->notice( __PACKAGE__ . "->prepareOptionsV2( source.node='$opts->{source}->{nodeName}', target.node='$opts->{target}->{nodeName}', mode='$opts->{process}->{mode}', e='$opts->{process}->{erase}', p='$opts->{process}->{prepare}' )");    $logger->debug( __PACKAGE__ . "->_prepareOptions( source.node='$opts->{source}->{nodeName}', target.node='$opts->{target}->{nodeName}', mode='$opts->{process}->{mode}', e='$opts->{process}->{erase}', p='$opts->{process}->{prepare}' )");
253    
254    # try to load mapping-metadata-container    # try to load mapping-metadata-container
255    #my $mapObject = getNewPerlObjectByPkgName($opts->{map}->{moduleName});      # How? Create a new instance of the given
256    my $mapObject = DesignPattern::Object->fromPackage($opts->{map}->{moduleName});      # perl module/package name in ->{...}->{moduleName}.
257        # This instance is used later in the innards of the sync,
258        # that's why the module (class) should have a certain layout
259        # enabling the core to use it for gathering metadata while processing.
260        my $mapObject = DesignPattern::Object->fromPackage($opts->{map}->{moduleName});
261    
262    # try to resolve map from metadata-container    # try to resolve map from metadata-container
263    
# Line 208  sub prepareOptionsV2 { Line 265  sub prepareOptionsV2 {
265      my $source_nodeType = $opts->{source}->{nodeType};      my $source_nodeType = $opts->{source}->{nodeType};
266            
267      # check if mapping for certain node is contained in mapping object      # check if mapping for certain node is contained in mapping object
268      if (!$mapObject->can($source_nodeType)) {      if (!$mapObject || !$mapObject->can($source_nodeType)) {
269        $logger->warning( __PACKAGE__ . "->prepareOptionsV2: Can't access mapping for source-type=\"$source_nodeType\" - please check \"$opts->{map}->{moduleName}\".");        $logger->warning( __PACKAGE__ . "->_prepareOptions: Can't access mapping for source-type=\"$source_nodeType\" - please check \"$opts->{map}->{moduleName}\".");
270        return;        return;
271      }      }
272    
   
273      # get map      # get map
274      my $map = $mapObject->$source_nodeType;      my $map = $mapObject->$source_nodeType;
275      #print Dumper($map);      #print Dumper($map);
276        
277  =pod        my $map_version = $map->{metadata}->{version};
278        # FIXME: backward compatibility
279        if (!$map_version) {
280          $self->options_to_V2($map);
281        }
282    
283        # trace
284          #print Dumper($map);
285          #exit;
286          #print "ref: ", ref $map->{target}, "\n";
287          #print "target: ", $map->{target}, "\n";
288        
289      # check here if "target" is actually a CODEref - in this case: resolve it - deprecated!!! ???      # check here if "target" is actually a CODEref - in this case: resolve it - deprecated!!! ???
290      if (ref $map->{target}->{address} eq 'CODE') {      if (ref $map->{target}->{address} eq 'CODE') {
291        $map->{target}->{address} = $map->{target}->{address}->($source_nodeType);        $map->{target}->{address} = $map->{target}->{address}->($source_nodeType);
292      }      }
293            
294      # resolve expressions (on nodename-level) here      # resolve expressions (on nodename-level) here
295      if ($map->{target}->{address} =~ m/^(code|expr):(.+?)$/) {      elsif ($map->{target}->{address} =~ m/^(code|expr):(.+?)$/) {
296        my $target_dynamic_type = $1;        my $target_dynamic_type = $1;
297        my $target_dynamic_expression = $2;        my $target_dynamic_expression = $2;
298        if (lc $target_dynamic_type eq 'code') {        if (lc $target_dynamic_type eq 'code') {
299          $map->{target} = $mapObject->$target_dynamic_expression($map);          $map->{target} = $mapObject->$target_dynamic_expression($map);
300        }        }
301      }      }
 =cut  
302    
303    #map { $opts->{$_} = $map->{$_}; } keys %$map;    # merging - V1
304    my $opts_merged = merge( $opts, $map );      #map { $opts->{$_} = $map->{$_}; } keys %$map;
305        # trace
306          #print Dumper($self->{options});
307      
308      # merging - V2
309    
310        # merge local map with local opts
311          # enable cloning
312          # FIXME: do we really need cloning here? trade safety/encapsulation for speed?
313          Hash::Merge::set_clone_behavior(1);
314          Hash::Merge::set_behavior( 'RIGHT_PRECEDENT' );
315          my $locals_merged = merge( $opts, $map );
316    
317        # trace
318          #print Dumper($opts);
319          #print Dumper($map);
320          #print Dumper($locals_merged);
321          #exit;
322    
323        # merge local-merged ones with instance-wide options
324          Hash::Merge::set_clone_behavior(0);
325          $self->{options} = merge( $self->{options}, $locals_merged );
326      
327        # trace
328          #print Dumper($self->{options});
329          #exit;
330      
331    
   $self->{options} = $opts_merged;  
332    $self->{state}->{options_ready} = 1;    $self->{state}->{options_ready} = 1;
333    
334    return 1;    return 1;
# Line 245  sub prepareOptionsV2 { Line 336  sub prepareOptionsV2 {
336  }  }
337    
338    
339  sub configure {  sub _preCheckOptions {
   my $self = shift;  
   my @args = @_;  
   if (!isEmpty(\@args)) {  
     my %properties = @_;  
     # merge args to properties  
     map { $self->{$_} = $properties{$_}; } keys %properties;  
     $self->_init();  
     $self->_initV1();  
   } else {  
     #print "no args!", "\n";  
   }  
   #print Dumper($self);  
   $self->{state}->{configured} = 1;  
   return 1;  
 }  
340    
 sub configureV2 {  
341    my $self = shift;    my $self = shift;
342    my @args = @_;    my $opts = shift;
   if (!isEmpty(\@args)) {  
     my %properties = @_;  
     # merge args to properties  
     #map { $self->{$_} = $properties{$_}; } keys %properties;  
     $self->{options} = merge($self->{options}, \%properties);  
     $self->_init();  
     #$self->_initV1();  
   } else {  
     #print "no args!", "\n";  
   }  
   
 #print Dumper($self);  
   
   $self->{state}->{configured} = 1;  
   return 1;  
 }  
343    
344  sub _getDirectedArrow {    # trace
345    my $self = shift;      #print Dumper($opts);
346    my $mode = shift;      #exit;
347    $mode ||= '';      
348        if (!$opts->{process}->{mode}) {
349    if (lc $mode eq 'push') {      $logger->error( __PACKAGE__ . "->_preCheckOptions failed: Please specify \"--action=(load|save)\".");
350      return '->';      return;
   } elsif (lc $mode eq 'pull') {  
     return '<-';  
   } elsif (lc $mode eq 'full') {  
     return '<->';  
   } else {  
     return '';  
351    }    }
 }  
   
 # TODO: some feature to show off the progress of synchronization (cur/max * 100)  
 sub syncNodes {  
   
   my $self = shift;  
   my $args = shift;  
352    
353    if (!$self->{state}->{configured}) {    # the type of the to-be-synced item
354      $logger->critical( __PACKAGE__ . "->syncNodes: Synchronization object is not configured/initialized correctly." );    if (!$opts->{source}->{nodeType}) {
355        $logger->error( __PACKAGE__ . "->_preCheckOptions failed: Please specify \"source-type\".");
356      return;      return;
357    }    }
358      # the name of the (container-) node the items are listed in
359    # remember arguments through the whole processing    if (!$opts->{source}->{nodeName}) {
360    $self->{args} = $args;      $logger->error( __PACKAGE__ . "->_preCheckOptions failed: Please specify \"source-node\".");
361        return;
   $logger->debug( __PACKAGE__ . "->syncNodes: starting" );  
   
   # hash to hold and/or fill in metadata required for the processing  
   $self->{meta} = {};  
     
   # hash to sum up results  
   # TODO: re-implement! (sync-statistics???)  
   
   # detect synchronization method to determine which optical symbol (directed arrow) to use  
   my $mode = $self->{args}->{mode};   # V1  
   $mode ||= $self->{options}->{process}->{mode};    # V2  
   my $direction_arrow = $self->_getDirectedArrow($mode);  
   
   if (!$self->{options}->{metadata}->{version} || $self->{options}->{metadata}->{version} < 0.2) {  
     $self->_buildMetadataV1();  
   } else {  
     $self->_buildMetadataV2();  
362    }    }
363    
364    $logger->info( __PACKAGE__ . "->syncNodes: source=$self->{meta}->{source}->{dbKey}/$self->{meta}->{source}->{nodeName} [$self->{meta}->{source}->{nodeType}] $direction_arrow target=$self->{meta}->{target}->{dbKey}/$self->{meta}->{target}->{nodeName} [$self->{meta}->{target}->{nodeType}]" );    # a "map"-declaration which module to use for mapping- and/or lookup-purposes
365      if (!$opts->{map}) {
366    return if !$self->_buildFieldmappingV1();      $logger->warning( __PACKAGE__ . "->_preCheckOptions: No mapping supplied - please check key 'map|mappings' in global configuration or specify additional argument '--mapping-module'.");
367    return if !$self->_handleNodeContainers();      return;
368    return if !$self->_prepareSync();    }
369      if (!$opts->{map}->{moduleName}) {
370        $logger->warning( __PACKAGE__ . "->_preCheckOptions: Currently only perl-modules can provide mappings: Please specify one with '--mapping-module=My::Mapping::Module'.");
371        return;
372      }
373    
374  #print Dumper($self);    return 1;
 #print Dumper($self->{args});  
 #print Dumper($self->{options});  
 #print Dumper($self->{meta});  
 #print Dumper($self->{metadata});  
375    
   $self->_syncNodes();  
     
376  }  }
377    
378    
 sub _handleNodeContainers {  
   my $self = shift;  
   
   # check partners/nodes: does partner exist / is node available?  
   foreach my $partner (keys %{$self->{meta}}) {  
       
     # 1. check partners & storages  
     if (!$self->{meta}->{$partner}) {  
       $logger->critical( __PACKAGE__ . "->_handleNodeContainers: Could not find partner '$partner' in configuration metadata." );  
       next;  
     }  
   
     my $dbkey = $self->{meta}->{$partner}->{dbKey};  
   
 #print Dumper($self->{meta});  
   
     if (!$self->{meta}->{$partner}->{storage}) {  
       $logger->critical( __PACKAGE__ . "->_handleNodeContainers: Could not access storage ( partner='$partner', dbKey='$dbkey' ) - configuration-error?" );  
       next;  
     }  
       
     # TODO:  
     # 2. check if partners (and nodes?) are actually available....  
     # eventually pre-check mode of access-attempt (read/write) here to provide an "early-croak" if possible  
       
 #    print Dumper($self->{meta}->{$partner}->{storage}->{locator});  
     
     my $dbType = $self->{meta}->{$partner}->{storage}->{locator}->{type};  
 #print "dbType: $dbType", "\n";  
       
     # 3. check nodes  
     next if $dbType eq 'DBI';    # HACK for DBD::CSV - re-enable for others  
     # get node-name  
 #      print Dumper($self);  
     #print Dumper($self->{meta}->{$partner});  
     #print "öö", $self->{meta}->{$partner}->{node}, "\n";  
     my $nodename = $self->{meta}->{$partner}->{node};   # V1  
     $nodename ||= $self->{meta}->{$partner}->{nodeName};    # V2  
     # check if nodename is actually a CODEref, execute it to get a mapped/filtered target-nodename  
   
 #print "nodename: $nodename", "\n";  
   
     $logger->debug( __PACKAGE__ . "->_handleNodeContainers: Accessing dbType=\"$dbType\", nodename=\"$nodename\"." );  
       
 =pod  
     #print "----", ref $nodename, "\n";  
     if ($nodename =~ m/CODE/) {  
       print Dumper($self);  
       #exit;  
       $nodename = $nodename->($nodename);  
     }  
 =cut      
379    
380  #print Dumper($self);  sub _prepare_sync {
       
     #print "partner: $partner - nodename: $nodename", "\n";  
       
     if (!$self->{meta}->{$partner}->{storage}->existsChildNode($nodename)) {  
 #print "ex", "\n";  
 #exit;  
381    
       if ($partner eq 'target' && $self->{options}->{target}->{autocreateFolders}) {  
         if (!$self->{meta}->{$partner}->{storage}->createChildNode($nodename)) {  
           $logger->critical( __PACKAGE__ . "->_handleNodeContainers: Could not create node '$self->{meta}->{$partner}->{nodeName}\@$self->{meta}->{$partner}->{dbKey}' [$self->{meta}->{$partner}->{nodeType}]." );  
           next;  
         }  
       } else {  
         $logger->critical( __PACKAGE__ . "->_handleNodeContainers: Could not reach node \"$nodename\" at partner \"$partner\"." );  
         next;  
       }  
     }  
       
   }  
     
   return 1;  
   
 }  
   
   
 sub _prepareSync {  
382    my $self = shift;    my $self = shift;
383    
384    # TODO:    # TODO:
# Line 435  sub _prepareSync { Line 386  sub _prepareSync {
386    #  -+  if action == PULL: swap metadata and start processing    #  -+  if action == PULL: swap metadata and start processing
387    #   -  if action == FULL: start processing, then swap metadata and (re-)start processing    #   -  if action == FULL: start processing, then swap metadata and (re-)start processing
388    
389      #print "dir: ", $self->{args}->{direction}, "\n";
390    
391    # manipulate metainfo according to direction of synchronization    # manipulate metainfo according to direction of synchronization
392    if (lc $self->{args}->{direction} eq 'push') {    if (lc $self->{options}->{process}->{mode} eq 'push') {
393      # just do it ...      # just do it ...    (don't modify any metadata)
394    } elsif (lc $self->{args}->{direction} eq 'pull') {    
395      #print "=======SWAP", "\n";    } elsif (lc $self->{options}->{process}->{mode} eq 'pull') {
396      # swap      # swap source and target metadata
397        # TODO: introduce different mechanism to make more then two partners (descents) possible
398      ($self->{meta}->{source}, $self->{meta}->{target}) =      ($self->{meta}->{source}, $self->{meta}->{target}) =
399          ($self->{meta}->{target}, $self->{meta}->{source});          ($self->{meta}->{target}, $self->{meta}->{source});
400    } elsif (lc $self->{args}->{direction} eq 'full') {    
401      } elsif (lc $self->{options}->{process}->{mode} eq 'full') {
402        # TODO:
403        # do a pull first and a push afterwards
404        # this requires us to be called somehow recursively - just one recursion level  ;-)
405      
406    } else {    } else {
407        # TODO: are there any other synchronization modes besides PULL, PUSH, FULL?
408      
409    }    }
410    
411    # import flag means: prepare the source node to be syncable    # import flag means: prepare the source node to be syncable
# Line 468  sub _prepareSync { Line 429  sub _prepareSync {
429    
430  }  }
431    
432    sub _getDirectedArrow {
433      my $self = shift;
434      my $mode = shift;
435      $mode ||= '';
436      
437      if (lc $mode eq 'push') {
438        return '->';
439      } elsif (lc $mode eq 'pull') {
440        return '<-';
441      } elsif (lc $mode eq 'full') {
442        return '<->';
443      } else {
444        return '';
445      }
446    }
447    
448  1;  1;

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed