@brunofuster

www.wesaveapp.com

Archive for the ‘java’ Category

uploading an image from iphone to appengine blobstore using vraptor

with 8 comments

Its quite simple to do this. I will represent the back-end using vraptor, a really great mvc web framework.

Well, at first, you need to generate the upload URI, provided by GAE’s SDK. When you’re working with web forms, you can just call the BlobstoreService to create the Upload URI directly from your JSP, but this is not the case.

We will provide then a resource that will return an URI for the upload.


@Resource
@Path("/image")
public class ImageController {

    private final BlobstoreSevice blobstoreSevice = BlobstoreServiceFactory.getBlobstoreService();
    private final Result result;

    public ImageController(Result result) {
        this.result = result;
    }

    @Path("/createUploadURI")
    public void uploadURI() {
        
        String uploadURI = blobstoreService.createUploadUrl("/image/upload");
        result.use(http()).body(uploadURI);
    }

}

That’s enough to return the upload URI into the response body (we wont use json or xml at this time to simplify the post).
Just for the record, there’s an issue when running this at development server. Blobstore won’t return the URI with its host, although it will return the absolute URI when at production environment.

Lets consume this resource from iphone now using asihttp.

#import "ASIHTTPRequest.h"
//...

-(void) getUploadURI {

	NSURL *uri = [NSURL URLWithString:@"http://yourserver.appspot.com/image/createUploadURI"]];
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:uri];
	[request setDelegate:self];
	[request startAsynchronous];
}

-(void) requestFinished:(ASIHTTPRequest *)request {

	NSString *uri = [request responseData];
}

-(void) requestFailed:(ASIHTTPRequest *)request {
	
	NSError *error = [request error];
	NSLog(@"error %@", error);
}

Now we have the URI to upload an image. Lets create a new objective-c class to handle the upload using asihttp form data (notice that we will also track the upload progress).

#import <Foundation/Foundation.h>
#import "ASIFormDataRequest.h"

@interface ImageUpload : NSObject {

	ASIFormDataRequest *formData;
	float progress;
}

@property (nonatomic, retain) ASIFormDataRequest *formData;
@property (nonatomic, assign) float progress;

-(id) initWithImage:(UIImage*)img uri:(NSString*)uri;
-(void) startUpload;

@end

And it’s implementation:

#import "ImageUpload.h"

@implementation ImageUpload

@synthesize formData, progress;

-(id) initWithImage:(UIImage*)img uri:(NSString*)uri {
	
	NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(img)];

	self.formData = [[ASIFormDataRequest requestWithURL:[NSURL URLWithString:uri]] retain];	
	[self.formData setData:imageData withFileName:@"defaultImage.png" andContentType:@"image/png" forKey:@"defaultImage"];
	[self.formData setDelegate:self];
	[self.formData setUploadProgressDelegate:self];
	
	return self;
}

-(void) startUpload {

	[self.formData startAsynchronous];
}

#pragma mark Upload Progress Tracking

- (void)request:(ASIHTTPRequest *)theRequest didSendBytes:(long long)newLength {
	
	if ([theRequest totalBytesSent] > 0) {
		float progressAmount = (float) ([theRequest totalBytesSent]/[theRequest postLength]);
		self.progress = progressAmount;
	}
	
}

-(void) requestFinished:(ASIHTTPRequest *)request {
	NSLog(@"upload finished");
}

-(void) requestFailed:(ASIHTTPRequest *)request {
	NSError *error = [request error];
	NSLog(@"error %@", error);
}

- (void) dealloc
{
	[self.formData release];
	[super dealloc];
}
@end

Let’s change the requestFinished: method for /image/getUploadURI to start the upload after its response is done.

#import "ImageUpload.h"
//...
-(void) requestFinished:(ASIHTTPRequest *)request {

	ImageUpload *imageUpload = [[ImageUpload alloc] initWithImage:self.imageView.image uri:[request responseData]];
	[imageUpload startUpload];
}

If you want to track the progress at this view, you can create your own delegate like [imageUpload setUploadTrackingProgress:self] or expose the asihttp method setUploadProgressDelegate:.

At last we will create the resource that Blobstore will call on your server after the upload has been completed. You can now use the Images Service to get an URI for this image and store it.

@Path("/upload")
public void upload() {
	Map<String, BlobKey> blobs = blobstoreService.getUploadedBlobs(request);
	BlobKey blob = blobs.get("defaultImage");
		
	ImagesService imagesService = ImagesServiceFactory.getImagesService();
	String imageUrl = imagesService.getServingUrl(blob);

	/* datastore.put(imageurl) */
	result.use(Results.http()).body(imageUrl);
}

We just need to inject the current HttpServletRequest for the BlobstoreService like this:

@Resource
@Path("/image")
public class ImageController {

    private final BlobstoreSevice blobstoreSevice = BlobstoreServiceFactory.getBlobstoreService();
    private final HttpServletRequest request;
    private final Result result;

    public ImageController(Result result, HttpServletRequest request) {
        this.result = result;
        this.request = request;
    }
...

References:
vraptor
asihttp
Blobstore Service
Images Service
http://ikaisays.com/2010/09/08/gwt-blobstore-the-new…

Advertisements

Written by brunofuster

March 11, 2011 at 3:06 pm

javageomodel with objectify

with 3 comments

GeoModel is an useful project (originally in python) ported to java which aims to make your life easier when you want to search near by coordinates in maps using bigtable as storage.

The only thing is that javageomodel is too coupled with JPA/JDO and I want to use Objectify. Well, there’s too much code that can be refactored, but this simple change satisfied my needs:

proximityFetch #old
List<T> proximityFetch(Point center, int maxResults, double maxDistance, Class<T> entityClass, GeocellQuery baseQuery, PersistenceManager pm)

proximityFetch #new
List<T> proximityFetch(Point center, int maxResults, double maxDistance, LocationCapableRepositorySearch<T> repositorySearch)

If you want to search over your LocationCapable entities, you should give a LocationCapableRepositorySearch<T> for javageomodel (ofy sample):

public class OfyEntityLocationCapableRepositorySearchImpl implements
		LocationCapableRepositorySearch<Entity> {

	private Objectify ofy;

	public EntityLocationCapableRepositorySearchImpl(Objectify ofy) {
		this.ofy = ofy;
	}

	@Override
	public List<Entity> search(List<String> geocells) {
		return ofy.query(Entity.class)
				.filter("coordinates.geocells in ", geocells).list();
	}

}

You might be looking for GeocellQuery. You could just change your LocationCapableRepositorySearch constructor waiting for a query and add some new filters to your search.

Now an Objectify proximity search looks like:

LocationCapableRepositorySearch<Entity> ofySearch = 
                    new OfyEntityLocationCapableRepositorySearchImpl(ofy);

List<Entity> entities = GeocellManager.proximityFetch(center, 20, 1000, ofySearch);

and I’ve created a JPALocationCapableRepositorySearchImpl for JPA searches:

LocationCapableRepositorySearch<Entity> jpaSearch = 
                    new JPALocationCapableRepositorySearchImpl<Entity>(baseQuery, pm, Entity.class);

List<Entity> entities = GeocellManager.proximityFetch(center, 40, 1000, jpaSearch);

You can find the new source at http://github.com/bfuster/javageomodel

Written by brunofuster

September 21, 2010 at 10:47 am

Posted in gae, geomodel, java, ofy

transfer object pattern & annotations (pt_BR)

leave a comment »

Como o título já diz, este post demonstra algumas implementações para facilitar a cópia de objetos semelhantes.

Para menor acoplamento entre a camada de visualização (Adobe Flex) e o banco de dados, utilizamos DTOs que são (quase) espelhos de Entidades. Ganhamos flexibilidade para criar objetos mais produtivos para o front-end, o que torna(va) o back-end improdutivo ao tentar espelhar entidades.

A cópia de objetos pode ser feita com apenas uma linha de código (6) e mais algumas anotações.


Opniões e colaboração são bem-vindos.

http://github.com/bfuster/dtomanager
Mirror DSL

Core J2EE Patterns, Transfer Object
Factory method pattern

Written by brunofuster

July 28, 2010 at 4:34 pm

Posted in flex, java

Spring & JDBC Template

leave a comment »

The Spring Framework makes JDBC development easier by using IoC to eliminate low-level code. If you don’t use an ORM framework, this API is highly recommended. Now let’s see a comparison sample between pure JDBC and JDBC with Spring JdbcTemplate class:

Example 1: Creating a list of objects with pure JDBC

public List<User> getUsers() {

    PreparedStatement ps = connection.prepareStatement("Select name, email from t_users where status = ?");
    ps.setInt(1, new Integer(1));

    ResultSet rs = ps.executeQuery();

    List users = new ArrayList();

    while (rs.next()) {
        User user = new User();
        user.setName(rs.getString("name"));
        user.setEmail(rs.getString("email"));
        users.add(user);
    }

    return users;
}

Besides, you have to control connections opening and closing.

Example 2: Creating a list of objects with Spring and JDBC:

We have to use the JdbcTemplate class that can be instantied by injecting your datasource (new JdbcTemplate(dataSource)). Then you should create a new class that implements the RowMapper interface for the objects creation. After that, you can get the list of objects with just one line of code:

public List<User> getUsers() {
    return (List) jdbcTemplate.query("Select name, email from t_users where status = ?", new Object[] { new Integer(1) }, new UserRowMapper());
}

RowMapper sample:

public class UserRowMapper implements RowMapper {

    @Override
    public Object mapRow(ResultSet rs, int numRow) throws SQLException {

        User user = new User();
        user.setName(rs.getString("name"));
        user.setEmail(rs.getString("email"));
        return user;
    }
}

Complete reference: http://static.springframework.org/spring/docs/2.0.x/reference/jdbc.html

Written by brunofuster

March 12, 2009 at 12:14 pm

Posted in java, jdbc, spring