diff --git a/wizard-server/src/main/java/org/cobbzilla/wizard/filters/EntityFilter.java b/wizard-server/src/main/java/org/cobbzilla/wizard/filters/EntityFilter.java deleted file mode 100644 index d0a9c50..0000000 --- a/wizard-server/src/main/java/org/cobbzilla/wizard/filters/EntityFilter.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.cobbzilla.wizard.filters; - -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; - -import javax.ws.rs.container.ContainerRequestContext; -import javax.ws.rs.container.ContainerResponseContext; -import javax.ws.rs.container.ContainerResponseFilter; -import java.io.IOException; -import java.lang.reflect.Type; - -import static org.cobbzilla.util.reflect.ReflectionUtil.forName; -import static org.cobbzilla.util.reflect.ReflectionUtil.getFirstTypeParam; - -@Slf4j -public abstract class EntityFilter implements ContainerResponseFilter { - - @Getter(lazy=true) private final Class matchEntityClass = getFirstTypeParam(getClass()); - - @Override public void filter(ContainerRequestContext request, ContainerResponseContext response) throws IOException { - - final Type entityType = response.getEntityType(); - if (entityType == null) return; - - final Class responseClass; - final String responseClassName; - try { - responseClassName = entityType.toString().split(" ")[1]; - responseClass = forName(responseClassName); - } catch (Exception e) { - log.warn("filter: error with '" + entityType + "': " + e); - return; - } - - if (shouldFilter(request, response, responseClassName, responseClass)) { - filter(request, response, responseClassName, responseClass); - } - } - - protected boolean shouldFilter(ContainerRequestContext request, ContainerResponseContext response, String responseClassName, Class responseClass) { - return getMatchEntityClass().isAssignableFrom(responseClass); - } - - protected void filter(ContainerRequestContext request, ContainerResponseContext response, String responseClassName, Class responseClass) {} - -} \ No newline at end of file diff --git a/wizard-server/src/main/java/org/cobbzilla/wizard/filters/EntityTypeHeaderFilter.java b/wizard-server/src/main/java/org/cobbzilla/wizard/filters/EntityTypeHeaderFilter.java deleted file mode 100644 index 3d638f9..0000000 --- a/wizard-server/src/main/java/org/cobbzilla/wizard/filters/EntityTypeHeaderFilter.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.cobbzilla.wizard.filters; - -import lombok.extern.slf4j.Slf4j; -import org.cobbzilla.wizard.dao.SearchResults; -import org.cobbzilla.wizard.model.Identifiable; - -import javax.ws.rs.container.ContainerRequestContext; -import javax.ws.rs.container.ContainerResponseContext; -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.Map; - -import static org.cobbzilla.util.daemon.ZillaRuntime.empty; - -@Slf4j -public class EntityTypeHeaderFilter extends EntityFilter { - - protected String getTypeHeaderName() { return Identifiable.ENTITY_TYPE_HEADER_NAME; } - - @Override public void filter(ContainerRequestContext request, - ContainerResponseContext response, - String responseClassName, - Class responseClass) { - - final boolean isSearchResults = SearchResults.class.isAssignableFrom(responseClass); - final boolean isCollection = Collection.class.isAssignableFrom(responseClass); - final boolean isMap = Map.class.isAssignableFrom(responseClass); - final boolean isArray = responseClass.isArray(); - String elementClassName; - if (isSearchResults) { - final SearchResults searchResults = (SearchResults) response.getEntity(); - response.getHeaders().add(getTypeHeaderName(), - SearchResults.class.getName() + (searchResults.hasResults() ? "<" + getCollectionElementClass(searchResults.getResults()) + ">" : "")); - - } else if (isCollection) { - response.getHeaders().add(getTypeHeaderName(), getCollectionElementClass((Collection) response.getEntity())+"[]"); - - } else if (isArray) { - final Object[] a = (Object[]) response.getEntity(); - try { - elementClassName = empty(a) ? "" : a[0].getClass().getName(); - } catch (Exception e) { - elementClassName = ""; - } - response.getHeaders().add(getTypeHeaderName(), elementClassName + "[]"); - - } else if (isMap) { - response.getHeaders().add(getTypeHeaderName(), LinkedHashMap.class.getName()); - } else { - response.getHeaders().add(getTypeHeaderName(), responseClassName); - } - return; - } - - protected String getCollectionElementClass(Collection c) { - try { - return empty(c) ? "" : c.iterator().next().getClass().getName(); - } catch (Exception ignored) { - return ""; - } - } - -} \ No newline at end of file diff --git a/wizard-server/src/main/java/org/cobbzilla/wizard/filters/MultiEntityFilter.java b/wizard-server/src/main/java/org/cobbzilla/wizard/filters/MultiEntityFilter.java deleted file mode 100644 index f2cc1d2..0000000 --- a/wizard-server/src/main/java/org/cobbzilla/wizard/filters/MultiEntityFilter.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.cobbzilla.wizard.filters; - -import javax.ws.rs.container.ContainerRequestContext; -import javax.ws.rs.container.ContainerResponseContext; -import java.util.Collection; -import java.util.Iterator; - -import static org.cobbzilla.util.reflect.ReflectionUtil.arrayClass; - -public abstract class MultiEntityFilter extends EntityFilter { - - protected abstract A getAccount(ContainerRequestContext request); - protected abstract P getActiveProfile(ContainerRequestContext request, A account); - protected abstract T filterEntity(T thing, A account, P profile); - - @Override protected boolean shouldFilter(ContainerRequestContext request, ContainerResponseContext response, - String responseClassName, Class responseClass) { - return super.shouldFilter(request, response, responseClassName, responseClass) - || (responseClass.isArray() && arrayClass(getMatchEntityClass()).isAssignableFrom(responseClass) && ((Object[]) response.getEntity()).length > 0) - || (Collection.class.isAssignableFrom(responseClass) && firstElementIsAssignableFrom(response)); - } - - private boolean firstElementIsAssignableFrom(ContainerResponseContext response) { - final Iterator iter = ((Collection) response.getEntity()).iterator(); - return iter.hasNext() && getMatchEntityClass().isAssignableFrom(iter.next().getClass()); - } - - @Override protected void filter(ContainerRequestContext request, ContainerResponseContext response, String responseClassName, Class responseClass) { - final A account = getAccount(request); - final P profile = getActiveProfile(request, account); - if (disableFilteringFor(account, profile)) return; - filterByProfile(responseClass, response, account, profile); - } - - protected boolean disableFilteringFor(A account, P profile) { return false; } - - protected ContainerResponseContext filterByProfile(Class responseClass, ContainerResponseContext response, A account, P profile) { - final Object entity = response.getEntity(); - if (responseClass.isArray()) { - for (T thing : (T[]) entity) filterEntity(thing, account, profile); - - } else if (Collection.class.isAssignableFrom(responseClass)) { - for (T thing : ((Collection) entity)) filterEntity(thing, account, profile); - - } else { - filterEntity(((T) entity), account, profile); - } - return response; - } - -} diff --git a/wizard-server/src/main/java/org/cobbzilla/wizard/resources/ByteStreamingOutput.java b/wizard-server/src/main/java/org/cobbzilla/wizard/resources/ByteStreamingOutput.java deleted file mode 100644 index 9d9117a..0000000 --- a/wizard-server/src/main/java/org/cobbzilla/wizard/resources/ByteStreamingOutput.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.cobbzilla.wizard.resources; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import org.cobbzilla.util.io.StreamUtil; - -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.StreamingOutput; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -@AllArgsConstructor -public class ByteStreamingOutput implements StreamingOutput { - - @Getter private final byte[] data; - - @Override public void write(OutputStream out) throws IOException, WebApplicationException { - try (InputStream in = new ByteArrayInputStream(data)) { - StreamUtil.copyLarge(in, out); - } - } -} diff --git a/wizard-server/src/main/java/org/cobbzilla/wizard/resources/FileStreamingOutput.java b/wizard-server/src/main/java/org/cobbzilla/wizard/resources/FileStreamingOutput.java deleted file mode 100644 index 150bc15..0000000 --- a/wizard-server/src/main/java/org/cobbzilla/wizard/resources/FileStreamingOutput.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.cobbzilla.wizard.resources; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import org.cobbzilla.util.io.StreamUtil; - -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.StreamingOutput; -import java.io.*; - -@AllArgsConstructor -public class FileStreamingOutput implements StreamingOutput { - - @Getter private final File file; - - @Override public void write(OutputStream out) throws IOException, WebApplicationException { - try (InputStream in = new FileInputStream(file)) { - StreamUtil.copyLarge(in, out); - } - } -} diff --git a/wizard-server/src/main/java/org/cobbzilla/wizard/resources/FileUploadContext.java b/wizard-server/src/main/java/org/cobbzilla/wizard/resources/FileUploadContext.java deleted file mode 100644 index b044bb9..0000000 --- a/wizard-server/src/main/java/org/cobbzilla/wizard/resources/FileUploadContext.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.cobbzilla.wizard.resources; - -public interface FileUploadContext { -} diff --git a/wizard-server/src/main/java/org/cobbzilla/wizard/resources/FileUploadResource.java b/wizard-server/src/main/java/org/cobbzilla/wizard/resources/FileUploadResource.java deleted file mode 100644 index af1f1a8..0000000 --- a/wizard-server/src/main/java/org/cobbzilla/wizard/resources/FileUploadResource.java +++ /dev/null @@ -1,115 +0,0 @@ -package org.cobbzilla.wizard.resources; - -import org.cobbzilla.wizard.asset.AssetStorageService; -import org.cobbzilla.wizard.asset.AssetStream; -import org.cobbzilla.wizard.model.AssetStorageInfo; -import org.glassfish.jersey.media.multipart.FormDataContentDisposition; -import org.glassfish.jersey.media.multipart.FormDataParam; -import org.glassfish.jersey.server.ContainerRequest; - -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.Response; -import java.io.InputStream; -import java.util.Collection; -import java.util.Optional; -import java.util.regex.Pattern; - -import static javax.ws.rs.core.MediaType.APPLICATION_JSON; -import static javax.ws.rs.core.MediaType.MULTIPART_FORM_DATA; -import static org.cobbzilla.util.daemon.ZillaRuntime.die; -import static org.cobbzilla.util.daemon.ZillaRuntime.empty; -import static org.cobbzilla.util.http.HttpContentTypes.contentType; -import static org.cobbzilla.wizard.resources.ResourceUtil.*; - -public abstract class FileUploadResource { - - protected abstract boolean validateUpload(ContainerRequest context); - protected abstract boolean validateDownload(ContainerRequest context, String uuid); - protected abstract boolean validateDelete(ContainerRequest context, String uuid); - - /** - * Subclasses should override this method, or subclass a from a more specific class like PdfUploadResource - * @return Regular expression representing the allowed file extensions - */ - protected abstract Pattern getAllowedFileExtensions(); - - protected abstract AssetStorageService getStorage(); - - protected abstract FI createFileInfo(FormDataContentDisposition fileDetail); - protected abstract Collection findFileInfos(); - protected abstract FI findFileInfo(String uuid); - protected abstract void deleteFileInfo(FI fileInfo); - - @GET - @Consumes(APPLICATION_JSON) - @Produces(APPLICATION_JSON) - public Response findDocuments(@Context ContainerRequest context) { - if (!validateDownload(context, null)) return forbidden(); - return ok(findFileInfos()); - } - - @POST - @Consumes(MULTIPART_FORM_DATA) - @Produces(APPLICATION_JSON) - public Response uploadDocument(@Context ContainerRequest context, - @FormDataParam("file") InputStream fileStream, - @FormDataParam("file") FormDataContentDisposition fileDetail) { - - if (!validateUpload(context)) return forbidden(); - - final Optional error = validateFile(fileStream, fileDetail); - if (error.isPresent()) return invalid(error.get()); - - final FI fileInfo = createFileInfo(fileDetail); - getStorage().store(fileStream, fileDetail.getFileName(), fileInfo.getAsset()); - return ok(fileInfo); - } - - @GET @Path("/{uuid}") - @Consumes(APPLICATION_JSON) - @Produces("*/*") - public Response downloadDocument(@Context ContainerRequest context, - @PathParam("uuid") String uuid) { - - if (!validateDownload(context, uuid)) return forbidden(); - - final FI fileInfo = findFileInfo(uuid); - if (fileInfo == null) return notFound(uuid); - - final AssetStream assetStream = getStorage().load(fileInfo.getAsset()); - if (empty(assetStream)) return notFound(); - - return stream(contentType(assetStream.getFormatName()), assetStream.getStream()); - } - - @DELETE @Path("/{uuid}") - @Consumes(APPLICATION_JSON) - @Produces(APPLICATION_JSON) - public Response deleteDocument(@Context ContainerRequest context, - @PathParam("uuid") String uuid) { - - if (!validateDelete(context, uuid)) return forbidden(); - - final FI fileInfo = findFileInfo(uuid); - if (fileInfo == null) return notFound(uuid); - - if (getStorage().exists(fileInfo.getAsset())) { - if (!getStorage().delete(fileInfo.getAsset())) return die("deleteDocument: could not delete: " + fileInfo.getAsset()); - } - deleteFileInfo(fileInfo); - - return ok(fileInfo); - } - - private Optional validateFile(InputStream fileStream, FormDataContentDisposition fileDetail) { - if (fileStream == null) return Optional.of("err.fileStream.empty"); - if (fileDetail == null) return Optional.of("err.fileDetail.empty"); - if (empty(fileDetail.getFileName())) return Optional.of("err.fileName.empty"); - if (!getAllowedFileExtensions().matcher(fileDetail.getFileName()).matches()) { - return Optional.of("err.fileFormat.invalid"); - } - - return Optional.empty(); - } -} diff --git a/wizard-server/src/main/java/org/cobbzilla/wizard/resources/PdfUploadResource.java b/wizard-server/src/main/java/org/cobbzilla/wizard/resources/PdfUploadResource.java deleted file mode 100644 index f32d360..0000000 --- a/wizard-server/src/main/java/org/cobbzilla/wizard/resources/PdfUploadResource.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.cobbzilla.wizard.resources; - -import org.cobbzilla.wizard.model.AssetStorageInfo; - -import java.util.regex.Pattern; - -public abstract class PdfUploadResource extends FileUploadResource { - - @Override protected Pattern getAllowedFileExtensions() { return Pattern.compile(".*\\.pdf"); } - -} diff --git a/wizard-server/src/main/java/org/cobbzilla/wizard/resources/SendableCsv.java b/wizard-server/src/main/java/org/cobbzilla/wizard/resources/SendableCsv.java deleted file mode 100644 index 81c7244..0000000 --- a/wizard-server/src/main/java/org/cobbzilla/wizard/resources/SendableCsv.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.cobbzilla.wizard.resources; - -import com.github.jknack.handlebars.Handlebars; -import org.cobbzilla.util.collection.NameAndValue; -import org.cobbzilla.util.http.HttpContentTypes; -import org.cobbzilla.wizard.model.search.ResultPage; -import org.cobbzilla.wizard.model.search.SqlViewField; -import org.cobbzilla.wizard.util.CsvStreamingOutput; - -import java.util.Collection; -import java.util.List; - -public class SendableCsv extends SendableResource { - - public SendableCsv(String name, Collection rows, String[] fields) { - this(name, rows, fields, null, null); - } - - public SendableCsv(String name, Collection rows, String[] fields, String[] header) { - this(name, rows, fields, header, null); - } - - public SendableCsv(String name, Collection rows, String[] fields, String[] header, Handlebars handlebars) { - super(new CsvStreamingOutput(rows, fields, header, handlebars)); - setName(name); - } - - @Override public String getContentType() { return HttpContentTypes.TEXT_CSV; } - @Override public Boolean getForceDownload() { return true; } - - public static SendableCsv searchToCSV(ResultPage search, String name, List results, SqlViewField[] searchFields, Handlebars handlebars) { - final String[] fields; - final String[] header; - if (search.hasFieldMappings()) { - final NameAndValue[] fieldMappings = search.getFieldMappings(); - fields = new String[fieldMappings.length]; - header = new String[fieldMappings.length]; - for (int i=0; i> data = new ArrayList<>(); - final boolean defaultHeaders = empty(header); - final Set columns = defaultHeaders ? new HashSet<>() : null; - for (Object row : rows) { - final Map map = new HashMap<>(); - for (String field : fields) { - if (field.startsWith("'") && field.endsWith("'")) { - map.put(field, field.substring(1, field.length()-1)); - - } else if (handlebars != null && field.contains("[[") && field.contains("]]")) { - final Map ctx = toMap(row); - if (row instanceof HasRelatedEntities) ctx.putAll(((HasRelatedEntities) row).getRelated()); - map.put(field, HandlebarsUtil.apply(handlebars, field, ctx, '[', ']')); - - } else { - map.put(field, ReflectionUtil.get(row, field, null)); - } - } - data.add(map); - if (defaultHeaders) columns.addAll(map.keySet()); - } - - if (defaultHeaders) header = columns.toArray(new String[columns.size()]); - writer.writeNext(header); // header row - - for (Map row : data) { - final String[] line = new String[fields.length]; - for (int i = 0; i < line.length; i++) { - final String field = fields[i]; - final Object value = row.get(field); - line[i] = value == null ? "" : String.valueOf(value); - } - writer.writeNext(line, false); - } - } - -} diff --git a/wizard-server/src/main/java/org/cobbzilla/wizard/util/FileStreamingOutput.java b/wizard-server/src/main/java/org/cobbzilla/wizard/util/FileStreamingOutput.java deleted file mode 100644 index c82ee11..0000000 --- a/wizard-server/src/main/java/org/cobbzilla/wizard/util/FileStreamingOutput.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.cobbzilla.wizard.util; - -import lombok.AllArgsConstructor; -import org.cobbzilla.util.io.StreamUtil; - -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.StreamingOutput; -import java.io.*; - -@AllArgsConstructor -public class FileStreamingOutput implements StreamingOutput { - - private File cache; - - @Override - public void write(OutputStream out) throws IOException, WebApplicationException { - try (InputStream in = new FileInputStream(cache)) { - StreamUtil.copyLarge(in, out); - } - } -} diff --git a/wizard-server/src/main/java/org/cobbzilla/wizard/util/ProxyStreamingOutput.java b/wizard-server/src/main/java/org/cobbzilla/wizard/util/ProxyStreamingOutput.java deleted file mode 100644 index e455bca..0000000 --- a/wizard-server/src/main/java/org/cobbzilla/wizard/util/ProxyStreamingOutput.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.cobbzilla.wizard.util; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import org.apache.commons.io.IOUtils; -import org.apache.http.HttpResponse; -import org.apache.http.impl.client.CloseableHttpClient; - -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.StreamingOutput; -import java.io.IOException; -import java.io.OutputStream; - -@AllArgsConstructor -class ProxyStreamingOutput implements StreamingOutput { - - @Getter private final HttpResponse response; - @Getter private final CloseableHttpClient httpClient; - - @Override public void write(OutputStream output) throws IOException, WebApplicationException { - try { - IOUtils.copy(response.getEntity().getContent(), output); - } finally { - httpClient.close(); - } - } - -} diff --git a/wizard-server/src/main/java/org/cobbzilla/wizard/util/StreamStreamingOutput.java b/wizard-server/src/main/java/org/cobbzilla/wizard/util/StreamStreamingOutput.java deleted file mode 100644 index 34a44a3..0000000 --- a/wizard-server/src/main/java/org/cobbzilla/wizard/util/StreamStreamingOutput.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.cobbzilla.wizard.util; - -import lombok.AllArgsConstructor; - -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.StreamingOutput; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import static org.cobbzilla.util.io.StreamUtil.copyLarge; - -@AllArgsConstructor -public class StreamStreamingOutput implements StreamingOutput { - - private InputStream in; - - @Override public void write(OutputStream out) throws IOException, WebApplicationException { copyLarge(in, out); } - -}