mirror of https://github.com/apache/archiva.git
[MRM-1586] rewrite upload artifact page
add REST service to upload files. git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@1306256 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
5a812b4b63
commit
e9e1fd8568
|
@ -376,4 +376,17 @@ appearance-configuration.logoLocation-label=Logo Location
|
||||||
appearance-configuration.updated=Appearance has been updated
|
appearance-configuration.updated=Appearance has been updated
|
||||||
appearance-configuration.updating-error=Error during appearance setting
|
appearance-configuration.updating-error=Error during appearance setting
|
||||||
|
|
||||||
|
#file upload
|
||||||
|
menu.artifacts.upload=Upload Artifact
|
||||||
|
fileupload.cancel=Cancel Upload
|
||||||
|
fileupload.start=Start Upload
|
||||||
|
fileupload.error=Error Upload
|
||||||
|
fileupload.destroy=Delete Upload
|
||||||
|
fileupload.errors.maxFileSize=File is too big
|
||||||
|
fileupload.errors.minFileSize=File is too small
|
||||||
|
fileupload.errors.acceptFileTypes=Filetype not allowed
|
||||||
|
fileupload.errors.maxNumberOfFiles=Max number of files exceeded
|
||||||
|
fileupload.errors.uploadedBytes=Uploaded bytes exceed file size
|
||||||
|
fileupload.errors.emptyResult=Empty file upload result
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
package org.apache.archiva.webapp.ui.services.api;
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
|
||||||
|
import org.apache.archiva.webapp.ui.services.model.FileMetadata;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import javax.ws.rs.core.Context;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Olivier Lamy
|
||||||
|
*/
|
||||||
|
@Service( "fileUploadService#rest" )
|
||||||
|
public class DefaultFileUploadService
|
||||||
|
implements FileUploadService
|
||||||
|
{
|
||||||
|
private Logger log = LoggerFactory.getLogger( getClass() );
|
||||||
|
|
||||||
|
@Context
|
||||||
|
private HttpServletRequest httpServletRequest;
|
||||||
|
|
||||||
|
@Context
|
||||||
|
private HttpServletResponse httpServletResponse;
|
||||||
|
|
||||||
|
public FileMetadata post()
|
||||||
|
throws ArchivaRestServiceException
|
||||||
|
{
|
||||||
|
log.info( "uploading file" );
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] bytes = IOUtils.toByteArray( httpServletRequest.getInputStream() );
|
||||||
|
return new FileMetadata( "thefile", bytes.length, "theurl" );
|
||||||
|
}
|
||||||
|
catch ( IOException e )
|
||||||
|
{
|
||||||
|
throw new ArchivaRestServiceException( e.getMessage(),
|
||||||
|
Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package org.apache.archiva.webapp.ui.services.api;
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
|
||||||
|
import org.apache.archiva.webapp.ui.services.model.FileMetadata;
|
||||||
|
import org.codehaus.plexus.redback.authorization.RedbackAuthorization;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Olivier Lamy
|
||||||
|
* @since 1.4-M3
|
||||||
|
*/
|
||||||
|
@Path( "/fileUploadService/" )
|
||||||
|
public interface FileUploadService
|
||||||
|
{
|
||||||
|
|
||||||
|
@Path( "upload" )
|
||||||
|
@POST
|
||||||
|
@Consumes( MediaType.MULTIPART_FORM_DATA )
|
||||||
|
@RedbackAuthorization( noRestriction = true )
|
||||||
|
FileMetadata post()
|
||||||
|
throws ArchivaRestServiceException;
|
||||||
|
}
|
|
@ -0,0 +1,107 @@
|
||||||
|
package org.apache.archiva.webapp.ui.services.model;
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Olivier Lamy
|
||||||
|
* @since 1.4-M3
|
||||||
|
*/
|
||||||
|
@XmlRootElement( name = "fileMetadata" )
|
||||||
|
public class FileMetadata
|
||||||
|
{
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private long size;
|
||||||
|
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
private String deleteUrl;
|
||||||
|
|
||||||
|
private String deleteType;
|
||||||
|
|
||||||
|
public FileMetadata()
|
||||||
|
{
|
||||||
|
// no op
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileMetadata( String filename, long size, String url )
|
||||||
|
{
|
||||||
|
this.name = filename;
|
||||||
|
this.size = size;
|
||||||
|
this.url = url;
|
||||||
|
this.deleteUrl = url;
|
||||||
|
this.deleteType = "DELETE";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName( String name )
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getSize()
|
||||||
|
{
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSize( long size )
|
||||||
|
{
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl()
|
||||||
|
{
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl( String url )
|
||||||
|
{
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
@XmlElement( name = "delete_url" )
|
||||||
|
public String getDeleteUrl()
|
||||||
|
{
|
||||||
|
return deleteUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setDeleteUrl( String deleteUrl )
|
||||||
|
{
|
||||||
|
this.deleteUrl = deleteUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@XmlElement( name = "delete_type" )
|
||||||
|
public String getDeleteType()
|
||||||
|
{
|
||||||
|
return deleteType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeleteType( String deleteType )
|
||||||
|
{
|
||||||
|
this.deleteType = deleteType;
|
||||||
|
}
|
||||||
|
}
|
|
@ -66,6 +66,7 @@
|
||||||
<jaxrs:serviceBeans>
|
<jaxrs:serviceBeans>
|
||||||
<ref bean="runtimeInfoService#rest"/>
|
<ref bean="runtimeInfoService#rest"/>
|
||||||
<ref bean="dataValidatorService#rest"/>
|
<ref bean="dataValidatorService#rest"/>
|
||||||
|
<ref bean="fileUploadService#rest"/>
|
||||||
</jaxrs:serviceBeans>
|
</jaxrs:serviceBeans>
|
||||||
|
|
||||||
<jaxrs:outInterceptors>
|
<jaxrs:outInterceptors>
|
||||||
|
|
|
@ -131,7 +131,12 @@ function() {
|
||||||
}
|
}
|
||||||
if (screen=='appearance-configuration'&& hasKarma('archiva-manage-configuration')){
|
if (screen=='appearance-configuration'&& hasKarma('archiva-manage-configuration')){
|
||||||
displayAppearanceConfiguration();
|
displayAppearanceConfiguration();
|
||||||
return
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (screen=='artifact-upload' && hasKarma('archiva-upload-repository')){
|
||||||
|
displayUploadArtifact();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// by default display search screen
|
// by default display search screen
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script id="file-upload-tmpl" type="text/html">
|
<script id="file-upload-tmpl" type="text/html">
|
||||||
<form id="fileupload" action="../server/php/" method="POST" enctype="multipart/form-data">
|
<form id="fileupload" action="restServices/archivaUiServices/fileUploadService/upload" method="POST" enctype="multipart/form-data">
|
||||||
<!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->
|
<!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->
|
||||||
<div class="row fileupload-buttonbar">
|
<div class="row fileupload-buttonbar">
|
||||||
<div class="span7">
|
<div class="span7">
|
||||||
|
@ -47,7 +47,7 @@
|
||||||
<td class="name"><span>{%=file.name%}</span></td>
|
<td class="name"><span>{%=file.name%}</span></td>
|
||||||
<td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
|
<td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
|
||||||
{% if (file.error) { %}
|
{% if (file.error) { %}
|
||||||
<td class="error" colspan="2"><span class="label label-important">{%=$.i18n.prop('locale.fileupload.error')%}</span> {%=$.i18n.prop('locale.fileupload.errors',[file.error]) || file.error%}</td>
|
<td class="error" colspan="2"><span class="label label-important">{%=$.i18n.prop('fileupload.error')%}</span> {%=$.i18n.prop('fileupload.errors.'+[file.error]) || file.error%}</td>
|
||||||
{% } else if (o.files.valid && !i) { %}
|
{% } else if (o.files.valid && !i) { %}
|
||||||
<td>
|
<td>
|
||||||
<div class="progress progress-success progress-striped active"><div class="bar" style="width:0%;"></div></div>
|
<div class="progress progress-success progress-striped active"><div class="bar" style="width:0%;"></div></div>
|
||||||
|
@ -55,7 +55,7 @@
|
||||||
<td class="start">{% if (!o.options.autoUpload) { %}
|
<td class="start">{% if (!o.options.autoUpload) { %}
|
||||||
<button class="btn btn-primary">
|
<button class="btn btn-primary">
|
||||||
<i class="icon-upload icon-white"></i>
|
<i class="icon-upload icon-white"></i>
|
||||||
<span>{%=$.i18n.prop('locale.fileupload.start')%}</span>
|
<span>{%=$.i18n.prop('fileupload.start')%}</span>
|
||||||
</button>
|
</button>
|
||||||
{% } %}</td>
|
{% } %}</td>
|
||||||
{% } else { %}
|
{% } else { %}
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
<td class="cancel">{% if (!i) { %}
|
<td class="cancel">{% if (!i) { %}
|
||||||
<button class="btn btn-warning">
|
<button class="btn btn-warning">
|
||||||
<i class="icon-ban-circle icon-white"></i>
|
<i class="icon-ban-circle icon-white"></i>
|
||||||
<span>{%=$.i18n.prop('locale.fileupload.cancel')%}</span>
|
<span>{%=$.i18n.prop('fileupload.cancel')%}</span>
|
||||||
</button>
|
</button>
|
||||||
{% } %}</td>
|
{% } %}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -78,7 +78,7 @@
|
||||||
<td></td>
|
<td></td>
|
||||||
<td class="name"><span>{%=file.name%}</span></td>
|
<td class="name"><span>{%=file.name%}</span></td>
|
||||||
<td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
|
<td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
|
||||||
<td class="error" colspan="2"><span class="label label-important">{%=$.i18n.prop('locale.fileupload.error')%}</span> {%=$.i18n.prop('locale.fileupload.errors',[file.error]) || file.error%}</td>
|
<td class="error" colspan="2"><span class="label label-important">{%=$.i18n.prop('fileupload.error')%}</span> {%=$.i18n.prop('fileupload.errors.'+[file.error]) || file.error%}</td>
|
||||||
{% } else { %}
|
{% } else { %}
|
||||||
<td class="preview">{% if (file.thumbnail_url) { %}
|
<td class="preview">{% if (file.thumbnail_url) { %}
|
||||||
<a href="{%=file.url%}" title="{%=file.name%}" rel="gallery" download="{%=file.name%}"><img src="{%=file.thumbnail_url%}"></a>
|
<a href="{%=file.url%}" title="{%=file.name%}" rel="gallery" download="{%=file.name%}"><img src="{%=file.thumbnail_url%}"></a>
|
||||||
|
@ -92,7 +92,7 @@
|
||||||
<td class="delete">
|
<td class="delete">
|
||||||
<button class="btn btn-danger" data-type="{%=file.delete_type%}" data-url="{%=file.delete_url%}">
|
<button class="btn btn-danger" data-type="{%=file.delete_type%}" data-url="{%=file.delete_url%}">
|
||||||
<i class="icon-trash icon-white"></i>
|
<i class="icon-trash icon-white"></i>
|
||||||
<span>{%=$.i18n.prop('locale.fileupload.destroy')%}</span>
|
<span>{%=$.i18n.prop('fileupload.destroy')%}</span>
|
||||||
</button>
|
</button>
|
||||||
<input type="checkbox" name="delete" value="1">
|
<input type="checkbox" name="delete" value="1">
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -28,7 +28,9 @@
|
||||||
<a href="#" id="menu-find-browse-a" onclick="displayBrowse(true)">${$.i18n.prop('menu.artifacts.browse')}</a>
|
<a href="#" id="menu-find-browse-a" onclick="displayBrowse(true)">${$.i18n.prop('menu.artifacts.browse')}</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="#" id="menu-find-upload-a" onclick="displayUploadArtifact(true)">${$.i18n.prop('menu.artifacts.upload')}</a>
|
<a href="#" id="menu-find-upload-a" redback-permissions="{permissions: ['archiva-upload-repository']}" onclick="displayUploadArtifact(true)">
|
||||||
|
${$.i18n.prop('menu.artifacts.upload')}
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue