0a910fe9bae7a742023daafef17424d2851c04db
[vfc/nfvo/wfengine.git] /
1 /*******************************************************************************
2  * Copyright (c) 2012-2013,2015 University of Stuttgart.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * and the Apache License 2.0 which both accompany this distribution,
6  * and are available at http://www.eclipse.org/legal/epl-v10.html
7  * and http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Contributors:
10  *     Oliver Kopp - initial API and implementation
11  *******************************************************************************/
12 package org.eclipse.winery.repository.resources.entitytemplates.artifacttemplates;
13
14 import java.io.BufferedInputStream;
15 import java.io.IOException;
16 import java.io.InputStream;
17 import java.util.ArrayList;
18 import java.util.List;
19 import java.util.SortedSet;
20
21 import javax.ws.rs.Consumes;
22 import javax.ws.rs.DELETE;
23 import javax.ws.rs.GET;
24 import javax.ws.rs.HeaderParam;
25 import javax.ws.rs.POST;
26 import javax.ws.rs.Path;
27 import javax.ws.rs.PathParam;
28 import javax.ws.rs.Produces;
29 import javax.ws.rs.core.Context;
30 import javax.ws.rs.core.MediaType;
31 import javax.ws.rs.core.Response;
32 import javax.ws.rs.core.Response.Status;
33 import javax.ws.rs.core.UriInfo;
34
35 import org.apache.commons.io.FilenameUtils;
36 import org.apache.commons.lang3.StringUtils;
37 import org.eclipse.winery.common.RepositoryFileReference;
38 import org.eclipse.winery.common.Util;
39 import org.eclipse.winery.repository.Constants;
40 import org.eclipse.winery.repository.Utils;
41 import org.eclipse.winery.repository.backend.BackendUtils;
42 import org.eclipse.winery.repository.backend.Repository;
43 import org.eclipse.winery.repository.datatypes.FileMeta;
44 import org.eclipse.winery.repository.datatypes.ids.elements.ArtifactTemplateDirectoryId;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48 import com.sun.jersey.api.view.Viewable;
49 import com.sun.jersey.core.header.FormDataContentDisposition;
50 import com.sun.jersey.multipart.FormDataBodyPart;
51 import com.sun.jersey.multipart.FormDataParam;
52
53 public class FilesResource {
54         
55         private static final Logger logger = LoggerFactory.getLogger(FilesResource.class);
56         private final ArtifactTemplateDirectoryId fileDir;
57         
58         
59         public FilesResource(ArtifactTemplateDirectoryId fileDir) {
60                 this.fileDir = fileDir;
61         }
62         
63         private String getData4jqueryFileUpload(List<FileMeta> metas) {
64                 String data4jqueryFileUpload = Utils.Object2JSON(metas);
65                 data4jqueryFileUpload = "{\"files\":" + data4jqueryFileUpload + "}";
66                 return data4jqueryFileUpload;
67         }
68         
69         /**
70          * Handles the upload of a <em>single</em> file. Adds the given file to the
71          * current artifact template.
72          * 
73          * If the file already exists, is it <em>overridden</em>
74          * 
75          * @return JSON with data required by JQuery-File-Upload (see
76          *         https://github.com/blueimp/jQuery-File-Upload/wiki/Setup)
77          */
78         @POST
79         @Produces(MediaType.APPLICATION_JSON)
80         @Consumes(MediaType.MULTIPART_FORM_DATA)
81         public Response onPost(@FormDataParam("files[]") InputStream uploadedInputStream, @FormDataParam("files[]") FormDataContentDisposition fileDetail, @FormDataParam("files[]") FormDataBodyPart body, @Context UriInfo uriInfo) {
82                 // existence check not required as instantiation of the resource ensures that the object only exists if the resource exists
83                 FilesResource.logger.debug("Beginning with file upload");
84                 
85                 String fileName = fileDetail.getFileName();
86                 if (StringUtils.isEmpty(fileName)) {
87                         return Response.status(Status.BAD_REQUEST).build();
88                 }
89                 RepositoryFileReference ref = this.fileName2fileRef(fileName, false);
90                 
91                 // TODO: instead of fixing the media type, we could overwrite the browser's mediatype by using some user configuration
92                 BufferedInputStream bis = new BufferedInputStream(uploadedInputStream);
93                 MediaType mediaType = Utils.getFixedMimeType(bis, fileName, body.getMediaType());
94                 
95                 Response response = BackendUtils.putContentToFile(ref, bis, mediaType);
96                 if (response.getStatus() == Status.INTERNAL_SERVER_ERROR.getStatusCode()) {
97                         return response;
98                 }
99                 
100                 // create FileMeta object
101                 String URL = Utils.getAbsoluteURL(this.fileDir) + Util.URLencode(fileName);
102                 String thumbnailURL = uriInfo.getBaseUriBuilder().path(Constants.PATH_MIMETYPEIMAGES).path(FilenameUtils.getExtension(fileName) + Constants.SUFFIX_MIMETYPEIMAGES).build().toString();
103                 long size;
104                 try {
105                         size = Repository.INSTANCE.getSize(ref);
106                 } catch (IOException e) {
107                         FilesResource.logger.error(e.getMessage(), e);
108                         return Response.serverError().entity(e.getMessage()).build();
109                 }
110                 FileMeta fileMeta = new FileMeta(fileName, size, URL, thumbnailURL);
111                 
112                 List<FileMeta> metas = new ArrayList<FileMeta>();
113                 metas.add(fileMeta);
114                 return Response.created(Utils.createURI(URL)).entity(this.getData4jqueryFileUpload(metas)).build();
115         }
116         
117         /**
118          * Returns a list of file meta object
119          */
120         @GET
121         @Produces(MediaType.APPLICATION_JSON)
122         public String getJSON() {
123                 return this.getData4jqueryFileUpload(this.getAllFileMetas());
124         }
125         
126         private List<FileMeta> getAllFileMetas() {
127                 List<FileMeta> res = new ArrayList<FileMeta>();
128                 SortedSet<RepositoryFileReference> fileRefs = Repository.INSTANCE.getContainedFiles(this.fileDir);
129                 for (RepositoryFileReference ref : fileRefs) {
130                         res.add(new FileMeta(ref));
131                 }
132                 return res;
133         }
134         
135         private RepositoryFileReference fileName2fileRef(String fileName, boolean encoded) {
136                 if (encoded) {
137                         fileName = Util.URLdecode(fileName);
138                 }
139                 RepositoryFileReference ref = new RepositoryFileReference(this.fileDir, fileName);
140                 return ref;
141         }
142         
143         @GET
144         @Produces(MediaType.TEXT_HTML)
145         public Viewable getHTML() {
146                 return new Viewable("/jsp/entitytemplates/artifacttemplates/files.jsp");
147         }
148         
149         @GET
150         @Path("/{fileName}")
151         public Response getFile(@PathParam("fileName") String fileName, @HeaderParam("If-Modified-Since") String modified) {
152                 RepositoryFileReference ref = this.fileName2fileRef(fileName, true);
153                 return BackendUtils.returnRepoPath(ref, modified);
154         }
155         
156         @DELETE
157         @Path("/{fileName}")
158         public Response deleteFile(@PathParam("fileName") String fileName) {
159                 RepositoryFileReference ref = this.fileName2fileRef(fileName, true);
160                 return BackendUtils.delete(ref);
161         }
162         
163 }