diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java index 6107abcd1b..1c9d2f673c 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java @@ -50,6 +50,7 @@ import org.slf4j.LoggerFactory; import sonia.scm.NotSupportedFeatuerException; import sonia.scm.Type; +import sonia.scm.api.rest.RestActionUploadResult; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryAllreadyExistExeption; import sonia.scm.repository.RepositoryException; @@ -161,54 +162,7 @@ public class RepositoryImportResource @PathParam("type") String type, @FormDataParam("name") String name, @FormDataParam("bundle") InputStream inputStream) { - SecurityUtils.getSubject().checkRole(Role.ADMIN); - - checkArgument(!Strings.isNullOrEmpty(name), - "request does not contain name of the repository"); - checkNotNull(inputStream, "bundle inputStream is required"); - - Repository repository; - - try - { - Type t = type(type); - - checkSupport(t, Command.UNBUNDLE, "bundle"); - - repository = create(type, name); - - RepositoryService service = null; - - File file = File.createTempFile("scm-import-", ".bundle"); - - try - { - long length = Files.asByteSink(file).writeFrom(inputStream); - - logger.info("copied {} bytes to temp, start bundle import", length); - service = serviceFactory.create(repository); - service.getUnbundleCommand().unbundle(file); - } - catch (RepositoryException ex) - { - handleImportFailure(ex, repository); - } - catch (IOException ex) - { - handleImportFailure(ex, repository); - } - finally - { - IOUtil.close(service); - IOUtil.delete(file); - } - } - catch (IOException ex) - { - logger.warn("could not create temporary file", ex); - - throw new WebApplicationException(ex); - } + Repository repository = doImportFromBundle(type, name, inputStream); return buildResponse(uriInfo, repository); } @@ -230,7 +184,6 @@ public class RepositoryImportResource * * * - * @param uriInfo uri info * @param type repository type * @param name name of the repository * @param inputStream input bundle @@ -242,11 +195,25 @@ public class RepositoryImportResource @Path("{type}/bundle.html") @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.TEXT_HTML) - public Response importFromBundleUI(@Context UriInfo uriInfo, - @PathParam("type") String type, @FormDataParam("name") String name, + public Response importFromBundleUI(@PathParam("type") String type, + @FormDataParam("name") String name, @FormDataParam("bundle") InputStream inputStream) { - return importFromBundle(uriInfo, type, name, inputStream); + Response response; + + try + { + doImportFromBundle(type, name, inputStream); + response = Response.ok(new RestActionUploadResult(true)).build(); + } + catch (WebApplicationException ex) + { + logger.warn("error durring bundle import", ex); + response = Response.fromResponse(ex.getResponse()).entity( + new RestActionUploadResult(false)).build(); + } + + return response; } /** @@ -503,6 +470,71 @@ public class RepositoryImportResource return repository; } + /** + * Start bundle import. + * + * + * @param type repository type + * @param name name of the repository + * @param inputStream bundle stream + * + * @return imported repository + */ + private Repository doImportFromBundle(String type, String name, + InputStream inputStream) + { + SecurityUtils.getSubject().checkRole(Role.ADMIN); + + checkArgument(!Strings.isNullOrEmpty(name), + "request does not contain name of the repository"); + checkNotNull(inputStream, "bundle inputStream is required"); + + Repository repository; + + try + { + Type t = type(type); + + checkSupport(t, Command.UNBUNDLE, "bundle"); + + repository = create(type, name); + + RepositoryService service = null; + + File file = File.createTempFile("scm-import-", ".bundle"); + + try + { + long length = Files.asByteSink(file).writeFrom(inputStream); + + logger.info("copied {} bytes to temp, start bundle import", length); + service = serviceFactory.create(repository); + service.getUnbundleCommand().unbundle(file); + } + catch (RepositoryException ex) + { + handleImportFailure(ex, repository); + } + catch (IOException ex) + { + handleImportFailure(ex, repository); + } + finally + { + IOUtil.close(service); + IOUtil.delete(file); + } + } + catch (IOException ex) + { + logger.warn("could not create temporary file", ex); + + throw new WebApplicationException(ex); + } + + return repository; + } + /** * Method description * diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.importwindow.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.importwindow.js index 975ec04bf0..43d870517f 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.importwindow.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.importwindow.js @@ -78,9 +78,6 @@ Sonia.repository.ImportPanel = Ext.extend(Ext.Panel, { nextText: 'Next', finishText: 'Finish', - // cache - importForm: null, - imported: [], importJobsFinished: 0, importJobs: 0, @@ -105,7 +102,11 @@ Sonia.repository.ImportPanel = Ext.extend(Ext.Panel, { initComponent: function(){ this.addEvents('finish'); - + + // fix initialization bug + this.imported = []; + this.importJobsFinished = 0; + this.importJobs = 0; var importedStore = new Ext.data.JsonStore({ fields: ['type', 'name'] @@ -256,12 +257,13 @@ Sonia.repository.ImportPanel = Ext.extend(Ext.Panel, { }] },{ id: 'importFileLayout', - layout: 'form', + xtype: 'form', + fileUpload: true, items: [{ id: 'importFileName', xtype: 'textfield', fieldLabel: 'Repository name', - name: 'importFileName', + name: 'name', type: 'textfield', width: 250, helpText: this.importFileNameHelpText @@ -270,7 +272,7 @@ Sonia.repository.ImportPanel = Ext.extend(Ext.Panel, { xtype: 'fileuploadfield', fieldLabel: 'Import File', ctCls: 'import-fu', - name: 'importFile', + name: 'bundle', helpText: this.importFileHelpText, cls: 'import-fu', buttonCfg: { @@ -339,9 +341,13 @@ Sonia.repository.ImportPanel = Ext.extend(Ext.Panel, { { next = 1; } - else if ( id === 'importUrlLayout' && direction === 1 ){ - var panel = Ext.getCmp('importUrlLayout'); - this.importFromUrl(layout, panel.getForm().getValues()); + else if ( id === 'importUrlLayout' && direction === 1 ) + { + this.importFromUrl(layout, Ext.getCmp('importUrlLayout').getForm().getValues()); + } + else if ( id === 'importFileLayout' && direction === 1 ) + { + this.importFromFile(layout, Ext.getCmp('importFileLayout').getForm()); } if ( next >= 0 ){ @@ -365,6 +371,27 @@ Sonia.repository.ImportPanel = Ext.extend(Ext.Panel, { } }, + importFromFile: function(layout, form){ + form.submit({ + url: restUrl + 'import/repositories/' + this.repositoryType + '/bundle.html', + scope: this, + success: function(form, action){ + this.appendImported([{ + name: form.getValues().name, + type: this.repositoryType + }]); + layout.setActiveItem(4); + }, + failure: function(form, action){ + main.handleRestFailure( + action.response, + this.errorTitleText, + this.errorMsgText + ); + } + }); + }, + importFromUrl: function(layout, repository){ Ext.Ajax.request({ url: restUrl + 'import/repositories/' + this.repositoryType + '/url.json',