Skip to content

Commit

Permalink
Hooking up a simple image uploader service.
Browse files Browse the repository at this point in the history
  • Loading branch information
neosavvy committed Apr 25, 2012
1 parent bfac010 commit 33077e4
Show file tree
Hide file tree
Showing 16 changed files with 729 additions and 51 deletions.
1 change: 1 addition & 0 deletions commons-user-client/commons-user-client.iml
Expand Up @@ -5,6 +5,7 @@
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
Expand Down
55 changes: 55 additions & 0 deletions commons-user-client/src/main/resources/index.html
@@ -0,0 +1,55 @@
<html>
<body>

<form accept-charset="UTF-8"
action="http://local.commons-user.com:8080/image/file/images/3"
class="html-form" enctype="multipart/form-data" id="base64_decoder"
method="post"><div style="margin:0;padding:0;display:inline"><input
name="utf8" type="hidden" value="">

<div class="html-form-header">
<p>
Please enter data to decode.
</p>
<p class="mandatory-message">
<span class="mandatory-sign">*</span> denotes mandatory field.
</p>

</div>


<fieldset>
<div class="html-form-section">
<h2>Data information</h2>
<p>Please enter data to text area or select file with data.</p>
</div>

<ul>
<li>
<label for="base64_decoder_base64dump">Base64 data to
decode<span class="mandatory-sign">*</span></label>
<textarea cols="40" id="base64_decoder_base64dump"
name="base64_decoder[base64dump]" rows="20"></textarea>
<input id="base64_decoder_file" name="base64_decoder[file]" type="file">
<div class="form-hint">Enter data or select file to decode</div>

</li>
<li>
<input name="base64_decoder[save_to_file]" type="hidden"
value="0"><input id="base64_decoder_save_to_file"
name="base64_decoder[save_to_file]" type="checkbox" value="1">
<label for="base64_decoder_save_to_file">Save result to file</label>
<div class="form-hint">Save result to file rather than output
to browser</div>

</li>
</ul>
</fieldset>
<fieldset>

<input name="commit" type="submit" value="Decode">
</fieldset>
</form>

</body>
</html>
14 changes: 13 additions & 1 deletion commons-user-service/commons-user-service.iml
Expand Up @@ -15,7 +15,7 @@
<orderEntry type="library" name="Maven: com.yammer.dropwizard:dropwizard-core:0.3.1" level="project" />
<orderEntry type="library" name="Maven: com.sun.jersey:jersey-core:1.12" level="project" />
<orderEntry type="library" name="Maven: com.sun.jersey:jersey-server:1.12" level="project" />
<orderEntry type="library" name="Maven: asm:asm:3.1" level="project" />
<orderEntry type="library" name="Maven: asm:asm:3.2" level="project" />
<orderEntry type="library" name="Maven: com.sun.jersey:jersey-servlet:1.12" level="project" />
<orderEntry type="library" name="Maven: com.yammer.metrics:metrics-core:2.1.1" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.6.4" level="project" />
Expand Down Expand Up @@ -44,6 +44,18 @@
<orderEntry type="library" name="Maven: org.hibernate:hibernate-validator:4.2.0.Final" level="project" />
<orderEntry type="library" name="Maven: javax.validation:validation-api:1.0.0.GA" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.10" level="project" />
<orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.2.1" level="project" />
<orderEntry type="library" name="Maven: org.clapper:util:2.5.1" level="project" />
<orderEntry type="library" name="Maven: asm:asm-analysis:3.2" level="project" />
<orderEntry type="library" name="Maven: asm:asm-tree:3.2" level="project" />
<orderEntry type="library" name="Maven: asm:asm-commons:3.2" level="project" />
<orderEntry type="library" name="Maven: asm:asm-util:3.2" level="project" />
<orderEntry type="library" name="Maven: javax.mail:mail:1.4.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:activation:1.1.1" level="project" />
<orderEntry type="library" name="Maven: commons-logging:commons-logging:1.1" level="project" />
<orderEntry type="library" name="Maven: logkit:logkit:1.0.1" level="project" />
<orderEntry type="library" name="Maven: avalon-framework:avalon-framework:4.1.3" level="project" />
<orderEntry type="library" name="Maven: javax.servlet:servlet-api:2.3" level="project" />
</component>
</module>

48 changes: 0 additions & 48 deletions commons-user-service/hbo-image-service.iml

This file was deleted.

12 changes: 11 additions & 1 deletion commons-user-service/pom.xml
Expand Up @@ -45,7 +45,7 @@
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.neosavvy.HelloWorldService</mainClass>
<mainClass>com.neosavvy.ImageService</mainClass>
</transformer>
</transformers>
</configuration>
Expand All @@ -67,6 +67,16 @@
<artifactId>dropwizard-core</artifactId>
<version>0.3.1</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.clapper</groupId>
<artifactId>util</artifactId>
<version>2.5.1</version>
</dependency>

</dependencies>

Expand Down
@@ -0,0 +1,13 @@
package com.neosavvy;

import com.yammer.dropwizard.config.Configuration;
import org.codehaus.jackson.annotate.JsonProperty;
import org.hibernate.validator.constraints.NotEmpty;

public class ImageConfiguration extends Configuration {

@NotEmpty
@JsonProperty
private String imageDirectory = "things";

}
140 changes: 140 additions & 0 deletions commons-user-service/src/main/java/com/neosavvy/ImageResource.java
@@ -0,0 +1,140 @@
package com.neosavvy;

import com.neosavvy.model.ResourceNotFoundException;
import com.neosavvy.model.StorageBucket;
import com.neosavvy.model.StorageBucketType;
import com.neosavvy.utils.FileUtils;
import com.neosavvy.utils.HttpUtils;
import com.neosavvy.utils.StringUtils;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.util.Streams;

import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
* Created by IntelliJ IDEA.
* User: waparrish
* Date: 4/24/12
* Time: 12:53 PM
* To change this template use File | Settings | File Templates.
*/
@Path("/image")
@Produces(MediaType.APPLICATION_JSON)
public class ImageResource {

private List<StorageBucket> buckets;

public List<StorageBucket> getBuckets() {

if( buckets == null )
{
buckets = new ArrayList<StorageBucket>();
buckets.add(new StorageBucket(
"images"
, StorageBucketType.STANDARD
, new File("/tmp/images/")
));
buckets.add(new StorageBucket(
"temp"
, StorageBucketType.TEMPORARY
, new File("/tmp/tempFiles")
));
}

return buckets;
}

@POST
@Path(value="/file/{bucket:.*?}/{key:.*}")
@Encoded
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_XML})
public void uploadFile(@Context Request request, @PathParam("bucket")String bucket, @PathParam("key")String key) throws Exception
{

String owner = null;
String fileNameOverride = null;
FileItemIterator iter = new ServletFileUpload().getItemIterator(HttpUtils.getHttpRequest());

while (iter.hasNext()) {
FileItemStream item = iter.next();
if (item.isFormField() && item.getFieldName().equals("owner")) {
owner = Streams.asString(item.openStream());
}
else if (item.isFormField() && item.getFieldName().equals("fileNameOverride")) {
fileNameOverride = Streams.asString(item.openStream());
}
else if (!item.isFormField()){
saveFile(bucket, key, (!StringUtils.isEmpty(fileNameOverride) ? fileNameOverride : item.getName()),
parseContentType(item.getContentType()), item.openStream(), owner);
}
}

}


public void saveFile(String bucket, String key, String fileName, String contentType, InputStream data, String owner)
throws IOException, ResourceNotFoundException {

File bucketDir = lookupBucketDirectory(bucket);


File parentDir = bucketDir;
File file = new File(parentDir, key);

if (!parentDir.exists()) {
parentDir.mkdirs();
}

FileUtils.writeFile(data, file);
}

private File lookupBucketDirectory(String bucketName) throws ResourceNotFoundException {
StorageBucket bucket = getBucket(bucketName);

if (bucket == null) {
throw new ResourceNotFoundException("The bucket " + bucketName + " is not a known bucket.");
}

if (!bucket.getDirectory().exists()) {
throw new ResourceNotFoundException("The directory for bucket " + bucketName + " does not exist");
}

return bucket.getDirectory();
}

public StorageBucket getBucket(String name) {
for (StorageBucket bucket : getBuckets()) {
if (bucket.getName().equals(name)) {
return bucket;
}
}
return null;
}

private String parseContentType(String contentType) {
if (!StringUtils.isEmpty(contentType)) {
int delimiter = contentType.indexOf(';');

if (delimiter != -1) {
return contentType.substring(0, delimiter);
}

}

return contentType;
}


}
31 changes: 31 additions & 0 deletions commons-user-service/src/main/java/com/neosavvy/ImageService.java
@@ -0,0 +1,31 @@
package com.neosavvy;

import com.neosavvy.utils.HttpServletRequestFilter;
import com.yammer.dropwizard.Service;
import com.yammer.dropwizard.config.Environment;

/**
* Created by IntelliJ IDEA.
* User: waparrish
* Date: 4/20/12
* Time: 2:38 PM
* To change this template use File | Settings | File Templates.
*/
public class ImageService extends Service<ImageConfiguration> {

public static void main(String[] args) throws Exception
{
new ImageService().run(args);
}

private ImageService() {
super("image");
}

@Override
protected void initialize(ImageConfiguration configuration, Environment environment) throws Exception {
environment.addResource(new ImageResource());

environment.addFilter(new HttpServletRequestFilter(), "/*");
}
}
@@ -0,0 +1,27 @@
package com.neosavvy.model;

/**
* This class is a derivative work of Fineline via Tommy Odom.
* The code herein cannot be distributed without first establishing prior written consent
* from tommy.odom@gmail.com
*/
public class ResourceNotFoundException extends Exception
{
private static final long serialVersionUID = 1L;

public ResourceNotFoundException() {
}

public ResourceNotFoundException(String message) {
super(message);
}

public ResourceNotFoundException(Throwable cause) {
super(cause);
}

public ResourceNotFoundException(String message, Throwable cause) {
super(message, cause);
}

}

0 comments on commit 33077e4

Please sign in to comment.