## Upload Images

In the previous chapter we have discussed how to create Navigation Trees that represent "Album Groups - Albums" hierarchy. Now it is time to upload images.

The <rich:fileUpload> component in the Photo Album application uses the embedded Flash module that adds extra functionality to the component:

- Multiple files choosing;

- Definition of permitted file types in the "Open File" dialog window;

- A number of additional client side object properties.

The code for the <rich:fileUpload> is contained in the "/includes/fileUpload/fileUploader.xhtml" page:

                        …
                    <rich:fileUpload maxFilesQuantity="100"
                        fileUploadListener="#{'#{'}fileUploadManager.listener}"
                        id="fileUpload"
                        disabled="#{'#{'}model.selectedAlbum == null}"
                        acceptedTypes="jpg,jpeg"
                        execute="uploadAlbum">
                        <a4j:ajax event="uploadcomplete" render="treePanel, filesPanel" listener="#{'#{'}fileWrapper.setComplete(true)}"
                            limitRender="true" />
                    </rich:fileUpload>
                        …

The "acceptedTypes" attribute specifies "jpg", "jpeg" as the permitted file types you can upload.

The "fileUploadListener" attribute represents the action listener method `listener()` of the `FileUploadManager` class that is notified after file is uploaded. This method makes the main job on the upload:

                public void listener(FileUploadEvent event) {
                    if (user == null) {
                        return;
                    }
                    UploadedFile file = event.getUploadedFile();
                    uploadFile(new FileHandler(file), model.getSelectedAlbum());
                }

                public void uploadFile(FileHandler fileHandler, Album album) {
                    Image image = constructImage(fileHandler);
                    try {
                        extractMetadata(fileHandler, image);
                    } catch (Exception e1) {
                        addError(fileHandler, image, Constants.FILE_PROCESSING_ERROR);
                        return;
                    }

                    image.setAlbum(album);
                    if (image.getAlbum() == null) {
                        addError(fileHandler, image, Constants.NO_ALBUM_TO_DOWNLOAD_ERROR);
                        return;
                    }
                    try {
                        if (imageAction.isImageWithThisPathExist(image.getAlbum(), image.getPath())) {
                            String newPath = generateNewPath(image);
                            image.setPath(newPath);
                            image.setName(newPath);
                        }
                        imageAction.addImage(image);
                    } catch (Exception e) {
                        addError(fileHandler, image, Constants.IMAGE_SAVING_ERROR);
                        return;
                    }
                    try {
                        if (!fileManager.addImage(image.getFullPath(), fileHandler)) {
                            addError(fileHandler, image, Constants.FILE_SAVE_ERROR);
                            return;
                        }
                    } catch (IOException ioe) {
                        log.log(Level.INFO, "error", ioe);
                        addError(image, Constants.FILE_SAVE_ERROR + " - " + ioe.getMessage());
                    }

                    fileWrapper.setComplete(false);
                    fileWrapper.getFiles().add(image);
                    imageEvent.fire(new ImageEvent(image));
                    try {
                        fileHandler.delete();
                    } catch (IOException ioe) {
                        log.log(Level.INFO, "error", ioe);
                        addError(image, "Error deleting file - " + ioe.getMessage());
                    }
                }

The `uploadFile()` method creates an `Image` object and extracts all image metadata such as Camera name, Image size, etc. It performs scaling of an image and saves six different image's dimensions in order to create thumbnails. After that the photo is added into the database the temporary file is removed.

Visit following pages at RichFaces Showcase for more information, examples and sources on the components used in the application and described in this chapter:

- FileUpload page for the <rich:fileUpload> component;

- Ajax for the <a4j:ajax> component.