org.iavante.sling.gad.hospies.impl.HospiesImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.iavante.sling.gad.hospies.impl.HospiesImpl.java

Source

/*
 * Digital Assets Management
 * =========================
 * 
 * Copyright 2009 Fundacin Iavante
 * 
 * Authors: 
 *   Francisco Jos Moreno Llorca <packo@assamita.net>
 *   Francisco Jess Gonzlez Mata <chuspb@gmail.com>
 *   Juan Antonio Guzmn Hidalgo <juan@guzmanhidalgo.com>
 *   Daniel de la Cuesta Navarrete <cues7a@gmail.com>
 *   Manuel Jos Cobo Fernndez <ranrrias@gmail.com>
 *
 * Licensed under the EUPL, Version 1.1 or  as soon they will be approved by
 * the European Commission - subsequent versions of the EUPL (the "Licence");
 * You may not use this work except in compliance with the Licence.
 * You may obtain a copy of the Licence at:
 *
 * http://ec.europa.eu/idabc/eupl
 *
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the Licence is distributed on an "AS IS" basis,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the Licence for the specific language governing permissions and 
 * limitations under the Licence.
 * 
 */
package org.iavante.sling.gad.hospies.impl;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.util.Date;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.text.SimpleDateFormat;

import javax.jcr.AccessDeniedException;
import javax.jcr.ItemNotFoundException;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.GetMethod;
import javax.servlet.http.HttpServletRequest;
import org.iavante.sling.commons.services.PortalSetup;
import org.iavante.sling.gad.hospies.Hospies;
import org.jets3t.service.S3Service;
import org.jets3t.service.S3ServiceException;
import org.jets3t.service.acl.AccessControlList;
import org.jets3t.service.impl.rest.httpclient.RestS3Service;
import org.jets3t.service.model.S3Bucket;
import org.jets3t.service.model.S3Object;
import org.jets3t.service.security.AWSCredentials;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * @see org.iavante.sling.gad.hospies.Hospies
 * @scr.component immediate="true"
 * @scr.service interface="org.iavante.sling.gad.hospies.Hospies"
 * @scr.property name="service.description" value="IAVANTE - Hospies"
 * @scr.property name="service.vendor" value="IAVANTE"
 * @scr.property name="service.type" value="distributionserver"
 * @scr.property name="service.typeimpl" value="hospies"
 */
public class HospiesImpl implements Hospies, Serializable {
    private static final long serialVersionUID = 1L;

    /** @scr.reference */
    private PortalSetup portalSetup;

    /** Default Logger. */
    private static final Logger log = LoggerFactory.getLogger(HospiesImpl.class);

    /** profiles. */
    private String[] profiles = null;

    /** base manifest for the profiles. */
    private String base_manifest = null;

    /** base playlist file name for the profiles. */
    private String base_playlist = null;

    /** base video file name for the profiles. */
    private String base_videos = null;

    /** base current file name for the profiles. */
    private String base_current = null;

    /** transformation name */
    private String transformation_name = "transformation";

    /** temporal directory in the app. server domain */
    private String tmp_folder = "tmp";

    /** hospbucket, bucket */
    private String hospbucket = null;

    /** paths to transformations */
    private String converted_file_folder = null;

    /** S3 Key */
    private String s3_key = null;

    /** S3 Secret */
    private String s3_secret = null;

    /** S3 Credentials. */
    private static AWSCredentials awsCredentials;

    /** S3 Service. */
    private S3Service s3service;

    /** manifest body **/
    private String manifest_head = "<?xml version='1.0' encoding='UTF-8'?>\n" + "<!DOCTYPE update>" + "<root>\n";

    /** daily playlists */
    private int daily_playlist = 0;

    /** manifest foot **/
    private String manifest_foot = "</root>\n";

    /** playlist head */
    private String playlist_head = "<?xml version=\"1.0\"?>\n"
            + "<smil xmlns=\"http://www.w3.org/2001/SMIL20/Language\">\n" + "  <head>\n"
            + "    <meta name=\"title\" content=\"ies \"/>\n" + "    <meta name=\"generator\" content=\"ies\"/>\n"
            + "    <meta name=\"author\" content=\"ies\"/>\n" + "    <layout>\n"
            + "      <root-layout id=\"Welcome\" backgroundColor=\"gray\" width=\"800\" height=\"600\"/>\n"
            + "      <region id=\"background\" width=\"800\" height=\"600\"/>\n" + "    </layout>\n" + "  </head>\n"
            + "  <body>\n" + "   <par>\n" + "    <img src=\"/etc/X11/xdm/FondoXDM.jpg\" region=\"Welcome\"/>\n"
            + "        <seq >\n";

    /** playlist foot */
    private String playlist_foot = "        </seq>\n" + "   </par>\n" + "  </body>\n" + "</smil>\n";

    /** array of manipuling nodes */
    private static ArrayList<Node> man_nodes = null;

    protected void activate(ComponentContext context) throws Exception {

        Map<String, String> properties = portalSetup.get_config_properties("/hospies");

        if (properties.containsKey("profiles"))
            profiles = properties.get("profiles").split(",");
        if (properties.containsKey("base_current"))
            base_current = properties.get("base_current");
        if (properties.containsKey("base_manifest"))
            base_manifest = properties.get("base_manifest");
        if (properties.containsKey("base_playlist"))
            base_playlist = properties.get("base_playlist");
        if (properties.containsKey("base_videos"))
            base_videos = properties.get("base_videos");
        if (properties.containsKey("transformation_name"))
            transformation_name = properties.get("transformation_name");
        if (properties.containsKey("hospies_bucket"))
            hospbucket = properties.get("hospies_bucket");

        properties = portalSetup.get_config_properties("/s3backend");

        if (properties.containsKey("key"))
            s3_key = properties.get("key");
        if (properties.containsKey("secret"))
            s3_secret = properties.get("secret");

        properties = portalSetup.get_config_properties("/transcoder");

        if (properties.containsKey("converted_file_folder"))
            converted_file_folder = properties.get("converted_file_folder");

        man_nodes = new ArrayList<Node>();

        awsCredentials = new AWSCredentials(s3_key, s3_secret);
        try {
            s3service = new RestS3Service(awsCredentials);
        } catch (S3ServiceException e1) {
            log.error("Error getting the s3service");
            throw new java.lang.Exception("Error getting the s3service");
        }

        /* check the temporal folder abd create if missing */
        File file = new File(tmp_folder);
        if (file.exists() == false)
            if (file.mkdir() == false) {
                log.error("Error making tmp folder");
                tmp_folder = "tmp";
            }
        log.info("HOSPIES: activated: " + this);

    }

    /*
     * @see org.iavante.sling.gad.hospies.hospies#getUrl
     */
    public String getUrl(String object) {

        return null;
    }

    /*
     * @see org.iavante.sling.hospies.hospies#upload
     */
    public String upload(Node contentNode) {
        log.info("HOSPIES called with a node as parameter");
        log.info("HOSPIES this:" + this);

        /* get the profile */
        String profile = "";

        profile = getChannelProfile(contentNode);

        if (isValidVideoNode(contentNode) == false) {
            /* it isn't a valid node transformation, exit ok */
            log.error("HOSPIES: it isn't a valid node transformation, exit ok");
            return "200";
        }
        /* the content in valid, continue */
        log.info("HOSPIES the node is a valid video content");

        /* set if the playlist is daily */
        daily_playlist = isDailyPlaylist(contentNode);
        if (daily_playlist == 1)
            return "200";
        /*
         * upload the content and the brothers nodes
         */
        try {
            log.info("HOSPIES uploading...");
            String status = this.upload(contentNode.getParent().getNodes(), profile, contentNode);
            man_nodes.remove(contentNode);
            log.info("HOSPIES uploaded with code: " + status);
            return status;
        } catch (ItemNotFoundException e) {
            log.error("ERROR uploading to HOSPIES: itemNotFound: " + e.getMessage());
            return "500";
        } catch (AccessDeniedException e) {
            log.error("ERROR uploading to HOSPIES: AccessDeniedExcep: " + e.getMessage());
            return "500";
        } catch (RepositoryException e) {
            log.error("ERROR uploading to HOSPIES: RepositoryExc: " + e.getMessage());
            return "500";
        }
    }

    /**
     * 
     * @param contentNode
     *          that is uploading
     * @return 0 if is not daily playlist, 1 if is daily but hasn't got all the
     *         contents, 2 if is daily content and has got the seven contents.
     */
    private int isDailyPlaylist(Node contentNode) {
        try {
            String daily_hospies = "";
            if (contentNode.getParent().getParent().hasProperty("daily_hospies"))
                daily_hospies = contentNode.getParent().getParent().getProperty("daily_hospies").getString();
            if ("true".compareToIgnoreCase(daily_hospies) == 0) {
                if (contentNode.getParent().getNodes().getSize() == 7)
                    return 2;
                else
                    return 1;
            } else
                return 0;
        } catch (ItemNotFoundException e) {
            log.error("isDaylyPlaylist: there is an error getting the channel node: " + e.getMessage());
            return 0;
        } catch (AccessDeniedException e) {
            log.error("isDaylyPlaylist: there is an error getting the channel node: " + e.getMessage());
            return 0;
        } catch (RepositoryException e) {
            log.error("isDaylyPlaylist: there is an error getting the channel node: " + e.getMessage());
            return 0;
        }
    }

    /**
     * get from the channel the IES profile to use in the bundle
     * 
     * @param contentNode
     *          is the son-> son of the channel to get the profile
     * @return the profile to use, if there is an error, the default is
     *         "sala_de_espera"
     */
    private String getChannelProfile(Node contentNode) {

        try {
            Node channel = contentNode.getParent().getParent();
            if (channel.hasProperty("profile_hospies") == true) {
                String profile = channel.getProperty("profile_hospies").getString();
                if (checkProfileExist(profile) == true)
                    return profile;
                else
                    return "sala_de_espera";
            }

        } catch (ItemNotFoundException e) {
            log.error("HOSPIES ERROR: exception getting the profile from the channel ItemNotFoundException: "
                    + e.getMessage());
        } catch (AccessDeniedException e) {
            log.error("HOSPIES ERROR: exception getting the profile from the channel AccessDeniedException: "
                    + e.getMessage());
        } catch (RepositoryException e) {
            log.error("HOSPIES ERROR: exception getting the profile from the channel RepositoryException: "
                    + e.getMessage());
        }

        return "sala_de_espera";
    }

    /**
     * check if the node content a transformation of the IES channel
     * 
     * @param contentNode
     *          the node to check
     * @return true if the node is valid, false in other case
     */
    private boolean isValidVideoNode(Node contentNode) {
        /* check that the node is a video */
        NodeIterator sourcenodes;
        try {
            sourcenodes = contentNode.getNode("sources").getNodes();
            Node source = null;

            while (sourcenodes.hasNext()) {
                /* for each content iterate into sources */
                source = sourcenodes.nextNode();

                try {
                    if (source.getNode("transformations").hasNode(transformation_name) == true) {
                        log.info("HOSPIES: there is a transformation name");
                        return true;
                    } else {
                        /*
                         * if there is no "transformation_name" transformation, exit
                         */
                        log.info("HOSPIES: there is no transformation name");
                        // return false;
                    }

                } catch (PathNotFoundException e1) {
                    log.info("HOSPIES: source without transformations");
                }
            }
        } catch (PathNotFoundException e1) {
            log.error("HOSPIES: error getting: " + e1.getMessage());
            return false;
        } catch (RepositoryException e1) {
            log.error("HOSPIES: error uploading a node content: " + e1.getMessage());
            return false;
        }
        return false;
    }

    /*
     * @see org.iavante.sling.hospies.hospies#upload
     */
    public String upload(String fileName) {
        String results = null;
        try {
            // get the bucket
            S3Bucket bucket = s3service.getBucket(hospbucket);
            log.info("HOSPIES: " + hospbucket);
            log.info("HOSPIES: " + fileName);
            // create an object with the file data
            File fileData = new File(fileName);
            S3Object fileObject = new S3Object(bucket, fileData);
            fileObject.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ);
            // put the data on S3
            s3service.putObject(bucket, fileObject);
            if (log.isInfoEnabled())
                log.info("Successfully uploaded object - " + fileObject);
            results = "200";

        } catch (S3ServiceException e) {
            log.error("Error uploading file to S3");
            return "500";
        } catch (NoSuchAlgorithmException e) {
            log.error("Error uploading file to S3");
            e.printStackTrace();
        } catch (IOException e) {
            log.error("Error getting data from file");
            e.printStackTrace();
        }
        return results;
    }

    /*
     * @see org.iavante.sling.hospies.hospies#upload
     */
    public String upload(NodeIterator itnode, String profile, Node contentNode) {
        log.info("HOSPIES called with profile: " + profile);
        try {
            String publish_code = null;
            List<String> playlistmsg = new ArrayList<String>();
            String manifestmsg = null;
            String videosmsg = null;

            /* check that the profile is correct */
            if (!checkProfileExist(profile)) {
                log.error("Error: the profile doesn't exists");
                return "404";
            }
            log.info("HOSPIES: profile exists");
            /* get the list of transformations */
            ArrayList<String> transformations_av = getTransformationsList(itnode);
            log.info("HOSPIES got transformation list");
            /* upload transformations to S3 */
            if (!uploadTransformations(transformations_av)) {
                log.error("Error, can't upload transformations, aborting...");
                return "500";
            }
            log.info("HOSPIES: transformations uploaded");
            /* check the availability of transformations */
            if (checkTransformationsAvailability(transformations_av) != 200) {
                log.error("Error, the transformations aren't in remote repository");
                return "404";
            }
            log.info("HOSPIES transformations remote availability checked");
            /* generate the publish code */
            publish_code = getCodeForPublishing();
            log.info("HOSPIES: code for publishing obtained");
            /* generate publishing objects */
            manifestmsg = createManifest(profile);
            playlistmsg = createPlaylist(transformations_av, contentNode);
            videosmsg = createVideoList(transformations_av);
            log.info("HOSPIES: manifest, playlist and video created");
            /* upload publishing documents */
            if (publishUpdate(manifestmsg, playlistmsg, videosmsg, profile, publish_code) != 200) {
                log.error("publishUpdate out with errors");
                return "500";
            }
            log.info("HOSPIES: manifests updated");
        } catch (Exception e) {
            log.error("Error publishing: " + e.getMessage());
            return "500";
        }
        log.info("HOSPIES: total update fisnish");
        return "200";
    }

    /**
     * upload transformations to S3
     * 
     * @param transformationsAv
     *          is the list of transformations
     * @return true if OK, false in other case
     */
    private boolean uploadTransformations(ArrayList<String> transformationsAv) {

        ListIterator<String> it = transformationsAv.listIterator();
        ArrayList<String> remote_names = new ArrayList<String>();

        /*
         * iterate through the files and upload them if they aren't in the remote
         * server
         */
        S3Bucket upload_bucket;
        try {
            upload_bucket = s3service.getBucket(hospbucket);
            S3Object[] remote_objects = s3service.listObjects(upload_bucket);
            for (int i = 0; i < remote_objects.length; i++) {
                remote_names.add(remote_objects[i].getKey());
            }
        } catch (S3ServiceException e1) {
            log.error("Error listing objects in S3");
            return false;
        }

        try {
            while (it.hasNext()) {

                String name = it.next();
                if (!name.endsWith("mp4")) {
                    log.info("HOSPIES: media hasn't the correc format: " + name);
                    continue;
                }
                boolean uploaded = false;
                log.info("HOSPIES: media has the correct format: " + name);
                /* if the local file is in remote server, pass to the next file */
                ListIterator<String> it_remote = remote_names.listIterator();
                while (it_remote.hasNext()) {
                    if (it_remote.next().compareToIgnoreCase(name) == 0) {
                        uploaded = true;
                        break;
                    }
                }

                if (uploaded == true)
                    continue;

                File fileData = new File(converted_file_folder + "/" + name);
                S3Object upload_object = new S3Object(upload_bucket, fileData);
                if (upload_object == null || upload_bucket == null) {
                    log.error("Error, upload object or buckat are null");
                    return false;
                }

                upload_object.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ);
                s3service.putObject(upload_bucket, upload_object);
            }
        } catch (Exception e) {
            log.error("Error uploading transformations in hospies service: " + e.getMessage());
            return false;
        }

        return true;
    }

    /**
     * publish the diferent files in the profile "profile" to remote repository -
     * manifest - current - playlist - video list
     * 
     * @param manifest
     *          manifest to publish
     * @param playlist
     *          playlist file to publish
     * @param videos
     *          videos file to publish
     * @param profile
     *          profile which update
     * @return the HTML code of the operation
     */
    private int publishUpdate(String manifest, List<String> playlist, String videos, String profile,
            String p_code) {

        /* upload objects */
        try {

            /*
             * upload the files of a media update, those are the manifest, the
             * playlist, the videos to download and the update manifest.
             */
            log.info("HOSPIES: start to upload");
            uploadObject(base_manifest + profile + "-" + p_code + ".xml", manifest);
            log.info("HOSPIES: manifest uploaded");
            /*
             * upload playslit. If the format is a playlist per day, has to upload
             * seven playlist, one if not
             */
            int count = 0;
            ListIterator<String> playlists = playlist.listIterator();
            while (playlists.hasNext()) {
                log.info("HOSPIES playlist: " + playlists.next());
                count++;
            }
            log.info("HOSPIES count: " + String.valueOf(count));
            if (count > 1) {
                count = 0;
                playlists = playlist.listIterator();
                while (playlists.hasNext()) {
                    log.info("HOSPIES count 2 : " + String.valueOf(count));
                    uploadObject(base_playlist + profile + "-" + p_code + "_" + String.valueOf(count) + ".smil",
                            playlists.next());
                    log.info("HOSPIES uploading: " + base_playlist + profile + "-" + p_code + "_"
                            + String.valueOf(count) + ".smil");
                    count++;
                }
            } else {
                uploadObject(base_playlist + profile + "-" + p_code + ".smil", playlist.get(0));
                log.info("HOSPIES uploading: " + base_playlist + profile + "-" + p_code + ".smil");
            }

            uploadObject(base_videos + profile + "-" + p_code + ".txt", videos);
            log.info("HOSPIES uploading videos.txt");
            uploadObject(base_current + profile, manifest);
            log.info("HOSPIES uploading manifest base.txt");
        } catch (NoSuchAlgorithmException e) {
            log.error("Error sending publish files NoSuchAlgorithmException: " + e.getMessage());
            return 500;
        } catch (IOException e) {
            log.error("Error sending publish files IOException: " + e.getMessage());
            return 500;
        } catch (S3ServiceException e) {
            log.error("Error sending publish files: " + e.getMessage());
            return 500;
        }
        return 200;
    }

    /**
     * upload an object with public read permissions
     * 
     * @param key
     *          the name of the object
     * @param content
     *          the content of the object
     * @return true if success,false in other case
     * @throws S3ServiceException
     * @throws IOException
     * @throws NoSuchAlgorithmException
     */
    private boolean uploadObject(String key, String content)
            throws S3ServiceException, IOException, NoSuchAlgorithmException {

        S3Bucket upload_bucket = s3service.getBucket(hospbucket);
        S3Object upload_object = new S3Object(upload_bucket, key, content);

        /* if there's an error, exit with errors */
        if (upload_object == null || upload_bucket == null) {
            log.error("Error, upload object or buckat are null");
            return false;
        }
        /* set the access control list to public read */
        upload_object.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ);

        /* upload */
        s3service.putObject(upload_bucket, upload_object);

        return true;

    }

    /**
     * create a playlist with the format of the IES canal hospitalario players
     * 
     * @param transformations
     *          a list of transformations(files) to include in the playlist
     * @return the content of the playlist in a string
     */
    private List<String> createPlaylist(ArrayList<String> transformations, Node contentNode) {

        String repcount = "1";
        List<String> resultout = new ArrayList<String>();

        if (daily_playlist == 0) {
            String playlistout = playlist_head;
            ListIterator<String> it = transformations.listIterator();
            while (it.hasNext()) {
                playlistout += "          <video fit=\"fill\" src=\"/var/media/" + it.next() + "\" repCount=\""
                        + repcount + "\" region=\"background\" />\n";
            }
            playlistout += playlist_foot;
            resultout.add(playlistout);
        } else {
            List<List<String>> trans_content = getTransformationsListByContents(contentNode);
            ListIterator<List<String>> contentsit = trans_content.listIterator();
            String playout = playlist_head;
            log.info("HOSPIES generating playlists");
            while (contentsit.hasNext()) {
                ListIterator<String> content = contentsit.next().listIterator();
                playout = playlist_head;
                log.info("HOSPIES generating playlists loop 1");
                while (content.hasNext()) {
                    log.info("HOSPIES generating playlists loop 2");
                    playout += "          <video fit=\"fill\" src=\"/var/media/" + content.next() + "\" repCount=\""
                            + repcount + "\" region=\"background\" />\n";
                }
                playout += playlist_foot;
                resultout.add(playout);
            }
        }
        return resultout;
    }

    /**
     * search around the nodes, return a list with all the transformations names
     * 
     * @param itnode
     *          the contents iterator
     * @return a list with filenames of transformations
     */
    private ArrayList<String> getTransformationsList(NodeIterator itnode) {

        ArrayList<String> listout = new ArrayList<String>();
        NodeIterator sourcenodes = null;
        Node source = null;
        Node actualContent = null;

        while (itnode.hasNext()) {
            /* iterate into the contents */

            actualContent = itnode.nextNode();

            try {
                sourcenodes = actualContent.getNode("sources").getNodes();
            } catch (RepositoryException e1) {
                log.error("Error getting the source nodes of a content in getTransformationsList: "
                        + e1.getMessage());
                return null;
            }
            String filename = "";
            while (sourcenodes.hasNext()) {
                /* for each content iterate into sources */
                source = sourcenodes.nextNode();

                try {
                    if (source.getNode("transformations").hasNode(transformation_name) == true) {

                        /* if the source has the right transformation we add it */
                        filename = source.getNode("transformations").getNode(transformation_name)
                                .getProperty("file").getString();
                        if ("".compareToIgnoreCase(filename) != 0)
                            listout.add(source.getNode("transformations").getNode(transformation_name)
                                    .getProperty("file").getString());
                    } else {
                        /*
                         * if there is no "transformation_name" transformation, continue to
                         * next source
                         */
                    }
                } catch (PathNotFoundException e) {
                } catch (RepositoryException e) {
                }
            }
        }
        return listout;
    }

    /**
     * search around the nodes, return a list with all the transformations names
     * 
     * @param contentNode
     *          content who get brothers and their transformations
     * @return a list with a list of transformations
     */
    private List<List<String>> getTransformationsListByContents(Node contentNode) {

        List<List<String>> listout = new ArrayList<List<String>>();
        NodeIterator sourcenodes = null;
        Node source = null;
        Node actualContent = null;
        NodeIterator itnode;
        try {
            itnode = contentNode.getParent().getNodes();
        } catch (ItemNotFoundException e2) {
            log.error("HOSPIES ERROR getting content nodes ItemNotFoundException : " + e2.getMessage());
            return new ArrayList<List<String>>();
        } catch (AccessDeniedException e2) {
            log.error("HOSPIES ERROR getting content nodes AccessDeniedException : " + e2.getMessage());
            return new ArrayList<List<String>>();
        } catch (RepositoryException e2) {
            log.error("HOSPIES ERROR getting content nodes RepositoryException : " + e2.getMessage());
            return new ArrayList<List<String>>();
        }

        while (itnode.hasNext()) {
            /* iterate into the contents */
            List<String> listcontent = new ArrayList<String>();
            actualContent = itnode.nextNode();

            try {
                sourcenodes = actualContent.getNode("sources").getNodes();
            } catch (RepositoryException e1) {
                log.error("Error getting the source nodes of a content in getTransformationsList: "
                        + e1.getMessage());
                return null;
            }
            String filename = "";
            while (sourcenodes.hasNext()) {
                /* for each content iterate into sources */
                source = sourcenodes.nextNode();

                try {
                    if (source.getNode("transformations").hasNode(transformation_name) == true) {

                        /* if the source has the right transformation we add it */
                        filename = source.getNode("transformations").getNode(transformation_name)
                                .getProperty("file").getString();
                        if ("".compareToIgnoreCase(filename) != 0)
                            listcontent.add(source.getNode("transformations").getNode(transformation_name)
                                    .getProperty("file").getString());
                    } else {
                        /*
                         * if there is no "transformation_name" transformation, continue to
                         * next source
                         */
                    }
                } catch (PathNotFoundException e) {
                } catch (RepositoryException e) {
                }
            }
            listout.add(listcontent);
        }
        return listout;
    }

    /**
     * check the availability of the objectlist in the remote repository
     * 
     * @param objectList
     * @return the html code with the result
     */
    private int checkTransformationsAvailability(ArrayList<String> localobjectList) {

        try {
            S3Bucket s3_bucket = s3service.getBucket(hospbucket);
            ListIterator<String> localobit = localobjectList.listIterator();
            S3Object[] remote_objects = s3service.listObjects(s3_bucket);

            boolean found = false;
            while (localobit.hasNext()) {
                found = false;
                String localob = localobit.next();
                if (!localob.endsWith("mp4"))
                    continue;
                for (int i = 0; i < remote_objects.length; i++) {
                    if (localob.compareTo(remote_objects[i].getKey()) == 0) {
                        found = true;
                        continue;
                    }
                }
                if (!found) {
                    log.error("Error, " + localob + " isn't in remote server, interrupting publishing.");
                    return 404;
                }
            }
        } catch (S3ServiceException e) {
            log.error("Error gettings objects form bucket " + hospbucket + " : " + e.getMessage());
            return 500;
        }
        return 200;
    }

    /**
     * download the current manifest and get the upgrade code
     * 
     * @return the code of the actual upgrade
     * 
     */
    private String getActualUpgradeCode(String profile) {
        /* make http connection */
        if (!checkProfileExist(profile))
            return null;

        /* get the document from S3 */
        InputStream body = null;

        HttpClient client = new HttpClient();
        GetMethod getm = new GetMethod("http://" + hospbucket + ".s3.amazonaws.com/" + base_current + profile);
        try {
            client.executeMethod(getm);
        } catch (HttpException e) {
            log.error("HttpException getting actual upgrade code: " + e.getMessage());
            return null;
        } catch (IOException e) {
            log.error("IOException getting actual upgrade code: " + e.getMessage());
            return null;
        }

        try {
            body = getm.getResponseBodyAsStream();
        } catch (IOException e) {
            log.error("IOException getting actual upgrade body code: " + e.getMessage());
            return null;
        }

        /* parse the xml document and get the upgrade tag */
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db;
        try {
            db = dbf.newDocumentBuilder();
            Document doc = db.parse(body);
            doc.getDocumentElement().normalize();
            NodeList nodeLst = doc.getElementsByTagName("upgrade");
            getm.releaseConnection();

            if (nodeLst.getLength() != 1) {
                log.error("nodeLst.getLength() != 1  , aborting...");
                return null;
            }

            Element ele = (Element) nodeLst.item(0);
            getm.releaseConnection();
            return ele.getTextContent();

        } catch (ParserConfigurationException e) {
            log.error("ParserConfigurationException parsing actual upgrade body code: " + e.getMessage());

        } catch (IOException e) {
            log.error("IOException parsing actual upgrade body code: " + e.getMessage());

        } catch (SAXException e) {
            log.error("SAXException parsing actual upgrade body code: " + e.getMessage());

        }
        getm.releaseConnection();
        return null;
    }

    /**
     * create the manifest for the contents
     * 
     * @return the String of the manifest
     */
    private String createManifest(String profile) {
        /*
         * the childs are manifest,upgrade y update
         */
        String maniout = "";

        try {
            maniout = manifest_head;
            maniout += "\t<manifest>" + getCodeForPublishing() + "</manifest>\n";
            maniout += "\t<update>" + getCodeForPublishing() + "</update>\n";
            maniout += "\t<upgrade>" + getActualUpgradeCode(profile) + "</upgrade>\n";
            maniout += manifest_foot;

        } catch (Exception e) {
            log.error("Error generating manifest: " + e.getMessage());
            return null;
        }
        return maniout;
    }

    /**
     * create the video list to download
     * 
     * @param objectList
     *          object to include in the list
     * @return the content of the file
     */
    private String createVideoList(ArrayList<String> objectList) {
        ListIterator<String> listit = null;
        String listout = null;

        try {
            listit = objectList.listIterator();
            listout = "";

            while (listit.hasNext()) {
                listout += listit.next() + "\n";
            }
        } catch (Exception e) {
            log.error("Error generating video list: " + e.getMessage());
            return null;
        }
        return listout;
    }

    /**
     * generate from the date the code for publishing it is generated with:
     * MMddhhmmyyyy
     * 
     * @return a string with the publishing code
     */
    private String getCodeForPublishing() {
        DateFormat sdf = new SimpleDateFormat("MMddhhmmyyyy");
        return sdf.format(new Date().getTime());
    }

    /**
     * check if the profile exists in the system
     * 
     * @param profile
     *          profile to check
     * @return true if exists or false in other case
     */
    private boolean checkProfileExist(String profile) {

        for (int i = 0; i < profiles.length; i++)
            if (profile.compareToIgnoreCase(profiles[i]) == 0)
                return true;
        return false;
    }

    /**
     * not used at this time
     */
    public String get_player(HttpServletRequest req, HashMap<String, Object> kwargs) {

        return null;
    }

}