Commits

Juan Carlos Picado Herrera  committed 7b9255b Merge

Merge branch 'juanpicado' into development

  • Participants
  • Parent commits 200d96e, b7170cd

Comments (0)

Files changed (32)

File encuestame-business/src/main/java/org/encuestame/business/service/PictureService.java

 package org.encuestame.business.service;
 
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.encuestame.business.service.imp.IPictureService;
 
 /**
  */
 public class PictureService extends AbstractBaseService implements IPictureService{
 
+    private Log log = LogFactory.getLog(this.getClass());
+
     /**
      * Picure Path.
      */
      * @param username
      * @param pictureType
      * @return
+     * @throws IOException
      */
     public byte[] getProfilePicture(
             final String id,
             final String username,
-            final PictureType pictureType){
+            final PictureType pictureType) throws IOException{
         final String url = getAccountUserPicturePath(username);
+        log.debug("getProfileURl "+url);
         final File file = new File(url + "3261353607_3bf3a23053_o.jpg");
+        InputStream is = new FileInputStream(file);
+        // Get the size of the file
+        long length = file.length();
+        if (length > Integer.MAX_VALUE) {
+            // File is too large
+        }
+        // Create the byte array to hold the data
+        byte[] bytes = new byte[(int)length];
+     // Read in the bytes
+        int offset = 0;
+        int numRead = 0;
+        while (offset < bytes.length
+               && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
+            offset += numRead;
+        }
+
+        // Ensure all the bytes have been read in
+        if (offset < bytes.length) {
+            throw new IOException("Could not completely read file "+file.getName());
+        }
 
-        return null;
+        // Close the input stream and return bytes
+        is.close();
+        log.debug("getProfileURl "+bytes);
+        return bytes;
 
     }
 

File encuestame-business/src/main/java/org/encuestame/business/service/imp/IPictureService.java

  */
 package org.encuestame.business.service.imp;
 
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
 import org.encuestame.business.service.PictureService.PictureType;
 
 /**
      * @param username
      * @param pictureType
      * @return
+     * @throws FileNotFoundException
+     * @throws IOException
      */
     byte[] getProfilePicture(
             final String id,
             final String username,
-            final PictureType pictureType);
+            final PictureType pictureType) throws FileNotFoundException, IOException;
 }

File encuestame-business/src/main/java/org/encuestame/business/service/package-info.java

 /**
- * Contains the Service Classes.
+ * Contains the Service Providers.
  *
  */
 package org.encuestame.business.service;

File encuestame-core/src/main/java/org/encuestame/core/image/ImageThumbnailGeneratorImpl.java

+package org.encuestame.core.image;
+
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.RenderingHints;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.imageio.ImageIO;
+import javax.swing.ImageIcon;
+
+import org.apache.log4j.Logger;
+
+
+/**
+ * Generate thumbnails for images.
+ * @author Picado, Juan juanATencuestame.org
+ * @since Jan 22, 2011 7:48:24 PM
+ * @version $Id:$
+ */
+public class ImageThumbnailGeneratorImpl implements ThumbnailGenerator {
+
+    private final static Logger log = Logger.getLogger(ImageThumbnailGeneratorImpl.class);
+
+    /**
+     *
+     */
+    public Object createThumbnail(InputStream inputStream, File fileOut,
+                  int largestDimension, Object hint) throws IOException {
+
+        // What's the base image that we are starting with?  If there's a hint, that's the scaled image
+        // from the last time around, use that... (since we know we always iterate downwards in scale)
+        Image imageIn;
+        if (hint instanceof Image) {
+            imageIn = (Image) hint;
+            log.info("createThumbnail(" + fileOut + ") reusing prior result image...");
+        }
+        else {
+            log.info("createThumbnail(" + fileOut + ") reading image from stream " + inputStream);
+            imageIn = ImageIO.read(inputStream);
+        }
+
+        if (imageIn == null) {
+            log.warn("Could not read image file: " + inputStream);
+            return hint;
+        }
+
+        BufferedImage imageOut = createThumbnailImage(imageIn, fileOut, largestDimension);
+
+        // Return this image now as the hint for the next scaling iteration
+        if (imageOut != null)
+            hint = imageOut;
+
+        return hint;
+    }
+
+
+    /**
+     * Create a thumbnail image and save it to disk.
+     *
+     * This algorithm is based on:
+     *      http://www.philreeve.com/java_high_quality_thumbnails.php
+     *
+     * @param imageIn           The image you want to scale.
+     * @param fileOut           The output file.
+     * @param largestDimension  The largest dimension, so that neither the width nor height
+     *                          will exceed this value.
+     *
+     * @return the image that was created, null if imageIn or fileOut is null.
+     * @throws java.io.IOException if something goes wrong when saving as jpeg
+     */
+    public BufferedImage createThumbnailImage(Image imageIn, File fileOut, int largestDimension) throws IOException {
+        if ((imageIn == null) || (fileOut == null)) {
+            return null;
+        }
+        //it seems to not return the right size until the methods get called for the first time
+        imageIn.getWidth(null);
+        imageIn.getHeight(null);
+
+        // Find biggest dimension
+        int     nImageWidth = imageIn.getWidth(null);
+        int     nImageHeight = imageIn.getHeight(null);
+        int     nImageLargestDim = Math.max(nImageWidth, nImageHeight);
+        double  scale = (double) largestDimension / (double) nImageLargestDim;
+        int     sizeDifference = nImageLargestDim - largestDimension;
+
+        //create an image buffer to draw to
+        BufferedImage imageOut = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); // 8-bit RGB
+        Graphics2D g2d;
+        AffineTransform tx;
+
+        // Use a few steps if the sizes are drastically different, and only scale
+        // if the desired size is smaller than the original.
+        int numSteps = 0;
+        if (scale < 1.0d) {
+            // Make sure we have at least 1 step
+            numSteps = Math.max(1, (sizeDifference / 100));
+        }
+
+        if (numSteps > 0) {
+            int stepSize = sizeDifference / numSteps;
+            int stepWeight = stepSize / 2;
+            int heavierStepSize = stepSize + stepWeight;
+            int lighterStepSize = stepSize - stepWeight;
+            int currentStepSize, centerStep;
+            double scaledW = imageIn.getWidth(null);
+            double scaledH = imageIn.getHeight(null);
+
+            if ((numSteps % 2) == 1) //if there's an odd number of steps
+                centerStep = (int) Math.ceil((double) numSteps / 2d); //find the center step
+            else
+                centerStep = -1; //set it to -1 so it's ignored later
+
+            Integer intermediateSize;
+            Integer previousIntermediateSize = nImageLargestDim;
+
+            for (Integer i = 0; i < numSteps; i++) {
+                if (i + 1 != centerStep) {
+                    //if this isn't the center step
+
+                    if (i == numSteps - 1) {
+                        //if this is the last step
+                        //fix the stepsize to account for decimal place errors previously
+                        currentStepSize = previousIntermediateSize - largestDimension;
+                    }
+                    else {
+                        if (numSteps - i > numSteps / 2) //if we're in the first half of the reductions
+                            currentStepSize = heavierStepSize;
+                        else
+                            currentStepSize = lighterStepSize;
+                    }
+                }
+                else {
+                    //center step, use natural step size
+                    currentStepSize = stepSize;
+                }
+
+                intermediateSize = previousIntermediateSize - currentStepSize;
+                scale = intermediateSize / (double) previousIntermediateSize;
+                scaledW = Math.max((int)(scaledW * scale), 1);
+                scaledH = Math.max((int)(scaledH * scale), 1);
+
+                log.info("step " + i + ": scaling to " + scaledW + " x " + scaledH);
+                imageOut = new BufferedImage((int) scaledW, (int) scaledH, BufferedImage.TYPE_INT_RGB); // 8 bit RGB
+                g2d = imageOut.createGraphics();
+                g2d.setBackground(Color.WHITE);
+                g2d.clearRect(0, 0, imageOut.getWidth(), imageOut .getHeight());
+                g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
+                tx = new AffineTransform();
+                tx.scale(scale, scale);
+                g2d.drawImage(imageIn, tx, null);
+                g2d.dispose();
+                imageIn = new ImageIcon(imageOut).getImage();
+                previousIntermediateSize = intermediateSize;
+            }
+        }
+        else {
+            // This enforces a rule that we always have an 8-bit image with white background for the thumbnail.  Plus, for large
+            // images, this makes subsequent downscaling really fast because we are working on a large 8-bit image
+            // instead of a large 12 or 24 bit image, so the downstream effect is very noticable.
+            imageOut = new BufferedImage(imageIn.getWidth(null), imageIn.getHeight(null), BufferedImage.TYPE_INT_RGB);
+            g2d = imageOut.createGraphics();
+            g2d.setBackground(Color.WHITE);
+            g2d.clearRect(0, 0, imageOut.getWidth(), imageOut.getHeight());
+            tx = new AffineTransform();
+            tx.setToIdentity(); //use identity matrix so image is copied exactly
+            g2d.drawImage(imageIn, tx, null);
+            g2d.dispose();
+        }
+        //saveImageAsJPEG(imageOut, fileOut);
+        ImageIO.write(imageOut, "jpg", fileOut);
+        return imageOut;
+    }
+
+}

File encuestame-core/src/main/java/org/encuestame/core/image/ThumbnailGenerator.java

+package org.encuestame.core.image;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.IOException;
+
+
+/**
+ * Interface implemented by all thumbnail generators.
+ * <p>The thumbnail generation process is always performed in order with the largest thumbnails first.
+ * Therefore it may be very handy for the generator to create smaller thumbnails using the results from
+ * the prior iteration instead of always using the full-sized image as the source.  To accomplish this,
+ * the generator can return a "hint" object that it can use in subsequent iterations, containing whatever
+ * helpers it might want (such as the prior image already loaded in memory, etc).
+ * Description Class.
+ * @author Picado, Juan juanATencuestame.org
+ * @since Jan 22, 2011 7:47:55 PM
+ * @version $Id:$
+ */
+public interface ThumbnailGenerator {
+
+    /**
+     * Create the thumbnail.  The thumbnail should always save as a JPEG file.
+     *
+     * @param inputStream       The source data.
+     * @param fileOut           The output file.
+     * @param largestDimension  The max width and height.  The generator should size the thumbnail so
+     *                          that the width and height both stay within this limit.
+     * @param hint              Optional hint that was returned from the prior thumbnail generation
+     *                          on this same file, null if none was returned or if this is the first
+     *                          thumbnail in this context.
+     *
+     * @return an optional hint object that will be passed to subsequent thumbnail generation calls
+     *         for this same source data.  Return null if you don't use hints, otherwise return some
+     *         object which allows you to communicate extra information to the next round, such as
+     *         the scaled image already loaded.
+     * @throws java.io.IOException if something goes wrong handling the io
+     */
+    Object createThumbnail(final InputStream inputStream,
+            final File fileOut,
+            int largestDimension,
+            final Object hint) throws IOException;
+
+}

File encuestame-core/src/main/java/org/encuestame/core/image/ThumbnailGeneratorEngine.java

+package org.encuestame.core.image;
+
+import java.io.InputStream;
+
+/**
+ * An engine in charge of generating thumbnails for files.
+ * @author Picado, Juan juanATencuestame.org
+ * @since Jan 22, 2011 7:51:44 PM
+ * @version $Id:$
+ */
+public interface ThumbnailGeneratorEngine {
+
+    /**
+     * @param fileNamePrefix
+     *            the prefix for the generated thumbnails
+     * @param inputStream
+     *            the stream to generate thumbnails for
+     * @param contentType
+     *            the content type of this input stream for example image/jpeg
+     */
+    void generateThumbnails(
+            final String fileNamePrefix,
+            final InputStream inputStream,
+            final String contentType,
+            final String thumbnailsLocation);
+}

File encuestame-core/src/main/java/org/encuestame/core/image/ThumbnailGeneratorEngineImpl.java

+package org.encuestame.core.image;
+
+import org.apache.log4j.Logger;
+
+import org.encuestame.core.image.ThumbnailGenerator;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Thumbnail Generator Engine.
+ * @author Picado, Juan juanATencuestame.org
+ * @since Jan 22, 2011 7:44:21 PM
+ * @version $Id:$
+ */
+public class ThumbnailGeneratorEngineImpl implements ThumbnailGeneratorEngine {
+
+    private final static Logger log = Logger
+            .getLogger(ThumbnailGeneratorEngineImpl.class);
+
+    private String generatedExtension;
+
+    /**
+     * @param generatedExtension
+     *            The extension for the generated thumbnails
+     */
+    public void setGeneratedExtension(String generatedExtension) {
+        this.generatedExtension = generatedExtension;
+    }
+
+    public String getGeneratedExtension() {
+        return generatedExtension;
+    }
+
+    private Map<String, ThumbnailGenerator> thumbnailGenerators;
+
+    /**
+     * @param thumbnailGenerators
+     *            The thumbnail generators known by this engine mapped to a
+     *            content type
+     */
+    public void setThumbnailGenerators(
+            Map<String, ThumbnailGenerator> thumbnailGenerators) {
+        this.thumbnailGenerators = thumbnailGenerators;
+    }
+
+    private List<Integer> supportedSizes;
+
+    /**
+     * @param supportedSizes
+     *            The suported sizes for the batch of generated thumbs
+     */
+    public void setSupportedSizes(List<Integer> supportedSizes) {
+        this.supportedSizes = supportedSizes;
+    }
+
+    private ThumbnailGenerator defaultThumbnailGenerator;
+
+    /**
+     * @param defaultThumbnailGenerator
+     *            the default thumbnail generator to be used for unregistered
+     *            mime types
+     */
+    public void setDefaultThumbnailGenerator(
+            ThumbnailGenerator defaultThumbnailGenerator) {
+        this.defaultThumbnailGenerator = defaultThumbnailGenerator;
+    }
+
+    /**
+     * @param fileNamePrefix
+     *            the prefix for the generated thumbnails
+     * @param inputStream
+     *            the stream to generate thumbnails for
+     * @param contentType
+     *            the content type of this input stream for example image/jpeg
+     */
+    public void generateThumbnails(final String fileNamePrefix,
+            final InputStream inputStream, final String contentType,
+            final String thumbnailsLocation) {
+        ThumbnailGenerator thumbnailGenerator = thumbnailGenerators.get(contentType);
+        thumbnailGenerator = thumbnailGenerator != null ? thumbnailGenerator
+                : defaultThumbnailGenerator;
+        if (thumbnailGenerator != null) {
+            Object hint = null;
+            for (int dimension : supportedSizes) {
+                File fileOut = new File(thumbnailsLocation, fileNamePrefix
+                        + "_" + dimension + generatedExtension);
+                try {
+                    hint = thumbnailGenerator.createThumbnail(inputStream,
+                            fileOut, dimension, hint);
+                    log.debug("Generated thumbnail for: " + inputStream
+                            + " in " + fileOut + " for type " + contentType);
+                } catch (Exception e) {
+                    log.error("Error generating thumbnail for: " + inputStream
+                            + " in " + fileOut + " for type " + contentType, e);
+                }
+
+            }
+        } else {
+            log.warn("Thumbnail generator not found for content type: "
+                    + contentType + " and no default generator was provided");
+        }
+    }
+}

File encuestame-core/src/main/java/org/encuestame/core/image/package-info.java

+/**
+ * Contain class to create thumbnails.
+ * Taked from http://raulraja.com/
+ */
+package org.encuestame.core.image;

File encuestame-mvc/src/main/java/org/encuestame/mvc/controller/FileUploadController.java

 
 import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
 
+import org.encuestame.core.image.ThumbnailGeneratorEngine;
 import org.encuestame.core.util.MD5Utils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 @Controller
 public class FileUploadController extends BaseController {
 
+    @Autowired
+    private ThumbnailGeneratorEngine thumbnailGeneratorEngine;
+
     /**
      * Upload Profile for User Account.
      * @param multipartFile
      * @return
      */
-    @RequestMapping(value = "/user/profile/file/upload", method = RequestMethod.POST)
+    @RequestMapping(value = "/file/upload/profile", method = RequestMethod.POST)
     public ModelAndView handleUserProfileFileUpload(
             @RequestParam("file") MultipartFile multipartFile) {
         ModelAndView mav = new ModelAndView(new MappingJacksonJsonView());
             //TODO: convert name to numbers, MD5 hash.
             final String filePath = MD5Utils.shortMD5(getPictureService().getAccountUserPicturePath("FAKE") + orgName);
             try {
+                InputStream stream = multipartFile.getInputStream();
+                try {
+                    //generate thumbnails
+                    thumbnailGeneratorEngine.generateThumbnails(
+                            multipartFile.getName(),
+                            stream,
+                            multipartFile.getContentType(),
+                            getPictureService().getAccountUserPicturePath("FAKE"));
+                } catch (Exception e) {
+                    log.error(e);
+                } finally {
+                    stream.close();
+                }
+
+
                 //TODO: replace FAKE by getUserAuthenticationUsername
                 log.debug("org filePath "+filePath);
                 final File dest = new File(filePath);
         return mav;
     }
 
+    /**
+     * @return the thumbnailGeneratorEngine
+     */
+    public ThumbnailGeneratorEngine getThumbnailGeneratorEngine() {
+        return thumbnailGeneratorEngine;
+    }
+
+    /**
+     * @param thumbnailGeneratorEngine the thumbnailGeneratorEngine to set
+     */
+    public void setThumbnailGeneratorEngine(
+            ThumbnailGeneratorEngine thumbnailGeneratorEngine) {
+        this.thumbnailGeneratorEngine = thumbnailGeneratorEngine;
+    }
+
+
+
     /**  TODO: we can add more methods to upload different types of files. **/
 }

File encuestame-mvc/src/main/java/org/encuestame/mvc/controller/HomeController.java

 
 package org.encuestame.mvc.controller;
 
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.encuestame.business.service.PictureService.PictureType;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.ModelMap;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
 
 /**
  * Home or FrontEnd Controller.
         return "user/signin";
     }
 
+    @RequestMapping(value = "/signin2", method = RequestMethod.GET)
+    public String signInController2(ModelMap model) {
+        log.debug("HOME222222");
+        return "user/signin";
+    }
+
     /**
      * Search.
      * @param model
         return "search";
     }
 
-    @RequestMapping(value = "/search.jspx", method = RequestMethod.GET)
-    public String searchHomeGet(ModelMap model) {
-        log.debug("search");
-        return "search";
+    @RequestMapping( value = "/pictures", method = RequestMethod.GET)
+    @ResponseBody
+    public byte[] getPictureWeb2(){
+        byte[] bytes = {};
+        log.debug("getPictureWeb");
+        //log.debug("getPictureWeb"+id);
+        //log.debug("getPictureWeb"+username);
+        try {
+            bytes = getPictureService().getProfilePicture("","", PictureType.WEB);
+        } catch (FileNotFoundException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+            log.error(e);
+        }
+        return bytes;
     }
+
+    @RequestMapping( value = "/picture/imagezzz", method = RequestMethod.GET)
+    @ResponseBody
+    public byte[] getPictureWeb3(){
+        byte[] bytes = {};
+        log.debug("getPictureWeb");
+        //log.debug("getPictureWeb"+id);
+        //log.debug("getPictureWeb"+username);
+        try {
+            bytes = getPictureService().getProfilePicture("","", PictureType.WEB);
+        } catch (FileNotFoundException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+            log.error(e);
+        }
+        return bytes;
+    }
+
+
+    @RequestMapping( value = "/image.jspx", method = RequestMethod.GET)
+    @ResponseBody
+    public byte[] getPictureWeb(){
+        byte[] bytes = {};
+        log.debug("getPictureWeb");
+        //log.debug("getPictureWeb"+id);
+        //log.debug("getPictureWeb"+username);
+        try {
+            bytes = getPictureService().getProfilePicture("","", PictureType.WEB);
+        } catch (FileNotFoundException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+            log.error(e);
+        }
+        return bytes;
+    }
+
 }

File encuestame-mvc/src/main/java/org/encuestame/mvc/controller/PictureProfileFactoryController.java

  */
 package org.encuestame.mvc.controller;
 
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
 import org.encuestame.business.service.PictureService.PictureType;
 import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
      * @param id The identifier of the image
      * @return A byte[] that contains the requested image
      */
-    @RequestMapping( value = "/user/picture/{username}/thumbnail/{id}", method = RequestMethod.GET )
+    @RequestMapping( value = "/picture/{username}/thumbnail/{id}", method = RequestMethod.GET )
     @ResponseBody
     public byte[] getPictureThumbnail(
             @PathVariable String id,
             @PathVariable String username ){
-        return getPictureService().getProfilePicture(id, username, PictureType.THUMBNAIL);
+        byte[] bytes = {};
+        try {
+            bytes = getPictureService().getProfilePicture(id, username, PictureType.THUMBNAIL);
+        } catch (FileNotFoundException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        return bytes;
     }
 
     /**
      * @param id The identifier of the image
      * @return A byte[] that contains the requested image
      */
-    @RequestMapping( value = "/user/picture/{username}/default/{id}", method = RequestMethod.GET )
+    @RequestMapping( value = "/picture/{username}/default/{id}", method = RequestMethod.GET )
     @ResponseBody
     public byte[] getPictureMaster(
             @PathVariable String id,
             @PathVariable String username ){
-        return getPictureService().getProfilePicture(id, username, PictureType.DEFAULT);
+        byte[] bytes = {};
+        try {
+            bytes = getPictureService().getProfilePicture(id, username, PictureType.DEFAULT);
+        } catch (FileNotFoundException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        return bytes;
     }
 
     /**
      * @param id The identifier of the image
      * @return A byte[] that contains the requested image
      */
-    @RequestMapping( value = "/user/picture/{username}/preview/{id}", method = RequestMethod.GET)
+    @RequestMapping( value = "/picture/{username}/preview/{id}", method = RequestMethod.GET)
     @ResponseBody
     public byte[] getPicturePreview(
             @PathVariable String id,
             @PathVariable String username ){
-        return getPictureService().getProfilePicture(id, username,  PictureType.PREVIEW);
+        byte[] bytes = {};
+        try {
+            bytes = getPictureService().getProfilePicture(id, username,  PictureType.PREVIEW);
+        } catch (FileNotFoundException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        return bytes;
     }
 
     /**
      * @param id  The identifier of the image
      * @return A byte[] that contains the requested image
      */
-    @RequestMapping( value = "/user/picture/{username}/web/{id}", method = RequestMethod.GET)
+    @RequestMapping( value = "/picture/{username}/web/{id}", method = RequestMethod.GET)
     @ResponseBody
-    public byte[] getPictureWeb(
-            @PathVariable String id,
-            @PathVariable String username  ){
-        return getPictureService().getProfilePicture(id, username, PictureType.WEB);
+    public byte[] getPictureWeb(){
+        byte[] bytes = {};
+        log.debug("getPictureWeb");
+        //log.debug("getPictureWeb"+id);
+        //log.debug("getPictureWeb"+username);
+        try {
+            bytes = getPictureService().getProfilePicture("","", PictureType.WEB);
+        } catch (FileNotFoundException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+            log.error(e);
+        }
+        return bytes;
     }
-
 }

File encuestame-mvc/src/main/java/org/encuestame/mvc/controller/TweetPollVoteController.java

 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.encuestame.business.service.imp.ISecurityService;
-import org.encuestame.mvc.controller.validation.ControllerValidation;
+import org.encuestame.mvc.validator.ValidateOperations;
 import org.encuestame.persistence.domain.survey.TweetPollSwitch;
 import org.encuestame.utils.vote.UtilVoteCaptcha;
 import org.springframework.stereotype.Controller;
              log.info("vote_code "+code);
              final ISecurityService securityService = getServiceManager().getApplicationServices().getSecurityService();
              final ReCaptchaResponse reCaptchaResponse = getReCaptcha().checkAnswer(req.getRemoteAddr(), challenge, response);
-             final ControllerValidation validation = new ControllerValidation(securityService);
+             final ValidateOperations validation = new ValidateOperations(securityService);
              validation.validateCaptcha(reCaptchaResponse, result);
              log.info("reCaptchaResponse "+reCaptchaResponse.getErrorMessage());
              log.info("reCaptchaResponse "+reCaptchaResponse.isValid());

File encuestame-mvc/src/main/java/org/encuestame/mvc/controller/security/ForgetPasswordController.java

 import net.tanesha.recaptcha.ReCaptchaResponse;
 
 import org.encuestame.core.security.util.PasswordGenerator;
-import org.encuestame.mvc.controller.validation.ControllerValidation;
+import org.encuestame.mvc.validator.ValidateOperations;
 import org.encuestame.persistence.exception.EnMeExpcetion;
 import org.encuestame.utils.security.UnitForgotPassword;
 import org.encuestame.utils.web.UnitUserBean;
                  final String email = user.getEmail();
                  log.debug("email "+email);
                  final ReCaptchaResponse reCaptchaResponse = getReCaptcha().checkAnswer(req.getRemoteAddr(), challenge, response);
-                 final ControllerValidation validation = new ControllerValidation(getSecurityService());
+                 final ValidateOperations validation = new ValidateOperations(getSecurityService());
                  final UnitUserBean unitUserBean = validation.validateUserByEmail(email == null ? "" : email);
                  if(unitUserBean == null){
                      result.rejectValue("email", "secure.email.notvalid", new Object[]{user.getEmail()}, "");

File encuestame-mvc/src/main/java/org/encuestame/mvc/controller/security/SignUpAccountFormController.java

 import net.tanesha.recaptcha.ReCaptchaResponse;
 
 import org.encuestame.core.security.util.PasswordGenerator;
-import org.encuestame.mvc.controller.validation.ControllerValidation;
+import org.encuestame.mvc.validator.ValidateOperations;
 import org.encuestame.utils.security.SignUpBean;
 import org.encuestame.utils.web.UnitUserBean;
 import org.springframework.stereotype.Controller;
              log.info("username "+username);
              log.info("password "+email);
              final ReCaptchaResponse reCaptchaResponse = getReCaptcha().checkAnswer(req.getRemoteAddr(), challenge, response);
-             final ControllerValidation validation = new ControllerValidation(getSecurityService());
+             final ValidateOperations validation = new ValidateOperations(getSecurityService());
 
              if(validation.validateUserByEmail(email) != null){
                    log.warn("Email NOT VALID");

File encuestame-mvc/src/main/java/org/encuestame/mvc/controller/security/json/JsonUsersController.java

 import org.codehaus.jackson.map.JsonMappingException;
 import org.encuestame.core.util.RelativeTimeEnum;
 import org.encuestame.mvc.controller.AbstractJsonController;
-import org.encuestame.mvc.controller.validation.ControllerValidation;
+import org.encuestame.mvc.validator.ValidateOperations;
 import org.encuestame.persistence.exception.EnMeDomainNotFoundException;
 import org.encuestame.utils.web.UnitUserBean;
 import org.springframework.security.access.prepost.PreAuthorize;
             //     .getSecurityService().searchUsersByEmail(email).size();
             //final Integer usernames = getServiceManager().getApplicationServices()
             //     .getSecurityService().searchUsersByUsername(username).size();
-            final ControllerValidation cv = new ControllerValidation( getServiceManager().getApplicationServices()
+            final ValidateOperations cv = new ValidateOperations( getServiceManager().getApplicationServices()
                   .getSecurityService());
             if(cv.validateEmail(email) && cv.validateUsername(username)){
                 final Map<String, Object> sucess = new HashMap<String, Object>();

File encuestame-mvc/src/main/java/org/encuestame/mvc/controller/validation/ControllerValidation.java

-/*
- ************************************************************************************
- * Copyright (C) 2001-2010 encuestame: system online surveys Copyright (C) 2009
- * encuestame Development Team.
- * Licensed under the Apache Software License version 2.0
- * 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.
- ************************************************************************************
- */
-package org.encuestame.mvc.controller.validation;
-
-import java.util.regex.Pattern;
-
-import net.tanesha.recaptcha.ReCaptchaResponse;
-
-import org.apache.log4j.Logger;
-import org.encuestame.business.service.imp.ISecurityService;
-import org.encuestame.core.util.ValidationUtils;
-import org.encuestame.persistence.domain.security.UserAccount;
-import org.encuestame.utils.web.UnitUserBean;
-import org.springframework.util.StringUtils;
-import org.springframework.validation.Errors;
-
-/**
- * Controller Validation.
- * @author Picado, Juan juanATencuestame.org
- * @since Jun 13, 2010 7:48:27 PM
- * @version $Id:$
- */
-public class ControllerValidation {
-
-    private static final Pattern emailPattern = Pattern.compile(ValidationUtils.EMAIL_REGEXP, Pattern.CASE_INSENSITIVE);
-
-    private Logger log = Logger.getLogger(this.getClass());
-
-    /**
-     *
-     * @param securityService
-     */
-    public ControllerValidation(final ISecurityService securityService) {
-        this.securityService = securityService;
-    }
-
-    private ISecurityService securityService;
-
-    /**
-     * Validate Username.
-     * @param username username
-     * @return
-     */
-    public Boolean validateUsername(final String username){
-        Boolean valid = false;
-        final UserAccount user = getSecurityService().findUserByUserName(username);
-        if(user == null){
-            valid = true;
-        }
-        return valid;
-    }
-
-    /**
-     * Validate User By Email.
-     * @param email email
-     * @return
-     */
-    public UnitUserBean validateUserByEmail(final String email){
-        UnitUserBean unitUserBean = null;
-        if(this.validateEmail(email)) {
-            unitUserBean = getSecurityService().findUserByEmail(email);
-        }
-        return unitUserBean;
-    }
-
-    /**
-     *
-     * @param email
-     * @return
-     */
-    public Boolean validateEmail(final String email){
-        Boolean valid = false;
-        if(emailPattern.matcher(email).matches() && StringUtils.hasLength(email)) {
-            log.warn("Captcha NOT VALID");
-            valid = !valid;
-        }
-        return valid;
-    }
-
-    /**
-     *
-     */
-    public void validateCaptcha(final ReCaptchaResponse reCaptchaResponse, final Errors errors){
-        if(!reCaptchaResponse.isValid()){
-            log.warn("Captcha NOT VALID");
-            errors.rejectValue("captcha", "secure.captcha.invalid");
-        } else {
-            log.info("Captcha VALID");
-        }
-    }
-
-    /**
-     * @return the securityService
-     */
-    public ISecurityService getSecurityService() {
-        return securityService;
-    }
-
-    /**
-     * @param securityService the securityService to set
-     */
-    public void setSecurityService(final ISecurityService securityService) {
-        this.securityService = securityService;
-    }
-}

File encuestame-mvc/src/main/java/org/encuestame/mvc/converter/EnhancedBufferedImageHttpMessageConverter.java

+package org.encuestame.mvc.converter;
+
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.imageio.ImageIO;
+
+import org.springframework.http.HttpOutputMessage;
+import org.springframework.http.MediaType;
+import org.springframework.http.converter.BufferedImageHttpMessageConverter;
+import org.springframework.http.converter.HttpMessageNotWritableException;
+
+public class EnhancedBufferedImageHttpMessageConverter extends BufferedImageHttpMessageConverter {
+
+    private List<MediaType> writerMediaTypes = new ArrayList<MediaType>();
+
+    public EnhancedBufferedImageHttpMessageConverter() {
+        String[] writerMimeTypes = ImageIO.getWriterMIMETypes();
+        for (String mimeType : writerMimeTypes) {
+            try {
+                writerMediaTypes.add(MediaType.parseMediaType(mimeType));
+            } catch (IllegalArgumentException e) {
+                // If the mimeType can't be parsed then it can't be a valid writerMediaType so ignore and go onto the next
+            }
+        }
+    }
+
+    @Override
+    public boolean canWrite(Class<?> clazz, MediaType mediaType) {
+        return (BufferedImage.class.equals(clazz) && isWritable(mediaType));
+    }
+
+    private boolean isWritable(MediaType mediaType) {
+        if (mediaType == null) {
+            return true;
+        }
+
+        for (MediaType writerMediaType : writerMediaTypes) {
+            if (writerMediaType.isCompatibleWith(mediaType)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public void write(BufferedImage image, MediaType contentType, HttpOutputMessage outputMessage) throws IOException,
+                HttpMessageNotWritableException {
+        MediaType checkedContentType = contentType;
+        if (contentType.isWildcardType() || contentType.isWildcardSubtype()) {
+            checkedContentType = null;
+        }
+        super.write(image, checkedContentType, outputMessage);
+    }
+}

File encuestame-mvc/src/main/java/org/encuestame/mvc/validator/SignUpBeanValidator.java

+/*
+ ************************************************************************************
+ * Copyright (C) 2001-2011 encuestame: system online surveys Copyright (C) 2009
+ * encuestame Development Team.
+ * Licensed under the Apache Software License version 2.0
+ * 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.
+ ************************************************************************************
+ */
+package org.encuestame.mvc.validator;
+
+import org.apache.log4j.Logger;
+import org.encuestame.business.service.SecurityService;
+import org.encuestame.business.service.imp.ISecurityService;
+import org.encuestame.utils.security.SignUpBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.binding.message.MessageBuilder;
+import org.springframework.binding.message.MessageContext;
+import org.springframework.binding.validation.ValidationContext;
+import org.springframework.stereotype.Component;
+
+/**
+ * Validator for SignUp.
+ * @author Picado, Juan juanATencuestame.org
+ * @since Jan 22, 2011 9:09:11 AM
+ * @version $Id:$
+ */
+@Component
+public class SignUpBeanValidator{
+
+    /**
+     * Log.
+     */
+    protected Logger log = Logger.getLogger(this.getClass());
+
+    /**
+     * Reference to {@link SecurityService}.
+     */
+    @Autowired
+    private ISecurityService securityService;
+
+    /**
+     * Validate SignUn Bean.
+     * @param booking
+     * @param context
+     */
+    public void validateSignup(SignUpBean booking, ValidationContext context) {
+        log.debug("Validate Sign Up");
+        final ValidateOperations validation = new ValidateOperations(securityService);
+        MessageContext messages = context.getMessageContext();
+        if(validation.validateUserByEmail(booking.getEmail()) != null){
+            log.warn("Email NOT VALID");
+            //result.rejectValue("email", "secure.email.notvalid"); //secure.email.notvalid
+            messages.addMessage(new MessageBuilder().error().source("email").
+                    defaultText("Email NOT VALID").build());
+        }
+        if(!validation.validateUsername(booking.getUsername())){
+            log.warn("Username NOT VALID");
+             //result.rejectValue("username", "secure.user.notvalid"); //secure.user.notvalid
+            messages.addMessage(new MessageBuilder().error().source("username").
+                    defaultText("Username NOT VALID").build());
+        }
+    }
+
+    /**
+     * @return the securityService
+     */
+    public ISecurityService getSecurityService() {
+        return securityService;
+    }
+
+    /**
+     * @param securityService the securityService to set
+     */
+    public void setSecurityService(final ISecurityService securityService) {
+        this.securityService = securityService;
+    }
+}

File encuestame-mvc/src/main/java/org/encuestame/mvc/validator/ValidateOperations.java

+/*
+ ************************************************************************************
+ * Copyright (C) 2001-2010 encuestame: system online surveys Copyright (C) 2009
+ * encuestame Development Team.
+ * Licensed under the Apache Software License version 2.0
+ * 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.
+ ************************************************************************************
+ */
+package org.encuestame.mvc.validator;
+
+import java.util.regex.Pattern;
+
+import net.tanesha.recaptcha.ReCaptchaResponse;
+
+import org.apache.log4j.Logger;
+import org.encuestame.business.service.imp.ISecurityService;
+import org.encuestame.core.util.ValidationUtils;
+import org.encuestame.persistence.domain.security.UserAccount;
+import org.encuestame.utils.web.UnitUserBean;
+import org.springframework.util.StringUtils;
+import org.springframework.validation.Errors;
+
+/**
+ * Controller Validation.
+ * @author Picado, Juan juanATencuestame.org
+ * @since Jun 13, 2010 7:48:27 PM
+ * @version $Id:$
+ */
+public class ValidateOperations {
+
+    private static final Pattern emailPattern = Pattern.compile(ValidationUtils.EMAIL_REGEXP, Pattern.CASE_INSENSITIVE);
+
+    private Logger log = Logger.getLogger(this.getClass());
+
+    /**
+     *
+     * @param securityService
+     */
+    public ValidateOperations(final ISecurityService securityService) {
+        this.securityService = securityService;
+    }
+
+    private ISecurityService securityService;
+
+    /**
+     * Validate Username.
+     * @param username username
+     * @return
+     */
+    public Boolean validateUsername(final String username){
+        Boolean valid = false;
+        final UserAccount user = getSecurityService().findUserByUserName(username);
+        if(user == null){
+            valid = true;
+        }
+        return valid;
+    }
+
+    /**
+     * Validate User By Email.
+     * @param email email
+     * @return
+     */
+    public UnitUserBean validateUserByEmail(final String email){
+        UnitUserBean unitUserBean = null;
+        if(this.validateEmail(email)) {
+            unitUserBean = getSecurityService().findUserByEmail(email);
+        }
+        return unitUserBean;
+    }
+
+    /**
+     *
+     * @param email
+     * @return
+     */
+    public Boolean validateEmail(final String email){
+        Boolean valid = false;
+        if(emailPattern.matcher(email).matches() && StringUtils.hasLength(email)) {
+            log.warn("Captcha NOT VALID");
+            valid = !valid;
+        }
+        return valid;
+    }
+
+    /**
+     *
+     */
+    public void validateCaptcha(final ReCaptchaResponse reCaptchaResponse, final Errors errors){
+        if(!reCaptchaResponse.isValid()){
+            log.warn("Captcha NOT VALID");
+            errors.rejectValue("captcha", "secure.captcha.invalid");
+        } else {
+            log.info("Captcha VALID");
+        }
+    }
+
+    /**
+     * @return the securityService
+     */
+    public ISecurityService getSecurityService() {
+        return securityService;
+    }
+
+    /**
+     * @param securityService the securityService to set
+     */
+    public void setSecurityService(final ISecurityService securityService) {
+        this.securityService = securityService;
+    }
+}

File encuestame-mvc/src/main/resources/encuestame-controller-context.xml

                         http://www.springframework.org/schema/context
                         http://www.springframework.org/schema/context/spring-context-3.0.xsd">
 
-
   <!--
     Maps requests to @Controllers based on @RequestMapping("path")
     annotation values If no annotation-based path mapping is found, Spring
      <property name="order" value="0"/>
   </bean>
 
- <bean id="mobileInterceptor" class="org.springframework.mobile.device.mvc.DeviceResolverHandlerInterceptor" />
- <bean id="enMeInterceptor" class=" org.encuestame.mvc.interceptor.DefaultEnMeInterceptor" />
+  <bean id="mobileInterceptor" class="org.springframework.mobile.device.mvc.DeviceResolverHandlerInterceptor" />
+  <bean id="enMeInterceptor" class=" org.encuestame.mvc.interceptor.DefaultEnMeInterceptor" />
 
   <!-- Scans for application @Components to deploy -->
   <context:component-scan base-package="org.encuestame.mvc" />
     POJO @Controller when one is mapped.
   -->
   <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
+        <property name="order" value="0"/>
         <!--
             NOTE: it is important to specify the order property, so this
             adapter will be attempted before the HandlerAdapter that
                 <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/>
 
                 <!-- Converter for images -->
-                <bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"/>
+                <bean class="org.encuestame.mvc.converter.EnhancedBufferedImageHttpMessageConverter"/>
 
                 <!-- Handle JAXB XML objects
                 <bean id="marshallingHttpMessageConverter"
                     </constructor-arg>
                 </bean> -->
 
-                <!-- This must come after our image converter -->
+                <!-- This must come after our image converter
                 <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
+                -->
             </list>
         </property>
   </bean>
 
+    <!-- thumbnail generator engine
+         thanks to raulraja.
+     -->
+    <bean id="thumbnailGeneratorEngine" class="org.encuestame.core.image.ThumbnailGeneratorEngineImpl">
+
+        <!-- the file extension for the thumbnail files -->
+        <property name="generatedExtension">
+            <value>.jpg</value>
+        </property>
+
+        <!-- the different sizes we want to generate, adjusting the aspect ratio based on the biggest dimension -->
+        <property name="supportedSizes">
+            <list>
+                <value>900</value>
+                <value>768</value>
+                <value>375</value>
+                <value>128</value>
+                <value>64</value>
+                <value>48</value>
+                <value>22</value>
+            </list>
+        </property>
+
+        <!-- mappings from the different content types to the right generator that handles each type -->
+        <property name="thumbnailGenerators">
+            <map>
+                <entry key="image/jpeg" value-ref="imageThumbnailGenerator" />
+                <entry key="image/jpg" value-ref="imageThumbnailGenerator" />
+                <entry key="image/pjpeg" value-ref="imageThumbnailGenerator" />
+                <entry key="image/gif" value-ref="imageThumbnailGenerator" />
+                <entry key="image/png" value-ref="imageThumbnailGenerator" />
+                <entry key="image/tiff" value-ref="imageThumbnailGenerator" />
+                <entry key="image/bmp" value-ref="imageThumbnailGenerator" />
+                <!--<entry key="application/pdf" value-ref="pdfThumbnailGenerator" />-->
+            </map>
+        </property>
+
+        <!-- A default thumbnail generator to be used for unregistered mime types -->
+        <property name="defaultThumbnailGenerator" ref="imageThumbnailGenerator"/>
+
+        <!-- location for the generated thumbnails -->
+        <property name="thumbnailsLocation" value="/home/jpicado/opt/encuestameImage"/>
+    </bean>
+
+    <!-- a thumbnail generator that generates thumbnails from images -->
+    <bean id="imageThumbnailGenerator" class="org.encuestame.core.image.ImageThumbnailGeneratorImpl" />
+
 </beans>

File encuestame-mvc/src/main/resources/username-blacklist.properties

+admin
+administrator
+root
+encuestame
+administrador

File encuestame-persistence/src/main/resources/log4j.properties

 #Spring Framework
 log4j.logger.org.springframework.security.oauth=DEBUG
 log4j.logger.org.springframework.security=WARN
-log4j.logger.org.springframework.webflow=WARN
+log4j.logger.org.springframework.webflow=DEBUG
 log4j.logger.org.springframework.web=DEBUG
 log4j.logger.org.springframework.orm.hibernate3.support.OpenSessionInViewFilter=WARN
 log4j.logger.org.encuestame=DEBUG

File encuestame-war/src/main/resources/encuestame-mvc-context.xml

                         http://www.springframework.org/schema/mobile/device
                         http://www.springframework.org/schema/mobile/device/spring-mobile-device-1.0.xsd">
 
- <!-- Define url mappings to web flow controller.  -->
-  <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
-    <property name="mappings">
-      <value>
-        /signup=flowController
-       </value>
-    </property>
-    <property name="defaultHandler" ref="urlFilenameViewController"/>
-    <property name="order" value="1"/>
-  </bean>
+   <!-- Define url mappings to web flow controller.  -->
+    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
+       <property name="mappings">
+         <value>
+           /signup=flowController
+         </value>
+       </property>
+       <property name="defaultHandler" ref="urlFilenameViewController"/>
+       <property name="order" value="1"/>
+    </bean>
 
   <!-- Maps request paths to @Controller classes;
        e.g. a path of /signup looks for a controller named SignUpController -->
     <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
         <property name="order" value="3" />
         <property name="defaultHandler">
-            <!-- If no @Controller match, map path to a view to render; e.g. the "/intro"
-                 path would map to the view named "intro" -->
             <ref bean="urlFilenameViewController"></ref>
         </property>
     </bean>
          <property name="order" value="0"/>
     </bean>
 
-     <!--
-     http://static.springsource.org/spring/docs/3.0.3.RELEASE/spring-framework-reference/html/view.html
-    <bean id="viewMappings" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
-       <property name="order" value="3"/>
-       <property name="basename" value="views"/>
-    </bean>
-    -->
-
   <!--
   This Resolve it's not compatible with org.springframework.web.servlet.view.UrlBasedViewResolver -->
   <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
       <property name="suffix" value=".jsp"/>
   </bean>
 
-  <!-- UrlFile Name View Controller. -->
+  <!-- Controller Views -->
   <bean id="urlFilenameViewController" class="org.springframework.web.servlet.mvc.UrlFilenameViewController" />
 
-  <!--
-    Dispatches requests mapped to
+  <bean id="flowController" class="org.springframework.webflow.mvc.servlet.FlowController">
+    <property name="flowExecutor" ref="flowExecutor"/>
+  </bean>
+
+  <!-- Dispatches requests mapped to
     org.springframework.web.servlet.mvc.Controller implementations
-  -->
+    required to render urlFilenameViewController.
+    -->
   <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
 
+
   <!--
     Dispatches requests mapped to flows to FlowHandler implementations
    <bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
   </bean>
   -->
 
-  <bean id="flowController" class="org.springframework.webflow.mvc.servlet.FlowController">
-    <property name="flowExecutor" ref="flowExecutor"/>
-  </bean>
-
     <!-- Maps request paths to flows in the flowRegistry;
         e.g. a path of /hotels/booking looks for a flow with id "hotels/booking"
     <bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
     </property>
   </bean>
   -->
+
+    <!--
+     http://static.springsource.org/spring/docs/3.0.3.RELEASE/spring-framework-reference/html/view.html
+    <bean id="viewMappings" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
+       <property name="order" value="3"/>
+       <property name="basename" value="views"/>
+    </bean>
+    -->
+
 </beans>

File encuestame-war/src/main/resources/encuestame-web-flow-registry-context.xml

-<?xml version="1.0" encoding="UTF-8"?>
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xmlns:webflow="http://www.springframework.org/schema/webflow-config"
-       xmlns:faces="http://www.springframework.org/schema/faces"
-       xsi:schemaLocation="
-           http://www.springframework.org/schema/beans
-           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
-           http://www.springframework.org/schema/webflow-config
-           http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd
-           http://www.springframework.org/schema/faces
-           http://www.springframework.org/schema/faces/spring-faces-2.0.xsd">
-
-     <!-- The registry of executable flow definitions -->
-     <webflow:flow-registry id="flowRegistry" base-path="/WEB-INF/flows">
-        <webflow:flow-location-pattern value="/**/*-flow.xml" />
-    </webflow:flow-registry>
-
-
-</beans>

File encuestame-war/src/main/resources/encuestame-web-flow-registry-test-context.xml

-<?xml version="1.0" encoding="UTF-8"?>
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xmlns:webflow="http://www.springframework.org/schema/webflow-config"
-       xmlns:faces="http://www.springframework.org/schema/faces"
-       xsi:schemaLocation="
-           http://www.springframework.org/schema/beans
-           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
-           http://www.springframework.org/schema/webflow-config
-           http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd
-           http://www.springframework.org/schema/faces
-           http://www.springframework.org/schema/faces/spring-faces-2.0.xsd">
-
-     <!-- The registry of executable flow definitions -->
-     <webflow:flow-registry id="flowRegistry" base-path="${application.test.flow.path}">
-        <webflow:flow-location-pattern value="/**/*-flow.xml" />
-    </webflow:flow-registry>
-
-
-</beans>

File encuestame-war/src/main/webapp/WEB-INF/flows/signup/profile.jsp

     dojo.require("encuestame.org.core.commons.signup.SignupProfile");
 </script>
     <div id="mainUserWrapper">
-        <form:form modelAttribute="signUpBean">
+        <form:form>
             <div class="">
                 <div dojoType="encuestame.org.core.commons.signup.SignupProfile"
                      username="${signUpBean.username}"

File encuestame-war/src/main/webapp/WEB-INF/flows/signup/signup-flow.xml

             <binding property="email" />
             <binding property="captcha" />
         </binder>
-        <transition on="saveUser" to="findFriends" >
+        <transition on="saveUser" to="findFriends" validate="true" history="discard">
                <evaluate expression="securityService.singupUser(signUpBean)" result="flowScope.userAccount"
                          result-type="org.encuestame.utils.web.UnitUserBean"/>
         </transition>
     </view-state>
 
     <view-state id="findFriends" model="signUpBean">
-        <transition on="next" to="profile" />
+        <transition on="next" to="profile" history="discard" />
     </view-state>
 
     <view-state id="profile" model="signUpBean">
-        <transition on="next" to="isActivated" />
+        <transition on="next" to="isActivated" history="discard" />
     </view-state>
 
      <view-state id="noActivated" model="signUpBean">
-        <transition on="review" to="isActivated" />
+        <transition on="review" to="isActivated" history="discard" />
     </view-state>
 
     <action-state id="isActivated">

File encuestame-war/src/main/webapp/WEB-INF/sql/install.sql

+INSERT INTO `account` (`uid`, `twitter_consumer_key`, `twitter_consumer_secret`, `twitter_account`, `twitter_password`, `twitter_pin`) VALUES
+(1, 'nFboU4T1Zhv8cqMC4cP0ug', 'GwOPUEJEaCbNBiBzq6J8StDhb7FOmwDcjfX6zMe0', 'testEncuesta', 'testEncuesta123', 4189783);
+
+INSERT INTO `userAccount` (`uid`, `name`, `date_new`, `invite_code`, `password`, `email`, `status`, `twitter`, `username`, `account_uid`, `last_ip_logged`, `last_time_logged`) VALUES
+(1, 'Juan Carlos Picado', '2010-01-20 12:47:40', '', '6xAX8siGWDJXfkJUVxWLqsk0rz8U+aG6Y8yA1IokxuhEIZ8+RugleJtLUYbdGxc+', 'juanpicado19@gmail.com', '', NULL, 'admin', 1, NULL, '2010-09-26 10:07:25');
+
+INSERT INTO `permission` (`id_permission`, `permission`, `description`) VALUES
+(2, 'ENCUESTAME_ADMIN', 'ENCUESTAME_ADMIN'),
+(3, 'ENCUESTAME_OWNER', 'ENCUESTAME_OWNER'),
+(4, 'ENCUESTAME_PUBLISHER', 'ENCUESTAME_PUBLISHER'),
+(5, 'ENCUESTAME_EDITOR', 'ENCUESTAME_EDITOR'),
+(6, 'ENCUESTAME_USER', 'ENCUESTAME_USER');
+
+INSERT INTO `userAccount_permission` (`sec_id_secondary`, `sec_id_permission`) VALUES
+(1, 2),
+(1, 3),
+(1, 4),
+(1, 5),
+(1, 6)

File encuestame-war/src/main/webapp/WEB-INF/web.xml

     </servlet-mapping>
     <servlet-mapping>
         <servlet-name>encuestame-spring-dispacher</servlet-name>
+        <url-pattern>/picture/*</url-pattern>
+    </servlet-mapping>
+    <servlet-mapping>
+        <servlet-name>encuestame-spring-dispacher</servlet-name>
         <url-pattern>*.pdf</url-pattern>
     </servlet-mapping>
     <servlet-mapping>

File encuestame-war/src/main/webapp/resource/js/encuestame/org/core/commons/signup/SignupProfile.js

             handleAs : "html",
             handle : function(ioResponse, args) {
                 if (ioResponse instanceof Error) {
-                    console.log("handle error: " + ioResponse);
+                    console.error("handle error: " + ioResponse);
                 } else {
-                    console.log("handle response: " + ioResponse);
+                    console.info("handle response: " + ioResponse);
                 }
             },
             // Callback on successful call:

File encuestame-war/src/main/webapp/resource/js/encuestame/org/core/commons/signup/templates/profile.inc

 <div class="updateProfile">
         FORMULARIO ACTUALIZACION
         <h1>Please upload a file</h1>
-        <form method="post" action="/encuestame/user/profile/file/upload" enctype="multipart/form-data" id="imageForm">
+        <form method="post" action="/encuestame/user/file/upload/profile" enctype="multipart/form-data" id="imageForm">
               <input type="file" name="file" onkeydown="javascript:return false;"/>
               <input type="button" value="Upload" dojoAttachEvent="onclick:_uploadImage"
         </form>
     <version>1.1.32-SNAPSHOT</version>
     <name>encuestame</name>
     <description>
-    encuestame is a open source webapp java survey system
+    encuestame is a open source webapp java survey system build