package act.util;
/*-
* #%L
* ACT Framework
* %%
* Copyright (C) 2014 - 2017 ActFramework
* %%
* Licensed 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.
* #L%
*/
import act.Act;
import act.app.ActionContext;
import act.app.App;
import act.handler.builtin.AlwaysNotFound;
import act.handler.builtin.controller.FastRequestHandler;
import org.apache.commons.fileupload.FileItem;
import org.osgl.http.H;
import org.osgl.storage.ISObject;
import org.osgl.storage.IStorageService;
import org.osgl.storage.KeyGenerator;
import org.osgl.storage.KeyNameProvider;
import org.osgl.storage.impl.FileSystemService;
import org.osgl.storage.impl.SObject;
import org.osgl.util.C;
import org.osgl.util.E;
import org.osgl.util.IO;
import org.osgl.util.S;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.UUID;
public class UploadFileStorageService extends FileSystemService {
public static final KeyNameProvider ACT_STORAGE_KEY_NAME_PROVIDER = new KeyNameProvider() {
@Override
public String newKeyName() {
return Act.cuid();
}
};
public UploadFileStorageService(Map<String, String> conf) {
super(conf);
this.setKeyNameProvider(ACT_STORAGE_KEY_NAME_PROVIDER);
}
public static IStorageService create(App app) {
File tmp = app.tmpDir();
if (!tmp.exists() && !tmp.mkdirs()) {
throw E.unexpected("Cannot create tmp dir");
}
Map<String, String> conf = C.newMap("storage.fs.home.dir", Files.file(app.tmpDir(), "uploads").getAbsolutePath(),
"storage.keygen", KeyGenerator.Predefined.BY_DATE.name());
conf.put(IStorageService.CONF_ID, "__upload");
conf.put("storage.storeSuffix", "false");
return new UploadFileStorageService(conf);
}
public static ISObject store(FileItem file, App app) {
IStorageService ss = app.uploadFileStorageService();
try {
String key = newKey();
ISObject sobj = SObject.of(file.getInputStream());
sobj.setAttribute(SObject.ATTR_FILE_NAME, file.getName());
sobj.setAttribute(SObject.ATTR_CONTENT_TYPE, file.getContentType());
sobj.setAttribute(SObject.ATTR_URL, "/~upload/" + sobj.getKey());
ss.put(key, sobj);
return ss.get(key);
} catch (IOException e) {
throw E.ioException(e);
}
}
public static String newKey() {
// Note we don't use App.cuid() here to get higher level security
return UUID.randomUUID().toString();
}
public static class UploadFileGetter extends FastRequestHandler {
@Override
public void handle(ActionContext context) {
String key = context.paramVal("path");
if (S.blank(key)) {
AlwaysNotFound.INSTANCE.handle(context);
return;
}
ISObject sobj = context.app().uploadFileStorageService().get(key);
if (null == sobj) {
AlwaysNotFound.INSTANCE.handle(context);
return;
}
H.Format fmt = H.Format.of(sobj.getAttribute(ISObject.ATTR_CONTENT_TYPE));
InputStream is = new BufferedInputStream(sobj.asInputStream());
H.Response resp = context.resp();
if (null != fmt && H.Format.UNKNOWN != fmt) {
resp.contentType(fmt.contentType());
}
IO.copy(is, context.resp().outputStream());
}
@Override
public String toString() {
return "Upload file getter";
}
}
}