]> source.dussan.org Git - archiva.git/blob
cfaad6ec25ee300728a0236f6c33a3260567f69c
[archiva.git] /
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  *   http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied.  See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 define("archiva/admin/repository/10maven2/repositories",["jquery","i18n","jquery.tmpl","bootstrap","jquery.validate","knockout","knockout.simpleGrid"],
20 function(jquery,i18n,jqueryTmpl,bootstrap,jqueryValidate,ko) {
21
22   // FIXME this must be dynamic if we do a plugin mechanism with dynamic repositories types
23   // FIXME i18n
24
25   ManagedRepositoryType=function(type,label){
26     this.type=type;
27     this.label=label;
28   }
29
30   window.managedRepositoryTypes = [
31             new ManagedRepositoryType("default","Maven 2.x Repository"),
32             new ManagedRepositoryType("legacy", "Maven 1.x Repository")
33             ];
34
35   ManagedRepository=function(id,name,layout,indexDirectory,location,snapshots,releases,blockRedeployments,cronExpression,
36                              scanned,daysOlder,retentionCount,deleteReleasedSnapshots,stageRepoNeeded,description,
37                              skipPackedIndexCreation,feedsUrl,url){
38
39     var self=this;
40
41     //private String id;
42     this.id=ko.observable(id);
43     this.id.subscribe(function(newValue){self.modified(true)});
44
45     //private String name;
46     this.name=ko.observable(name);
47     this.name.subscribe(function(newValue){self.modified(true)});
48
49     //private String layout = "default";
50     this.layout=ko.observable(layout);
51     this.layout.subscribe(function(newValue){self.modified(true)});
52
53     //private String indexDirectory;
54     this.indexDirectory=ko.observable(indexDirectory);
55     this.indexDirectory.subscribe(function(newValue){self.modified(true)});
56
57     //private String location;
58     this.location=ko.observable(location);
59     this.location.subscribe(function(newValue){self.modified(true)});
60
61     //private String cronExpression = "0 0 * * * ?";
62     this.cronExpression=ko.observable(cronExpression);
63     this.cronExpression.subscribe(function(newValue){self.modified(true)});
64
65     //private ManagedRepository stagingRepository;
66
67     //private int daysOlder = 100;
68     this.daysOlder=ko.observable(daysOlder);
69     this.daysOlder.subscribe(function(newValue){self.modified(true)});
70
71     //private int retentionCount = 2;
72     this.retentionCount=ko.observable(retentionCount);
73     this.retentionCount.subscribe(function(newValue){self.modified(true)});
74
75     //private boolean scanned = true;
76     this.scanned=ko.observable(scanned?scanned:true);
77     this.scanned.subscribe(function(newValue){self.modified(true)});
78
79     //private boolean deleteReleasedSnapshots;
80     this.deleteReleasedSnapshots=ko.observable(deleteReleasedSnapshots);
81     this.deleteReleasedSnapshots.subscribe(function(newValue){self.modified(true)});
82
83     //private boolean stageRepoNeeded;
84     this.stageRepoNeeded=ko.observable(stageRepoNeeded);
85     this.stageRepoNeeded.subscribe(function(newValue){self.modified(true)});
86
87     //private boolean snapshots = false;
88     this.snapshots=ko.observable(snapshots?snapshots:false);
89     this.snapshots.subscribe(function(newValue){self.modified(true)});
90
91     //private boolean releases = true;
92     this.releases=ko.observable(releases?releases:false);
93     this.releases.subscribe(function(newValue){self.modified(true)});
94
95     //private boolean blockRedeployments = false;
96     this.blockRedeployments=ko.observable(blockRedeployments?blockRedeployments:false);
97     this.blockRedeployments.subscribe(function(newValue){self.modified(true)});
98
99     //private String name;
100     this.description=ko.observable(description);
101     this.description.subscribe(function(newValue){self.modified(true)});
102
103     this.skipPackedIndexCreation=ko.observable(skipPackedIndexCreation?skipPackedIndexCreation:false);
104     this.skipPackedIndexCreation.subscribe(function(newValue){self.modified(true)});
105
106     this.feedsUrl=feedsUrl;
107
108     this.url=url;
109
110     this.getTypeLabel=function(){
111       for(var i=0;i<window.managedRepositoryTypes.length;i++){
112         if (window.managedRepositoryTypes[i].type==self.layout()){
113           return window.managedRepositoryTypes[i].label;
114         }
115       }
116       return "no label";
117     }
118
119     this.modified=ko.observable(false);
120   }
121
122   ArchivaRepositoryStatistics=function(scanEndTime,scanStartTime,totalArtifactCount,totalArtifactFileSize,totalFileCount,
123                                        totalGroupCount,totalProjectCount,newFileCount,duration,managedRepository,lastScanDate){
124     //private Date scanEndTime;
125     this.scanEndTime = ko.observable(scanEndTime);
126
127     //private Date scanStartTime;
128     this.scanStartTime = ko.observable(scanStartTime);
129
130     //private long totalArtifactCount;
131     this.totalArtifactCount = ko.observable(totalArtifactCount);
132
133     //private long totalArtifactFileSize;
134     this.totalArtifactFileSize = ko.observable(totalArtifactFileSize);
135
136     //private long totalFileCount;
137     this.totalFileCount = ko.observable(totalFileCount);
138
139     //private long totalGroupCount;
140     this.totalGroupCount = ko.observable(totalGroupCount);
141
142     //private long totalProjectCount;
143     this.totalProjectCount = ko.observable(totalProjectCount);
144
145     //private long newFileCount;
146     this.newFileCount = ko.observable(newFileCount);
147
148     this.duration = ko.observable(duration);
149
150     this.managedRepository = managedRepository;
151
152     this.lastScanDate=ko.observable(lastScanDate);
153   }
154
155   mapManagedRepositories=function(data,applicationUrl){
156     var mappedManagedRepositories = $.map(data, function(item) {
157       var managedRepository = mapManagedRepository(item);
158       managedRepository.feedsUrl=applicationUrl+"/feeds/"+managedRepository.id();
159       managedRepository.url=applicationUrl+"/repository/"+managedRepository.id()
160       return managedRepository;
161     });
162     return mappedManagedRepositories;
163   }
164   mapManagedRepository=function(data){
165     if (data==null){
166       return null;
167     }
168     return new ManagedRepository(data.id,data.name,data.layout,data.indexDirectory,data.location,data.snapshots
169                                  ,data.releases,
170                                  data.blockRedeployments,data.cronExpression,
171                                  data.scanned,data.daysOlder,data.retentionCount,data.deleteReleasedSnapshots,
172                                  data.stageRepoNeeded,data.description,data.skipPackedIndexCreation);
173   }
174
175   mapArchivaRepositoryStatistics=function(data){
176     if (data==null){
177       return null;
178     }
179     return new ArchivaRepositoryStatistics(data.scanEndTime,data.scanStartTime,data.totalArtifactCount,data.totalArtifactFileSize,
180                                            data.totalFileCount,data.totalGroupCount,data.totalProjectCount,data.newFileCount,
181                                            data.duration,data.managedRepository,data.lastScanDate)
182   }
183
184   ManagedRepositoryViewModel=function(managedRepository, update, managedRepositoriesViewModel){
185     this.managedRepository=managedRepository;
186     this.managedRepositoriesViewModel = managedRepositoriesViewModel;
187     this.update = update;
188
189     var self = this;
190
191     this.availableLayouts = window.managedRepositoryTypes;
192
193     showCronExpressionDoc=function(){
194       //$.log("showCronExpressionDoc") ;
195     }
196
197     this.save=function(){
198       $.log('managedrepo save');
199       var valid = $("#main-content").find("#managed-repository-edit-form").valid();
200       if (valid==false) {
201           return;
202       }
203       $.log("save:"+this.managedRepository.name());
204       clearUserMessages();
205       var userMessages=$("#user-messages");
206       userMessages.html(mediumSpinnerImg());
207       $("#managed-repository-save-button" ).button('loading');
208       if (this.update){
209         $.ajax("restServices/archivaServices/managedRepositoriesService/updateManagedRepository",
210           {
211             type: "POST",
212             data: ko.toJSON(this.managedRepository),
213             contentType: 'application/json',
214             dataType: 'json',
215             success: function(data) {
216               displaySuccessMessage($.i18n.prop('managedrepository.updated',self.managedRepository.id()));
217               activateManagedRepositoriesGridTab();
218               self.managedRepository.modified(false);
219             },
220             complete: function(){
221               $("#managed-repository-save-button" ).button('reset');
222               removeMediumSpinnerImg(userMessages);
223             }
224           }
225         );
226       } else {
227         var url="restServices/archivaServices/managedRepositoriesService/fileLocationExists";
228         url+="?fileLocation="+encodeURIComponent(self.managedRepository.location());
229         $.ajax(url,
230         {
231           type: "GET",
232           dataType: 'json',
233           success: function(data) {
234             if (data){
235               var completeCallbackFn = function(){window.modalConfirmDialog.modal('hide')};
236               openDialogConfirm(
237                   function(){addManagedRepository(self.managedRepository,completeCallbackFn)},
238                   $.i18n.prop('ok'), $.i18n.prop('cancel'),
239                   $.i18n.prop('managedrepository.add.title'),
240                   $("#managed-repository-location-warning-tmpl").tmpl(self.managedRepository));
241             }else{
242               addManagedRepository(self.managedRepository);
243             }
244           },
245           complete: function(){
246             $("#managed-repository-save-button" ).button('reset');
247             removeMediumSpinnerImg(userMessages);
248           }
249         });
250       }
251     }
252
253     addManagedRepository=function(managedRepository,completeCallbackFn){
254       var curManagedRepository=managedRepository;
255       var callbackFn = completeCallbackFn;
256       var dataJson=ko.toJSON(managedRepository);
257       $.log("managedRepository.release:"+managedRepository.releases()+",dataJson:"+dataJson);
258       $.ajax("restServices/archivaServices/managedRepositoriesService/addManagedRepository",
259         {
260           type: "POST",
261           contentType: 'application/json',
262           data: dataJson,
263           dataType: 'json',
264           success: function(data) {
265             if (managedRepository.stageRepoNeeded()){
266               $.log("stageRepoNeeded:"+managedRepository.stageRepoNeeded());
267               // reload all to see the new staged repo
268               loadManagedRepositories(function(data){
269                 self.managedRepositoriesViewModel.managedRepositories(mapManagedRepositories(data));
270               });
271             } else {
272               curManagedRepository.location(data.location);
273               self.managedRepositoriesViewModel.managedRepositories.push(curManagedRepository);
274             }
275
276             displaySuccessMessage($.i18n.prop('managedrepository.added',curManagedRepository.id()));
277             curManagedRepository.modified(false);
278             activateManagedRepositoriesGridTab();
279           },
280           error: function(data) {
281             var res = $.parseJSON(data.responseText);
282             displayRestError(res);
283           },
284           complete:function(data){
285             if(callbackFn){
286               callbackFn();
287             }
288           }
289         }
290       );
291     }
292
293     displayGrid=function(){
294       activateManagedRepositoriesGridTab();
295     }
296
297   }
298
299   activateManagedRepositoryFormValidation=function(){
300     var validator = $("#main-content" ).find("#managed-repository-edit-form").validate({
301       rules: {
302         daysOlder : {
303           digits: true,
304           min: 1
305         },
306         retentionCount : {
307           digits: true,
308           min: 1,
309           max: 100
310         },
311         cronExpression: {
312           required: true,
313           remote: {
314             url: "restServices/archivaServices/commonServices/validateCronExpression",
315             type: "get"
316           }
317         },
318         id: {
319           required: true,
320           remote: {
321             url: "restServices/archivaUiServices/dataValidatorService/managedRepositoryIdNotExists",
322             type: "get"
323           }
324         }
325       },
326       showErrors: function(validator, errorMap, errorList) {
327         customShowError("#main-content #managed-repository-edit-form",validator,errorMap,errorMap);
328       }
329     });
330     validator.settings.messages["cronExpression"]=$.i18n.prop("cronExpression.notvalid");
331     validator.settings.messages["id"]=$.i18n.prop("id.required.or.alreadyexists");
332   }
333
334   ManagedRepositoriesViewModel=function(){
335     this.managedRepositories=ko.observableArray([]);
336
337     this.gridViewModel = null;
338     var self = this;
339
340     editManagedRepository=function(managedRepository){
341       var mainContent = $("#main-content");
342       var viewModel = new ManagedRepositoryViewModel(managedRepository,true,self);
343       ko.applyBindings(viewModel,mainContent.find("#managed-repository-edit").get(0));
344       activateManagedRepositoryEditTab();
345       mainContent.find("#managed-repository-edit-li a").html($.i18n.prop('edit'));
346       activateManagedRepositoryFormValidation();
347       activatePopoverDoc();
348     }
349
350     this.editManagedRepositoryWithId=function(managedRepositoryId){
351       $.each(self.managedRepositories(), function(index, value) {
352         if(value.id()==managedRepositoryId){
353           editManagedRepository(value);
354         }
355       });
356     }
357
358     scanNow=function(managedRepository){
359       clearUserMessages();
360       openDialogConfirm(
361           function(){
362             $("#dialog-confirm-modal" ).find("#modal-login-footer").append(smallSpinnerImg());
363             var checked = $("#managed-repository-scan-now-all").get(0).checked;
364             var url = "restServices/archivaServices/repositoriesService/scanRepositoryNow?";
365             url += "repositoryId="+encodeURIComponent(managedRepository.id());
366             url += "&fullScan="+(checked==true?"true":"false");
367             $.ajax(url,
368               {
369                 type: "GET",
370                 beforeSend:function(){
371                   displayInfoMessage($.i18n.prop("managedrepository.scan.started",managedRepository.id()));
372                   closeDialogConfirm();
373                 },
374                 success: function(data) {
375                   displaySuccessMessage($.i18n.prop("managedrepository.scanned",managedRepository.name()));
376                 },
377                 error: function(data) {
378                   var res = $.parseJSON(data.responseText);
379                   displayRestError(res);
380                 },
381                 complete: function(){
382                   removeSmallSpinnerImg();
383                   closeDialogConfirm();
384                 }
385               }
386             );
387           },
388           $.i18n.prop("ok"),
389           $.i18n.prop("cancel"),
390           $.i18n.prop("managedrepository.scan.now"),
391           $("#managed-repository-scan-now-modal-tmpl").tmpl(managedRepository));
392
393     }
394
395     removeManagedRepository=function(managedRepository){
396       clearUserMessages();
397       openDialogConfirm(
398           function(){
399             var url = "restServices/archivaServices/managedRepositoriesService/deleteManagedRepository?";
400             url += "repositoryId="+encodeURIComponent(managedRepository.id());
401             var checked = $("#managedrepository-deletecontent").get(0).checked;
402             url += "&deleteContent="+(checked==true?"true":"false");
403             var dialogText=$("#dialog-confirm-modal-body-text" );
404             dialogText.html(mediumSpinnerImg());
405             $.ajax(url,
406               {
407                 type: "GET",
408                   success: function(data) {
409                     self.managedRepositories.remove(managedRepository);
410                     displaySuccessMessage($.i18n.prop("managedrepository.deleted",managedRepository.name()));
411
412                   },
413                   error: function(data) {
414                     var res = $.parseJSON(data.responseText);
415                     displayRestError(res);
416                   },
417                   complete: function(){
418                     removeMediumSpinnerImg(dialogText);
419                     closeDialogConfirm();
420                   }
421               }
422             );
423
424           },
425           $.i18n.prop("ok"),
426           $.i18n.prop("cancel"),
427           $.i18n.prop("managedrepository.delete.confirm",managedRepository.name()),
428           $("#managed-repository-delete-warning-tmpl").tmpl(managedRepository));
429     }
430
431     updateManagedRepository=function(managedRepository){
432       var managedRepositoryViewModel = new ManagedRepositoryViewModel(managedRepository,true,this);
433       managedRepositoryViewModel.save();
434     }
435
436     this.bulkSave=function(){
437       $.log("bulkSave");
438       return getModifiedManagedRepositories().length>0;
439     }
440
441     getModifiedManagedRepositories=function(){
442       var prx = $.grep(self.managedRepositories(),
443           function (managedRepository,i) {
444             return managedRepository.modified();
445           });
446       return prx;
447     }
448     updateModifiedManagedRepositories=function(){
449       var repos = getModifiedManagedRepositories();
450
451       openDialogConfirm(function(){
452                           for (i=0;i<repos.length;i++){
453                             updateManagedRepository(repos[i]);
454                           }
455                           closeDialogConfirm();
456                         },
457                         $.i18n.prop('ok'),
458                         $.i18n.prop('cancel'),
459                         $.i18n.prop('managed.repository.bulk.save.confirm.title'),
460                         $.i18n.prop('managed.repository.bulk.save.confirm',repos.length));
461     }
462
463     directoriesScan=function(managedRepository){
464       $.log("directoriesScan:"+managedRepository.id());
465       clearUserMessages();
466       var url = "restServices/archivaServices/repositoriesService/scanRepositoryDirectoriesNow/"+managedRepository.id();
467       $.ajax(url,
468         {
469           type: "GET",
470           dataType: 'json',
471           beforeSend:function(){
472             displayInfoMessage($.i18n.prop("managedrepository.scan.directories.started", managedRepository.id()));
473           },
474           success: function(data) {
475             $.log(" scanRepositoryDirectoriesNow finished ");
476             displaySuccessMessage( $.i18n.prop("managedrepository.scan.directories.finished", managedRepository.id()));
477           },
478           error: function(data) {
479             var res = $.parseJSON(data.responseText);
480             displayRestError(res);
481           },
482           complete: function(){
483             removeSmallSpinnerImg();
484           }
485
486         }
487       );
488     }
489
490     showStats=function(managedRepository){
491       if ($(calculatePopoverId(managedRepository)).html()){
492         // we ask stats all the time ? if no uncomment return
493         //return;
494         $("#managedrepository-stats-"+escapeDot(managedRepository.id())).append(smallSpinnerImg());
495       }
496       var curRepo=managedRepository;
497       var url = "restServices/archivaServices/managedRepositoriesService/getManagedRepositoryStatistics/"+managedRepository.id();
498       url+="/"+encodeURIComponent(usedLang());
499       $.ajax(url,
500         {
501           type: "GET",
502           dataType: 'json',
503           success: function(data) {
504             if (data==null){
505               return;
506             }
507             var archivaRepositoryStatistics=mapArchivaRepositoryStatistics(data);
508             archivaRepositoryStatistics.managedRepository=curRepo;
509             var mainContent = $("#main-content");
510             mainContent.find("#managedrepository-stats-"+escapeDot(curRepo.id())).append($("#managed-repository-stats-tmpl").tmpl(archivaRepositoryStatistics));
511             mainContent.find("#managedrepository-stats-img-"+escapeDot(curRepo.id())).attr("data-content",$(calculatePopoverId(curRepo)).html());
512             mainContent.find("#managedrepository-stats-img-"+escapeDot(curRepo.id())).popover(
513                 {
514                   placement: "left",
515                   html: true,
516                   trigger:'manual'
517                 }
518             );
519
520             mainContent.find("#managedrepository-stats-img-"+escapeDot(curRepo.id())).popover('show');
521             removeSmallSpinnerImg();
522           },
523           error: function(data) {
524             var res = $.parseJSON(data.responseText);
525             displayRestError(res);
526           },
527           complete: function(){
528            }
529         }
530       );
531     }
532
533     calculatePopoverId=function(managedRepository){
534       return "#main-content #managedrepository-stats-"+escapeDot(managedRepository.id()) + " #managedrepository-stats-"+escapeDot(managedRepository.id())+"-popover";
535     }
536
537     hideStats=function(managedRepository){
538       $("#body_content" ).find(".popover" ).hide();
539     }
540
541     showPomSnippet=function(managedRepository){
542       var mainContent = $("#main-content");
543       mainContent.find("#managed-repositories-pom-snippet").html(mediumSpinnerImg());
544       mainContent.find('#managed-repositories-pom-snippet').show();
545       var url = "restServices/archivaServices/managedRepositoriesService/getPomSnippet/"+encodeURIComponent(managedRepository.id());
546       $.ajax(url,
547         {
548           type: "GET",
549           dataType: 'text',
550           success: function(data) {
551             $("#managed-repositories-pom-snippet").html($("#pom-snippet-tmpl").tmpl(data));
552           },
553           error: function(data) {
554             var res = $.parseJSON(data.responseText);
555             displayRestError(res);
556           },
557           complete: function(){
558           }
559         }
560       );
561
562     }
563
564     mergeRepo=function(managedRepository){
565       var userMessages=$("#user-messages");
566       userMessages.html(mediumSpinnerImg());
567       // is there any artifacts to merge ?
568       var artifactsNumberUrl = "restServices/archivaServices/browseService/artifacts/"+encodeURIComponent(managedRepository.id());
569       $.ajax(artifactsNumberUrl,{
570             type: "GET",
571             dataType: 'json',
572             success: function(data){
573               var artifacts=mapArtifacts(data);
574               $.log("artifactsNumber for '" + managedRepository.id() + "': " + artifacts.length);
575
576               if (artifacts<1){
577                 displayWarningMessage($.i18n.prop("managedrepository.merge.noartifacts", managedRepository.id()));
578                 return;
579               }
580
581               $.log("merge repo open dialog");
582               var dialogMergeRepo=$("#dialog-modal-merge-repo");
583               if (window.modalMergeRepoDialog==null) {
584                 window.modalMergeRepoDialog = dialogMergeRepo.modal();
585
586               }
587
588               loadManagedRepositories(function(data){
589
590                 var managedRepositories = $.map(mapManagedRepositories(data), function(item) {
591                     return item.id()==managedRepository.id()?null:item;
592                 });
593                 $("#dialog-modal-merge-repo-body-text").html($("#merge-repo-dialog-content" )
594                                                                   .tmpl({sourceRepoId:managedRepository.id(),repositories:managedRepositories}));
595                 window.modalMergeRepoDialog.modal('show');
596               });
597
598             },
599             complete: function(){
600               removeMediumSpinnerImg(userMessages);
601             }
602         }
603       );
604
605     }
606
607
608   }
609
610
611   mergeRepositories=function(sourceRepository,targetRepository){
612     $.log("mergeRepositories:"+sourceRepository+":"+targetRepository);
613
614     var mergeRepoDialogBodyId="dialog-modal-merge-repo-body-text";
615     var mergeRepoDialogBody=$("#"+mergeRepoDialogBodyId);
616     mergeRepoDialogBody.html(mediumSpinnerImg());
617
618     // check conflicts
619     var url = "restServices/archivaServices/mergeRepositoriesService/mergeConflictedArtifacts/"+encodeURIComponent(sourceRepository);
620     url+="/"+encodeURIComponent(targetRepository);
621     $.ajax(url, {
622         type: "GET",
623         dataType: 'json',
624         success: function(data){
625           var artifacts=mapArtifacts(data);
626           if (artifacts && artifacts.length){
627             // we have conflicts ask to skip or not
628             $.log("conflicts:"+artifacts.length);
629             displayWarningMessage($.i18n.prop("managedrepository.merge.conflicts", artifacts.length),"dialog-modal-merge-repo-body-text");
630             $.tmpl($("#merge-repo-skip-conflicts").html(),
631                 { artifacts:artifacts, sourceRepository: sourceRepository, targetRepository:targetRepository })
632                 .appendTo( "#dialog-modal-merge-repo-body-text" );
633             $("#dialog-modal-merge-repo-header-title" ).html($.i18n.prop("managedrepository.merge.conflicts.header",sourceRepository,targetRepository));
634           } else {
635             doMerge(sourceRepository,targetRepository,false);
636           }
637         },
638         complete: function(){
639           $.log("complete removeMediumSpinnerImg");
640           removeMediumSpinnerImg("#dialog-modal-merge-repo-body-text");
641         }
642     });
643
644
645
646   }
647
648   doMerge=function(sourceRepository,targetRepository,skipConflicts){
649     $.log("doMerge:"+sourceRepository+" to " + targetRepository + ", skipConflicts: " + skipConflicts);
650     window.modalMergeRepoDialog.modal('hide');
651     var userMessages=$("#user-messages");
652     userMessages.html(mediumSpinnerImg());
653     var url = "restServices/archivaServices/mergeRepositoriesService/mergeRepositories/"+encodeURIComponent(sourceRepository);
654     url+="/"+encodeURIComponent(targetRepository);
655     url+="/"+skipConflicts;
656     $.ajax(url, {
657         type: "GET",
658         dataType: 'json',
659         success: function(data){
660           displaySuccessMessage($.i18n.prop("managedrepository.merge.success", sourceRepository,targetRepository));
661         },
662         complete: function(){
663           removeMediumSpinnerImg(userMessages);
664         }
665     });
666   }
667
668   activateManagedRepositoriesGridTab=function(){
669     var mainContent = $("#main-content");
670     mainContent.find("#managed-repository-edit-li").removeClass("active");
671     mainContent.find("#managed-repository-edit").removeClass("active");
672
673     mainContent.find("#managed-repositories-view-li").addClass("active");
674     mainContent.find("#managed-repositories-view").addClass("active");
675     mainContent.find("#managed-repository-edit-li a").html($.i18n.prop("add"));
676   }
677
678   activateManagedRepositoryEditTab=function(){
679     var mainContent = $("#main-content");
680     mainContent.find("#managed-repositories-view-li").removeClass("active");
681     mainContent.find("#managed-repositories-view").removeClass("active");
682
683     mainContent.find("#managed-repository-edit-li").addClass("active");
684     mainContent.find("#managed-repository-edit").addClass("active");
685   }
686
687
688   //---------------------------
689   // Remote repositories part
690   //---------------------------
691
692
693
694   RemoteRepository=function(id,name,layout,indexDirectory,url,userName,password,timeout,downloadRemoteIndex,remoteIndexUrl,
695                             remoteDownloadNetworkProxyId,cronExpression,remoteDownloadTimeout,downloadRemoteIndexOnStartup,
696                             description,extraParametersEntries,extraHeadersEntries){
697
698     var self=this;
699
700     //private String id;
701     this.id=ko.observable(id);
702     this.id.subscribe(function(newValue){self.modified(true)});
703
704     //private String name;
705     this.name=ko.observable(name);
706     this.name.subscribe(function(newValue){self.modified(true)});
707
708     //private String layout = "default";
709     this.layout=ko.observable(layout);
710     this.layout.subscribe(function(newValue){self.modified(true)});
711
712     //private String indexDirectory;
713     this.indexDirectory=ko.observable(indexDirectory);
714     this.indexDirectory.subscribe(function(newValue){self.modified(true)});
715
716     //private String url;
717     this.url=ko.observable(url);
718     this.url.subscribe(function(newValue){self.modified(true)});
719
720     //private String userName;
721     this.userName=ko.observable(userName);
722     this.userName.subscribe(function(newValue){self.modified(true)});
723
724     //private String password;
725     this.password=ko.observable(password);
726     this.password.subscribe(function(newValue){self.modified(true)});
727
728     //private int timeout = 60;
729     this.timeout=ko.observable(timeout);
730     this.timeout.subscribe(function(newValue){self.modified(true)});
731
732     //private boolean downloadRemoteIndex = false;
733     this.downloadRemoteIndex=ko.observable(downloadRemoteIndex?false:downloadRemoteIndex);
734     this.downloadRemoteIndex.subscribe(function(newValue){self.modified(true)});
735
736     //private String remoteIndexUrl = ".index";
737     this.remoteIndexUrl=ko.observable(remoteIndexUrl);
738     this.remoteIndexUrl.subscribe(function(newValue){self.modified(true)});
739
740     //private String remoteDownloadNetworkProxyId;
741     this.remoteDownloadNetworkProxyId=ko.observable(remoteDownloadNetworkProxyId);
742     this.remoteDownloadNetworkProxyId.subscribe(function(newValue){self.modified(true)});
743
744     //private String cronExpression = "0 0 08 ? * SUN";
745     this.cronExpression=ko.observable(cronExpression);
746     this.cronExpression.subscribe(function(newValue){self.modified(true)});
747
748     //private int remoteDownloadTimeout = 300;
749     this.remoteDownloadTimeout=ko.observable(remoteDownloadTimeout);
750     this.remoteDownloadTimeout.subscribe(function(newValue){self.modified(true)});
751
752     //private boolean downloadRemoteIndexOnStartup = false;
753     this.downloadRemoteIndexOnStartup=ko.observable(downloadRemoteIndexOnStartup?false:downloadRemoteIndexOnStartup);
754     this.downloadRemoteIndexOnStartup.subscribe(function(newValue){self.modified(true)});
755
756     this.description=ko.observable(description);
757     this.description.subscribe(function(newValue){self.modified(true)});
758
759     this.getTypeLabel=function(){
760       for(var i=0;i<window.managedRepositoryTypes.length;i++){
761         if (window.managedRepositoryTypes[i].type==self.layout()){
762           return window.managedRepositoryTypes[i].label;
763         }
764       }
765       return "no label";
766     }
767
768     this.extraParametersEntries=ko.observableArray(extraParametersEntries==null?new Array():extraParametersEntries);
769     this.extraParametersEntries.subscribe(function(newValue){
770       self.modified(true);
771     });
772
773     this.extraHeadersEntries=ko.observableArray(extraHeadersEntries==null?new Array():extraHeadersEntries);
774     this.extraHeadersEntries.subscribe(function(newValue){
775       self.modified(true);
776     });
777
778     this.modified=ko.observable(false);
779   }
780
781   mapRemoteRepository=function(data){
782     if (data==null){
783       return null;
784     }
785
786     var extraParametersEntries = data.extraParametersEntries == null ? []: $.each(data.extraParametersEntries,function(item){
787       return new Entry(item.key, item.value);
788     });
789     if (!$.isArray(extraParametersEntries)){
790       extraParametersEntries=[];
791     }
792
793     var extraHeadersEntries = data.extraHeadersEntries == null ? []: $.each(data.extraHeadersEntries,function(item){
794       return new Entry(item.key, item.value);
795     });
796     if (!$.isArray(extraHeadersEntries)){
797       extraHeadersEntries=[];
798     }
799
800     return new RemoteRepository(data.id,data.name,data.layout,data.indexDirectory,data.url,data.userName,data.password,
801                                 data.timeout,data.downloadRemoteIndex,data.remoteIndexUrl,data.remoteDownloadNetworkProxyId,
802                                 data.cronExpression,data.remoteDownloadTimeout,data.downloadRemoteIndexOnStartup,data.description,
803                                 extraParametersEntries,extraHeadersEntries);
804   }
805
806   mapRemoteRepositories=function(data){
807     var mappedRemoteRepositories = $.map(data, function(item) {
808       return mapRemoteRepository(item);
809     });
810     return mappedRemoteRepositories;
811   }
812
813   RemoteRepositoryViewModel=function(remoteRepository, update, remoteRepositoriesViewModel){
814     this.remoteRepository=remoteRepository;
815     this.remoteRepositoriesViewModel = remoteRepositoriesViewModel;
816     this.networkProxies=ko.observableArray([]);
817     this.update = update;
818
819     var self = this;
820
821     this.availableLayouts = window.managedRepositoryTypes;
822
823     this.save=function(){
824       var valid = $("#main-content" ).find("#remote-repository-edit-form").valid();
825       if (valid==false) {
826         return;
827       }
828       clearUserMessages();
829       var userMessages=$("#user-messages");
830       userMessages.html(mediumSpinnerImg());
831       $("#remote-repository-save-button" ).button('loading');
832       if (update){
833         $.ajax("restServices/archivaServices/remoteRepositoriesService/updateRemoteRepository",
834           {
835             type: "POST",
836             data: ko.toJSON(this.remoteRepository),
837             contentType: 'application/json',
838             dataType: 'json',
839             success: function(data) {
840               displaySuccessMessage($.i18n.prop('remoterepository.updated',self.remoteRepository.id()));
841               activateRemoteRepositoriesGridTab();
842               self.remoteRepository.modified(false);
843             },
844             error: function(data) {
845               var res = $.parseJSON(data.responseText);
846               displayRestError(res);
847             },
848             complete: function(){
849               $("#remote-repository-save-button" ).button('reset');
850               removeMediumSpinnerImg(userMessages);
851             }
852           }
853         );
854       }else {
855         $.ajax("restServices/archivaServices/remoteRepositoriesService/addRemoteRepository",
856           {
857             type: "POST",
858             data: ko.toJSON(this.remoteRepository),
859             contentType: 'application/json',
860             dataType: 'json',
861             success: function(data) {
862               self.remoteRepository.modified(false);
863               self.remoteRepositoriesViewModel.remoteRepositories.push(self.remoteRepository);
864               displaySuccessMessage($.i18n.prop('remoterepository.added'));
865               activateRemoteRepositoriesGridTab();
866               removeMediumSpinnerImg(userMessages);
867             },
868             error: function(data) {
869               var res = $.parseJSON(data.responseText);
870               displayRestError(res);
871             }
872           }
873         );
874       }
875     }
876
877     displayGrid=function(){
878       activateRemoteRepositoriesGridTab();
879     }
880
881     addExtraParameter=function(){
882
883       var mainContent=$("#main-content");
884       mainContent.find("#extra-parameters-error" ).empty();
885       var key=mainContent.find("#extraParameter-key").val();
886       if($.trim(key).length<1){
887         displayErrorMessage( $.i18n.prop("key.empty.error.message"),"extra-parameters-error");
888         return;
889       }
890       var value=mainContent.find("#extraParameter-value").val();
891       $.log("addExtraParameter="+key+":"+value);
892       var oldTab = self.remoteRepository.extraParametersEntries();
893       oldTab.push(new Entry(key,value));
894       self.remoteRepository.extraParametersEntries(oldTab);
895       mainContent.find("#extraParameter-key").val("");
896       mainContent.find("#extraParameter-value").val("");
897       self.remoteRepository.modified(true);
898     }
899
900     deleteExtraParameter=function(key){
901       for(var i=0;i<self.remoteRepository.extraParametersEntries().length;i++){
902         var entry=self.remoteRepository.extraParametersEntries()[i];
903         if (entry.key==key){
904           self.remoteRepository.extraParametersEntries.remove(entry);
905           self.remoteRepository.modified(true);
906         }
907       }
908     }
909
910     addExtraHeader=function(){
911
912       var mainContent=$("#main-content");
913       mainContent.find("#extra-headers-error" ).empty();
914       var key=mainContent.find("#extraHeader-key").val();
915       if( $.trim(key).length<1){
916         if($.trim(key).length<1){
917           displayErrorMessage( $.i18n.prop("key.empty.error.message"),"extra-headers-error");
918           return;
919         }
920       }
921       var value=mainContent.find("#extraHeader-value").val();
922       $.log("addExtraParameter="+key+":"+value);
923       var oldTab = self.remoteRepository.extraHeadersEntries();
924       oldTab.push(new Entry(key,value));
925       self.remoteRepository.extraHeadersEntries(oldTab);
926       mainContent.find("#extraHeader-key").val("");
927       mainContent.find("#extraHeader-value").val("");
928       self.remoteRepository.modified(true);
929     }
930
931     deleteExtraHeader=function(key){
932       for(var i=0;i<self.remoteRepository.extraHeadersEntries().length;i++){
933         var entry=self.remoteRepository.extraHeadersEntries()[i];
934         if (entry.key==key){
935           self.remoteRepository.extraHeadersEntries.remove(entry);
936           self.remoteRepository.modified(true);
937         }
938       }
939     }
940
941   }
942
943   RemoteRepositoriesViewModel=function(){
944     this.remoteRepositories=ko.observableArray([]);
945     this.applicationUrl=null;
946     this.gridViewModel = null;
947     var self = this;
948
949     editRemoteRepository=function(remoteRepository){
950       $.log("editRemoteRepository");
951       $.ajax("restServices/archivaServices/networkProxyService/getNetworkProxies", {
952           type: "GET",
953           dataType: 'json',
954           success: function(data) {
955             var viewModel = new RemoteRepositoryViewModel(remoteRepository,true,self);
956             viewModel.networkProxies(mapNetworkProxies(data));
957             var mainContent = $("#main-content");
958
959             ko.applyBindings(viewModel,mainContent.find("#remote-repository-edit").get(0));
960             activateRemoteRepositoryEditTab();
961             mainContent.find("#remote-repository-edit-li a").html($.i18n.prop('edit'));
962             activateRemoteRepositoryFormValidation(false);
963             activatePopoverDoc();
964           }
965       })
966
967     }
968
969     removeRemoteRepository=function(remoteRepository){
970       clearUserMessages();
971       openDialogConfirm(
972           function(){
973             var dialogText=$("#dialog-confirm-modal-body-text" );
974             dialogText.html(mediumSpinnerImg());
975             $.ajax("restServices/archivaServices/remoteRepositoriesService/deleteRemoteRepository/"+encodeURIComponent(remoteRepository.id()),
976                   {
977                     type: "GET",
978                     success: function(data) {
979                       self.remoteRepositories.remove(remoteRepository);
980                       displaySuccessMessage($.i18n.prop('remoterepository.deleted',remoteRepository.id()));
981                     },
982                     error: function(data) {
983                       var res = $.parseJSON(data.responseText);
984                       displayRestError(res);
985                     },
986                     complete:function(){
987                       removeMediumSpinnerImg(dialogText);
988                       closeDialogConfirm();
989                     }
990                   }
991                 )}, $.i18n.prop('ok'),
992                 $.i18n.prop('cancel'),
993                 $.i18n.prop('remoterepository.delete.confirm',remoteRepository.id()),
994                 $("#remote-repository-delete-modal-tmpl").tmpl(remoteRepository));
995
996     }
997
998     this.bulkSave=function(){
999       return getModifiedRemoteRepositories().length>0;
1000     }
1001
1002     getModifiedRemoteRepositories=function(){
1003       var prx = $.grep(self.remoteRepositories(),
1004           function (remoteRepository,i) {
1005             return remoteRepository.modified();
1006           });
1007       return prx;
1008     }
1009
1010     updateModifiedRemoteRepositories=function(){
1011       var modifiedRemoteRepositories = getModifiedRemoteRepositories();
1012
1013       openDialogConfirm(function(){
1014                           for(var i=0;i<modifiedRemoteRepositories.length;i++){
1015                             updateRemoteRepository(modifiedRemoteRepositories[i]);
1016                           }
1017                           closeDialogConfirm();
1018                         },
1019                         $.i18n.prop('ok'),
1020                         $.i18n.prop('cancel'),
1021                         $.i18n.prop('remoterepositories.bulk.save.confirm.title'),
1022                         $.i18n.prop('remoterepositories.bulk.save.confirm',modifiedRemoteRepositories.length));
1023     }
1024
1025     updateRemoteRepository=function(remoteRepository){
1026       var viewModel = new RemoteRepositoryViewModel(remoteRepository,true,self);
1027       viewModel.save();
1028     }
1029
1030     scheduleDownloadRemoteIndex=function(remoteRepository){
1031       openDialogConfirm(
1032         function(){
1033
1034           var url = "restServices/archivaServices/repositoriesService/scheduleDownloadRemoteIndex?";
1035           url += "repositoryId="+encodeURIComponent(remoteRepository.id());
1036
1037           var now = $("#remoterepository-scan-now").get(0).checked;
1038
1039           var full = $("#remoterepository-scan-full").get(0).checked;
1040
1041           url += "&now="+(now==true?"true":"false");
1042           url += "&fullDownload="+(full==true?"true":"false");
1043           $.ajax(url,
1044             {
1045               type: "GET",
1046                 success: function(data) {
1047                   clearUserMessages();
1048                   displaySuccessMessage($.i18n.prop("remoterepository.download.remote.scheduled",remoteRepository.name()));
1049                 },
1050                 error: function(data) {
1051                   var res = $.parseJSON(data.responseText);
1052                   displayRestError(res);
1053                 },
1054                 complete: function(){
1055                   closeDialogConfirm();
1056                 }
1057             }
1058           );
1059
1060         },
1061         $.i18n.prop("ok"),
1062         $.i18n.prop("cancel"),
1063         $.i18n.prop("remoterepository.download.remote.confirm",remoteRepository.name()),
1064         $("#remote-repository-scan-modal-tmpl").tmpl(remoteRepository));
1065     }
1066   }
1067
1068   /**
1069    *
1070    * @param validateId to validate if id already exists: not needed for update !
1071    */
1072   activateRemoteRepositoryFormValidation=function(validateId){
1073     // FIXME find a way to activate cronExpression validation only if downloadRemote is activated !
1074     var validator = null;
1075     if (validateId){
1076       validator = $("#main-content" ).find("#remote-repository-edit-form").validate({
1077         rules: {
1078           id: {
1079             required: true,
1080             remote: {
1081               url: "restServices/archivaUiServices/dataValidatorService/remoteRepositoryIdNotExists",
1082               type: "get"
1083             }
1084           }
1085         },
1086         showErrors: function(validator, errorMap, errorList) {
1087           customShowError("#main-content #remote-repository-edit-form",validator,errorMap,errorMap);
1088         }
1089       });
1090     } else {
1091       validator = $("#main-content" ).find("#remote-repository-edit-form").validate({
1092         rules: {
1093           id: {
1094             required: true
1095           }
1096         },
1097         showErrors: function(validator, errorMap, errorList) {
1098           customShowError("#main-content #remote-repository-edit-form",validator,errorMap,errorMap);
1099         }
1100       });
1101     }
1102     validator.settings.messages["cronExpression"]=$.i18n.prop("cronExpression.notvalid");
1103     validator.settings.messages["id"]=$.i18n.prop("id.required.or.alreadyexists");
1104   }
1105
1106   activateRemoteRepositoriesGridTab=function(){
1107     var mainContent = $("#main-content");
1108     mainContent.find("#remote-repository-edit-li").removeClass("active");
1109     mainContent.find("#remote-repository-edit").removeClass("active");
1110
1111     mainContent.find("#remote-repositories-view-li").addClass("active");
1112     mainContent.find("#remote-repositories-view").addClass("active");
1113     mainContent.find("#remote-repository-edit-li a").html($.i18n.prop("add"));
1114   }
1115
1116   activateRemoteRepositoryEditTab=function(){
1117     var mainContent = $("#main-content");
1118     mainContent.find("#remote-repositories-view-li").removeClass("active");
1119     mainContent.find("#remote-repositories-view").removeClass("active");
1120
1121     mainContent.find("#remote-repository-edit-li").addClass("active");
1122     mainContent.find("#remote-repository-edit").addClass("active");
1123   }
1124
1125   //---------------------------
1126   // Screen loading
1127   //---------------------------
1128
1129    /**
1130     *
1131     * @param successFnManagedRepositories function called with param managedRepositoriesViewModel when managed repositories grid has been displayed
1132     * @param successFnRemoteRepositories  function called with param remoteRepositoriesViewModel when remote repositories grid has been displayed
1133     */
1134   displayRepositoriesGrid=function(successFnManagedRepositories,successFnRemoteRepositories){
1135     screenChange();
1136     var mainContent = $("#main-content");
1137     mainContent.html(mediumSpinnerImg());
1138     mainContent.html($("#repositoriesMain").tmpl());
1139     mainContent.find("#repositories-tabs a:first").tab("show");
1140
1141     mainContent.find("#managed-repositories-content").append(mediumSpinnerImg());
1142     mainContent.find("#remote-repositories-content").append(mediumSpinnerImg());
1143
1144     var managedRepositoriesViewModel = new ManagedRepositoriesViewModel();
1145     var remoteRepositoriesViewModel = new RemoteRepositoriesViewModel();
1146
1147     $.ajax({
1148         url: "restServices/archivaServices/archivaAdministrationService/applicationUrl",
1149         type: "GET",
1150         dataType: 'text',
1151         success: function(applicationUrl){
1152           $.log("applicationUrl:"+applicationUrl);
1153           loadManagedRepositories(function(data) {
1154
1155
1156             managedRepositoriesViewModel.managedRepositories(
1157                 mapManagedRepositories(data,applicationUrl?applicationUrl:window.location.toString().substringBeforeLast("/")));
1158
1159             managedRepositoriesViewModel.gridViewModel = new ko.simpleGrid.viewModel({
1160               data: managedRepositoriesViewModel.managedRepositories,
1161               columns: [
1162                 {
1163                   headerText: $.i18n.prop('identifier'),
1164                   rowText: "id"
1165                 },
1166                 {
1167                   headerText: $.i18n.prop('name'),
1168                   rowText: "name"
1169                 },
1170                 {
1171                 headerText: $.i18n.prop('type'),
1172                 rowText: "getTypeLabel",
1173                 // FIXME i18n
1174                 title: "Repository type (default is Maven 2)"
1175                 }
1176               ],
1177               pageSize: 5,
1178               gridUpdateCallBack: function(){
1179                 // a bit ugly
1180                 //$("#main-content" ).find("#managed-repositories-table").find("[title]").tooltip({animation:"false"});
1181               }
1182             });
1183             var mainContent = $("#main-content");
1184             ko.applyBindings(managedRepositoriesViewModel,mainContent.find("#managed-repositories-view").get(0));
1185             activatePopoverDoc();
1186             mainContent.find("#managed-repositories-pills #managed-repositories-view-a").tab('show');
1187             removeMediumSpinnerImg(mainContent.find("#managed-repositories-content"));
1188             activateManagedRepositoriesGridTab();
1189             if(successFnManagedRepositories){
1190               successFnManagedRepositories(managedRepositoriesViewModel);
1191             }
1192           });
1193
1194           loadRemoteRepositories(function(data) {
1195             remoteRepositoriesViewModel.remoteRepositories(mapRemoteRepositories(data));
1196             remoteRepositoriesViewModel.gridViewModel = new ko.simpleGrid.viewModel({
1197               data: remoteRepositoriesViewModel.remoteRepositories,
1198               columns: [
1199                 {
1200                   headerText: $.i18n.prop('identifier'),
1201                   rowText: "id"
1202                 },
1203                 {
1204                   headerText: $.i18n.prop('name'),
1205                   rowText: "name"
1206                 },
1207                 {
1208                   headerText: $.i18n.prop('url'),
1209                   rowText: "url"
1210                 },
1211                 {
1212                 headerText: $.i18n.prop('type'),
1213                 rowText: "getTypeLabel",
1214                 // FIXME i18n
1215                 title: "Repository type (default is Maven 2)"
1216                 }
1217               ],
1218               pageSize: 5,
1219               gridUpdateCallBack: function(){
1220                 //$("#main-content" ).find("#remote-repositories-table").find("[title]").tooltip();
1221               }
1222             });
1223             var mainContent = $("#main-content");
1224             ko.applyBindings(remoteRepositoriesViewModel,mainContent.find("#remote-repositories-view").get(0));
1225             mainContent.find("#remote-repositories-pills #remote-repositories-view-a").tab('show')
1226             removeMediumSpinnerImg(mainContent.find("#remote-repositories-content"));
1227             activatePopoverDoc();
1228             if(successFnRemoteRepositories){
1229               successFnRemoteRepositories(managedRepositoriesViewModel);
1230             }
1231           });
1232         }
1233     }
1234     );
1235
1236
1237     mainContent.find("#managed-repositories-pills").on('show', function (e) {
1238       var mainContent = $("#main-content");
1239       if ($(e.target).attr("href")=="#managed-repository-edit") {
1240         var managedRepo=new ManagedRepository();
1241         managedRepo.cronExpression("0 0 * * * ?");
1242         var viewModel = new ManagedRepositoryViewModel(managedRepo,false,managedRepositoriesViewModel);
1243         ko.applyBindings(viewModel,mainContent.find("#managed-repository-edit").get(0));
1244         activateManagedRepositoryFormValidation();
1245         activatePopoverDoc();
1246       }
1247       if ($(e.target).attr("href")=="#managed-repositories-view") {
1248         mainContent.find("#managed-repository-edit-li a").html($.i18n.prop("add"));
1249       }
1250
1251     });
1252
1253     mainContent.find("#remote-repositories-pills").on('show', function (e) {
1254       if ($(e.target).attr("href")=="#remote-repository-edit") {
1255         $.ajax("restServices/archivaServices/networkProxyService/getNetworkProxies", {
1256             type: "GET",
1257             dataType: 'json',
1258             success: function(data) {
1259               var remoteRepo=new RemoteRepository();
1260               remoteRepo.cronExpression("0 0 08 ? * SUN");
1261               var viewModel = new RemoteRepositoryViewModel(remoteRepo,false,remoteRepositoriesViewModel);
1262               viewModel.networkProxies(mapNetworkProxies(data));
1263               ko.applyBindings(viewModel,mainContent.find("#remote-repository-edit").get(0));
1264               activateRemoteRepositoryFormValidation(true);
1265               activatePopoverDoc();
1266             }
1267         })
1268       }
1269       if ($(e.target).attr("href")=="#remote-repositories-view") {
1270         $("#main-content" ).find("#remote-repository-edit-li" ).find("a").html($.i18n.prop("add"));
1271       }
1272
1273     });
1274
1275   }
1276
1277   loadManagedRepositories=function(successCallBackFn,errorCallBackFn){
1278     $.ajax("restServices/archivaServices/managedRepositoriesService/getManagedRepositories", {
1279         type: "GET",
1280         dataType: 'json',
1281         success: successCallBackFn,
1282         error: errorCallBackFn
1283     });
1284   }
1285
1286   loadRemoteRepositories=function(successCallBackFn,errorCallBackFn){
1287     $.ajax("restServices/archivaServices/remoteRepositoriesService/getRemoteRepositories", {
1288         type: "GET",
1289         dataType: 'json',
1290         success: successCallBackFn,
1291         error: errorCallBackFn
1292     });
1293   }
1294
1295   findManagedRepository=function(id,managedRepositories){
1296     var managedRepository=$.grep(managedRepositories,
1297                                     function(repo,idx){
1298                                       return repo.id()==id;
1299                                     }
1300                           );
1301     return ($.isArray(managedRepository) && managedRepository.length>0) ? managedRepository[0]:new ManagedRepository();
1302   }
1303
1304 });