org.iavante.sling.transcodingServer.impl.TranscodingManagerImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.iavante.sling.transcodingServer.impl.TranscodingManagerImpl.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.transcodingServer.impl;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.jcr.AccessDeniedException;
import javax.jcr.InvalidItemStateException;
import javax.jcr.ItemExistsException;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
import javax.jcr.ReferentialIntegrityException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.ValueFormatException;
import javax.jcr.lock.LockException;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.nodetype.NoSuchNodeTypeException;
import javax.jcr.version.VersionException;

import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthPolicy;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.sling.jcr.api.SlingRepository;
import org.iavante.sling.commons.services.JcrTools;
import org.iavante.sling.commons.services.ServiceProvider;
import org.iavante.sling.s3backend.S3BackendFactory;
import org.iavante.sling.s3backend.S3backend;
import org.iavante.sling.transcodingServer.CalendarTools;
import org.iavante.sling.transcodingServer.Capitalize;
import org.iavante.sling.transcodingServer.Constantes;
import org.iavante.sling.transcodingServer.ITranscodingManager;
import org.iavante.sling.transcodingServer.modules.*;
import org.iavante.sling.commons.distributionserver.IDistributionServer;
import org.iavante.sling.commons.services.DistributionServiceProvider;

import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.sling.commons.json.*;

/**
 * @see org.iavante.sling.transcodingServer.ITranscodingManager
 * @scr.service
 * @scr.component immediate="true" metatype="false"
 * @scr.property name="service.description"
 *               value="IAVANTE - Transcoding Server Manager"
 * @scr.property name="service.vendor" value="IAVANTE"
 * @scr.service 
 *              interface="org.iavante.sling.transcodingServer.ITranscodingManager"
 */

public class TranscodingManagerImpl implements ITranscodingManager, Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private Session session;

    /** @scr.reference */
    private SlingRepository repository;

    /** @scr.reference */
    private JcrTools jcr_tool;

    /** @scr.reference */
    DistributionServiceProvider myDSProvider = null;
    private Node rootNode;
    /** @scr.reference */
    private S3backend s3backend;

    /** @scr.reference */
    private S3BackendFactory s3_factory;

    private int QueueSize = 4;

    private boolean isWorking = false;

    private final String PENDING_PATH = "/content/components/transcodingServer/jobs/pending";

    private final String DOING_PATH = "/content/components/transcodingServer/jobs/doing";
    /**
     * Log
     */
    private static final Logger log = LoggerFactory.getLogger(TranscodingManagerImpl.class);

    private int contador = 0;

    /**
     *Initial Activation
     * 
     * @param context
     */
    protected void activate(ComponentContext context) {
        try {
            session = repository.loginAdministrative(null);
            rootNode = session.getRootNode();
            log.info("Manager Activated");

            checkFrozenDoingJobs();
        } catch (Exception e) {
            log.error("Error activating Manager");
        }

    }

    public String createJob(Node jobNode) {
        contador = contador + 1;
        isWorking = false;

        String createJobResponse = "OK.";
        String moduleResponse = "";
        String externStorage = null;
        String uploadResponse = "";
        boolean error = false;

        try {
            if (jobNode.hasProperty("target_location")) {
                String target_location = jobNode.getProperty("target_location").getString();
                if (target_location.toLowerCase().endsWith("gif")) {
                    Thread.sleep(1000);

                }
            }
        } catch (ValueFormatException e) {

            e.printStackTrace();
        } catch (PathNotFoundException e) {

            e.printStackTrace();
        } catch (RepositoryException e) {

            e.printStackTrace();
        } catch (InterruptedException e) {

            e.printStackTrace();
        }

        addTojobLog("Job ID:" + contador, jobNode);
        log.error("Starting Job " + contador);

        addTojobLog("Instantiating module", jobNode);
        log.error("Instantiating module");

        moduleResponse = instantiateModule(jobNode);

        if (!moduleResponse.toUpperCase().startsWith("OK")) {
            log.error("Error in Job " + contador + ". The dynamic Module Has failed. " + moduleResponse);
            error = true;
            createJobResponse = moduleResponse;
        }

        addTojobLog(moduleResponse, jobNode);

        // process external Storage
        if (!error) {

            try {
                externStorage = jobNode.getProperty("extern_storage_server").getValue().getString();
            } catch (ValueFormatException e) {

                e.printStackTrace();
            } catch (IllegalStateException e) {

                e.printStackTrace();
            } catch (PathNotFoundException e) {

                e.printStackTrace();
            } catch (RepositoryException e) {

                e.printStackTrace();
            }

            if (!externStorage.equals(null) && !externStorage.equals("")) {
                addTojobLog("Uploading...", jobNode);
                log.info("Uploading Job ..." + contador);
                uploadResponse = readyForUpload(jobNode);
                if (!uploadResponse.toUpperCase().startsWith("OK")) {
                    log.error("Error Uploading Job ..." + contador + ". " + uploadResponse);
                    error = true;
                    createJobResponse = uploadResponse;
                }
            }
        }

        addTojobLog(uploadResponse, jobNode);

        // process Notification
        if (!error) {
            String notificationURL = null;
            String notificationResponse = "";
            try {
                notificationURL = jobNode.getProperty("notification_url").getValue().getString();
            } catch (ValueFormatException e) {
                e.printStackTrace();
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (PathNotFoundException e) {
                e.printStackTrace();
            } catch (RepositoryException e) {
                e.printStackTrace();
            }

            if (!notificationURL.equals(null) && !notificationURL.equals("")) {
                log.info("Notificating Job" + contador);
                addTojobLog("Notificating Job...", jobNode);
                notificationResponse = readyForNotification(jobNode);
                if (!notificationResponse.toUpperCase().startsWith("OK")) {
                    log.error("Error Notificating Job" + contador + ". " + notificationResponse);
                    error = true;
                    createJobResponse = notificationResponse;
                }
                addTojobLog(notificationResponse, jobNode);
            }

        }

        isWorking = false;

        if (!error) {
            log.info("Everything was OK with Job " + contador + ". Moving to Done.");
            addTojobLog("Everything OK. Moving to Done...", jobNode);
            moveJobToDone(jobNode);

        } else {
            log.error("Error in Job " + contador + ". Moving to error. " + createJobResponse);
            addTojobLog("There was an Error. Moving to Error...", jobNode);
            moveJobToError(jobNode);
        }

        return createJobResponse;
    }

    public String readyForNotification(Node jobNode) {
        /*
         * Right Now is not necessary implement a FIFO structure to organize a
         * Queue. If you want to do it, This is the place.
         */
        String response = notificateTransformation(jobNode);
        return response;
    }

    @SuppressWarnings("unchecked")
    private String notificateTransformation(Node jobNode) {
        log.info("notificateTransformation: reading properties");
        String response = "";
        String source_location = "";
        String target_location = "";

        String notification_url = null;
        String gadUser = null;
        String gadPassword = null;
        String source_file = null;
        String target_file = null;

        HttpClient client = null;
        List authPrefs = new ArrayList(2);
        client = new HttpClient();
        Credentials defaultcreds;
        // first of all. We have to take the useful data
        try {
            // source_location-->sourcefile
            // target_location-->targetfile
            // ds_custom_props-->ds_custom_props
            source_location = jobNode.getProperty("source_location").getValue().getString();
            String[] splitedSourceLocation = source_location.split("/");
            source_file = splitedSourceLocation[splitedSourceLocation.length - 1];

            target_location = jobNode.getProperty("target_location").getValue().getString();
            String[] splitedTargetLocation = target_location.split("/");
            target_file = splitedTargetLocation[splitedTargetLocation.length - 1];

            notification_url = jobNode.getProperty("notification_url").getValue().getString();

            gadUser = Constantes.getGADuser();
            gadPassword = Constantes.getGADpassword();

            log.info("notificateTransformation: notification_url:" + notification_url);
            log.info("notificateTransformation: target_file:" + target_file);
            log.info("notificateTransformation: source_file:" + source_file);

        } catch (ValueFormatException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (PathNotFoundException e) {
            e.printStackTrace();
        } catch (RepositoryException e) {
            e.printStackTrace();
        }
        // Using the hhtp client. This has to be authenticated
        authPrefs.add(AuthPolicy.DIGEST);
        authPrefs.add(AuthPolicy.BASIC);
        defaultcreds = new UsernamePasswordCredentials(gadUser, gadPassword);
        client.getParams().setAuthenticationPreemptive(true);
        client.getState().setCredentials(AuthScope.ANY, defaultcreds);
        client.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
        // Using the POST Method
        PostMethod post_notification = new PostMethod(notification_url);
        post_notification.setDoAuthentication(true);
        NameValuePair[] data_notification = { new NameValuePair("sling:resourceType", "gad/transformation"),
                new NameValuePair("title", source_file),
                //
                new NameValuePair("file", target_file), new NameValuePair("jcr:lastModified", "") };
        post_notification.setRequestBody(data_notification);
        post_notification.setDoAuthentication(true);
        try {
            log.info("notificateTransformation: Notificating...");
            client.executeMethod(post_notification);
        } catch (HttpException e1) {
            e1.printStackTrace();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        // Response in Status
        int status = post_notification.getStatusCode();
        post_notification.releaseConnection();
        if (status == 200) {
            response = "OK. Notificated. Status =" + status;
            log.info(response);
        } else {
            response = "Error notificating. Status =" + status;
            log.error(response);
        }
        return response;
    }

    @SuppressWarnings("unchecked")
    private String notificateStatus(String mystatus, Node jobNode) {
        log.info("notificatingStatus: reading properties");
        String response = "";

        String notification_url = null;
        String gadUser = null;
        String gadPassword = null;

        HttpClient client = null;
        List authPrefs = new ArrayList(2);
        client = new HttpClient();
        Credentials defaultcreds;
        // first of all. We have to take the useful data
        try {

            notification_url = jobNode.getProperty("notification_url").getValue().getString();

            gadUser = Constantes.getGADuser();
            gadPassword = Constantes.getGADpassword();

        } catch (ValueFormatException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (PathNotFoundException e) {
            e.printStackTrace();
        } catch (RepositoryException e) {
            e.printStackTrace();
        }
        // Using the hhtp client. This has to be authenticated
        authPrefs.add(AuthPolicy.DIGEST);
        authPrefs.add(AuthPolicy.BASIC);
        defaultcreds = new UsernamePasswordCredentials(gadUser, gadPassword);
        client.getParams().setAuthenticationPreemptive(true);
        client.getState().setCredentials(AuthScope.ANY, defaultcreds);
        client.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
        // Using the POST Method
        PostMethod post_notification = new PostMethod(notification_url);
        post_notification.setDoAuthentication(true);
        NameValuePair[] data_notification = { new NameValuePair("sling:resourceType", "gad/transformation"),
                new NameValuePair("state", mystatus) };
        post_notification.setRequestBody(data_notification);
        post_notification.setDoAuthentication(true);
        try {
            log.info("notificatingStatus...");
            client.executeMethod(post_notification);
        } catch (HttpException e1) {
            e1.printStackTrace();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        // Response in Status
        int status = post_notification.getStatusCode();
        post_notification.releaseConnection();
        if (status == 200) {
            response = "OK. Notificated. Status =" + status;
            log.info(response);
        } else {
            response = "Error notificating. Status =" + status;
            log.error(response);
        }
        return response;
    }

    /**
     * Right Now is not necessary implement a FIFO structure to organize a Queue.
     * If you want to do it, This is the place. Now externalStorage is called
     * directly
     */
    public String readyForUpload(Node jobNode) {
        String response_storage = externalStorage(jobNode);
        return response_storage;
    }

    /**
     * externalStorage checks extern_storage_server property and make a
     * instantiattion of the propper IDistributionServer. Then call to tjhe method
     * upload with the temp_target_location porperty file. This method has to
     * return 200 for OK.
     * 
     * @param jobNode
     * @return
     */
    private String externalStorage(Node jobNode) {
        String response = "";
        String response_upload = "";
        boolean error = false;
        String extern_storage_server = "";
        String temp_target_location = "";
        String extern_storage_url = "";
        String ds_custom_props = "";

        // First of all we've to read the useful data
        try {
            log.error("externalStorage: ...reading properties");
            if (jobNode.hasProperty("extern_storage_server")) {
                extern_storage_server = jobNode.getProperty("extern_storage_server").getValue().getString();
            }
            if (jobNode.hasProperty("extern_storage_url")) {
                extern_storage_url = jobNode.getProperty("extern_storage_url").getValue().getString();
            }
            if (jobNode.hasProperty("temp_target_location")) {
                temp_target_location = jobNode.getProperty("temp_target_location").getValue().getString();
            }
            if (jobNode.hasProperty("ds_custom_props")) {
                ds_custom_props = jobNode.getProperty("ds_custom_props").getValue().getString();

            }

        } catch (ValueFormatException e) {

            error = true;
            e.printStackTrace();
        } catch (IllegalStateException e) {

            error = true;
            e.printStackTrace();
        } catch (PathNotFoundException e) {

            error = true;
            e.printStackTrace();
        } catch (RepositoryException e) {

            error = true;
            e.printStackTrace();
        }
        if (extern_storage_server.equals("")) {
            response = "OK. Nothing to Upload.";
            addTojobLog(" Nothing to Upload.", jobNode);
            log.error(response);
        }

        File myfile = new File(temp_target_location);

        if ((!extern_storage_server.equals("")) && (!error) && (myfile.exists())) {
            log.info("Uploading " + temp_target_location);
            log.info("Distribution Server is " + extern_storage_server.toLowerCase());

            if (!ds_custom_props.equals("") && extern_storage_server.toLowerCase().equals("s3")) {
                //
                if (log.isInfoEnabled())
                    log.info("Distribution server has customized properties and is S3");
                Map<String, String> propsMap = new HashMap<String, String>();

                try {
                    JSONObject json_props = new JSONObject(ds_custom_props);
                    Iterator props = json_props.keys();

                    while (props.hasNext()) {
                        String prop = props.next().toString();
                        String value = json_props.get(prop).toString();
                        log.error("prop:" + prop + ",value" + value);
                        propsMap.put(prop, value);
                    }

                } catch (JSONException e) {

                    e.printStackTrace();
                }

                // s3backend

                S3backend s3_backend = (S3backend) s3_factory.getService(propsMap);

                response_upload = s3_backend.upload(temp_target_location);

                // myDServer.configure(propsMap);

                log.error("_____________myDServer.configure:" + propsMap.values());
            } else {
                IDistributionServer myDServer = myDSProvider
                        .get_distribution_server(extern_storage_server.toLowerCase());
                try {
                    addTojobLog(" Uploadind Data to " + extern_storage_server.toLowerCase(), jobNode);
                    response_upload = myDServer.upload(temp_target_location);
                } catch (NullPointerException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }

            if (response_upload.equals("200")) {
                response = "OK. Uploaded.";
                log.info(response);
            } else {
                // response = 500
                response = "Error. Uploading Fail." + response_upload;
                log.error(response);
                error = true;
            }
            addTojobLog(response, jobNode);

        }

        return response;
    }

    /**
     * 
     * */
    public String notifyFinishedTask(Node jobNode) {
        // Not implemented Yet
        deleteTempFiles(jobNode);

        return null;
    }

    private String instantiateModule(Node jobNode) {
        String jobResponse = "";
        String myClase = "";

        boolean error = false;
        try {

            if (jobNode.hasProperty("executable")) {
                if (!jobNode.getProperty("executable").getValue().equals(null)) {
                    myClase = jobNode.getProperty("executable").getValue().getString();
                    myClase = Capitalize.capitalize(myClase);
                    log.info("Instantiating " + myClase + " ...");
                    Class dynamicClass = null;
                    dynamicClass = Class.forName("org.iavante.sling.transcodingServer.modules.impl." + myClase);
                    gadJobInterface job = null;
                    job = (gadJobInterface) dynamicClass.newInstance();
                    // Running the Job for The Module Instantiated
                    log.info("Starting the Job in module:" + myClase + " ...");
                    addTojobLog("(" + myClase + ")", jobNode);
                    jobResponse = job.startJob(jobNode);
                }

            }
        } catch (ValueFormatException e) {

            error = true;
            e.printStackTrace();
            return "Error.";
        } catch (PathNotFoundException e) {

            error = true;
            e.printStackTrace();
            return "Error.";
        } catch (RepositoryException e) {

            error = true;
            e.printStackTrace();
            addTojobLog("Module not found.", jobNode);

        } catch (ClassNotFoundException e) {

            error = true;
            e.printStackTrace();
            return "Error.";
        } catch (InstantiationException e) {

            error = true;
            e.printStackTrace();
            return "Error.";
        } catch (IllegalAccessException e) {

            error = true;
            e.printStackTrace();
            return "Error.";
        }
        // If some errors instantiating the Module
        // We're gonna try a generic Module called UnknowApp
        if (error) {

            try {
                myClase = "UnknownApp";
                log.error("Instantiating " + myClase + " ...");
                Class dynamicClass = null;
                dynamicClass = Class.forName("org.iavante.sling.transcodingServer.modules.impl." + myClase);
                gadJobInterface job = null;
                job = (gadJobInterface) dynamicClass.newInstance();
                // Running the Job for The Module Instantiated
                log.error("Starting the Job in module:" + myClase + " ...");
                addTojobLog("(" + myClase + ")", jobNode);
                jobResponse = job.startJob(jobNode);
            } catch (ClassNotFoundException e) {

                e.printStackTrace();
            } catch (InstantiationException e) {

                e.printStackTrace();
            } catch (IllegalAccessException e) {

                e.printStackTrace();
            }

        }

        return jobResponse;

    }

    private void moveJobToDoing(Node jobNode) {
        log.info("Moving the job to Doing ");

        try {
            Thread.sleep(300);
        } catch (InterruptedException e1) {

            e1.printStackTrace();
        }
        try {
            String path = jobNode.getPath().toString();
            String pendigPathToNode = path.substring(1);
            String[] a = pendigPathToNode.split("/");
            String doingPath = "";
            a[4] = "doing";
            for (int i = 0; i < a.length - 1; i++) {
                doingPath = doingPath + "/" + a[i];
            }
            doingPath = doingPath.substring(1);
            Node ParentDoingNode = rootNode.getNode(doingPath);
            jcr_tool.copy(jobNode, ParentDoingNode, null);
            ParentDoingNode.save();
            Node tempNode = jobNode.getParent();
            jobNode.remove();
            tempNode.save();

        } catch (RepositoryException e) {
            log.error("Moving the job to Doing. " + e);
            e.printStackTrace();
        }

    }

    private void moveJobToError(Node jobNode) {
        log.info("Moving the job to Error ");
        try {
            Thread.sleep(300);
        } catch (InterruptedException e1) {

            e1.printStackTrace();
        }
        try {
            String path = jobNode.getPath().toString();
            String doingPathToNode = path.substring(1);
            String[] a = doingPathToNode.split("/");
            String errorPath = "";
            a[4] = "error";
            for (int i = 0; i < a.length - 1; i++) {
                errorPath = errorPath + "/" + a[i];
            }
            errorPath = errorPath.substring(1);
            Node ParentErrorNode = rootNode.getNode(errorPath);
            jcr_tool.copy(jobNode, ParentErrorNode, null);
            ParentErrorNode.save();
            Node tempNode = jobNode.getParent();
            jobNode.remove();
            tempNode.save();

        } catch (RepositoryException e) {
            log.error("Error Moving the job.");
            e.printStackTrace();
        }

    }

    private void moveJobToDone(Node jobNode) {
        log.info("Moving the job to Done");
        try {
            Thread.sleep(300);
        } catch (InterruptedException e1) {

            e1.printStackTrace();
        }
        try {
            String path = jobNode.getPath().toString();
            String doingPathToNode = path.substring(1);
            String[] a = doingPathToNode.split("/");
            String donePath = "";
            a[4] = "done";

            for (int i = 0; i < a.length - 1; i++) {
                donePath = donePath + "/" + a[i];
            }
            donePath = donePath.substring(1);
            log.info("donePath:" + donePath);
            Node ParentDoneNode = rootNode.getNode(donePath);
            jcr_tool.copy(jobNode, ParentDoneNode, null);
            ParentDoneNode.save();
            Node tempNode = jobNode.getParent();
            jobNode.remove();
            tempNode.save();

        } catch (RepositoryException e) {
            log.error("Error Moving the job.");
            e.printStackTrace();

        }

    }

    public void notifyDoneJob(Node jobNode) {

        try {
            Thread.sleep(300);
        } catch (InterruptedException e1) {

            e1.printStackTrace();
        }
        log.info("Done Job Notified. Calling the nextOne...");
        addTojobLog("Done", jobNode);
        setJobState("Done", jobNode);
        notifyFinishedTask(jobNode);
        reloadPendingJobs();
    }

    public void notifyErrorJob(Node jobNode) {

        try {
            Thread.sleep(300);
        } catch (InterruptedException e1) {

            e1.printStackTrace();
        }
        log.info("Error Job Notified. Calling the nextOne...");
        setJobState("Error", jobNode);
        notifyFinishedTask(jobNode);
        reloadPendingJobs();
    }

    public void notifyPendingJob(Node jobNode) {
        /*
         * jobsProcessing = 0; maximumJobsDoing = 4;
         */
        // first of all
        // check if is a ffmpeg process

        try {
            Thread.sleep(300);
        } catch (InterruptedException e1) {

            e1.printStackTrace();
        }

        if (isJobQueable(jobNode)) {

            int numberOfFfmpeg = numberOfExecutableDoingjobs("ffmpeg");

            log.info("numberOfFfmpeg Process Running:" + numberOfFfmpeg);
            if (numberOfExecutableDoingjobs("ffmpeg") < QueueSize) {
                log.info("New job To the Doing Queue");
                moveJobToDoing(jobNode);
            } else {
                log.info("The queue is full.");
            }
        } else {
            log.info("New Job in Pending (DIRECT To DOING)");
            moveJobToDoing(jobNode);
        }
    }

    public void notifyDoingJob(Node addedNode) {

        try {
            Thread.sleep(300);
        } catch (InterruptedException e1) {

            e1.printStackTrace();
        }
        setJobState("Doing", addedNode);

        createJob(addedNode);
    }

    protected void deactivate(ComponentContext componentContext) {
        log.info("Deactivating Transcoding Manager");

    }

    private void deleteTempFiles(Node jobNode) {

        Boolean error = false;
        String temp_target_location = "";
        String temp_source_location = "";

        try {
            log.error("deleting temp Files: ...reading properties");

            if (jobNode.hasProperty("temp_target_location")) {
                temp_target_location = jobNode.getProperty("temp_target_location").getValue().getString();
                log.error("temp_target_location:" + temp_target_location);
            }

            if (jobNode.hasProperty("temp_source_location")) {
                temp_source_location = jobNode.getProperty("temp_source_location").getValue().getString();
                log.error("temp_source_location:" + temp_source_location);
            }

        } catch (ValueFormatException e) {

            error = true;
            e.printStackTrace();
        } catch (IllegalStateException e) {

            error = true;
            e.printStackTrace();
        } catch (PathNotFoundException e) {

            error = true;
            e.printStackTrace();
        } catch (RepositoryException e) {

            error = true;
            e.printStackTrace();
        }

        // deleting Files
        // It's possible that the source and the target are the same file,
        // so we're only to delete once.
        if (temp_source_location.equals(temp_target_location)) {
            log.error("Deleting: Source and Target are the same");
            deleteFile(temp_source_location);
        } else {
            // they're different files
            log.error("Deleting: Deleting 2 Files");
            deleteFile(temp_target_location);
            deleteFile(temp_source_location);

        }

    }

    private boolean isJobQueable(Node jobNode) {

        Boolean queable = false;
        String target_location = "";
        String source_location = "";
        String executable = "";

        // First of all we've to read the useful data

        try {

            if (jobNode.hasProperty("target_location")) {
                target_location = jobNode.getProperty("target_location").getValue().getString();
            }
            if (jobNode.hasProperty("source_location")) {
                source_location = jobNode.getProperty("source_location").getValue().getString();
            }
            if (jobNode.hasProperty("executable")) {
                executable = jobNode.getProperty("executable").getValue().getString();
            }

        } catch (ValueFormatException e) {

            e.printStackTrace();
            return false;

        } catch (IllegalStateException e) {

            e.printStackTrace();
            return false;

        } catch (PathNotFoundException e) {

            e.printStackTrace();
            return false;

        } catch (RepositoryException e) {

            e.printStackTrace();
            return false;

        }

        if (target_location.toLowerCase().endsWith("gif")) {
            queable = true;
        }
        if (executable.toLowerCase().equals("ffmpeg")) {
            queable = true;
        }
        return queable;

    }

    public void reloadPendingJobs() {
        try {
            // Read all pendings Jobs and notify the first one to the manager
            log.info("Reading pending Jobs...");
            session = repository.loginAdministrative(null);
            Node addedNode = session.getRootNode().getNode(PENDING_PATH.substring(1));
            NodeIterator allNodesIterator = addedNode.getNodes();

            while (allNodesIterator.hasNext()) {
                // Notify the first tone
                log.info("Notifying A Pending Job.");
                notifyPendingJob((Node) allNodesIterator.next());
            }
        } catch (PathNotFoundException e) {
            e.printStackTrace();
            log.info("Error. ");
        } catch (RepositoryException e) {
            e.printStackTrace();
        }
    }

    public int numberOfDoingjobs() {
        int doingjobs = 0;
        try {
            // Read all pendings Jobs and notify the first one to the manager

            session = repository.loginAdministrative(null);
            Node addedNode = session.getRootNode().getNode(DOING_PATH.substring(1));
            NodeIterator allNodesIterator = addedNode.getNodes();
            doingjobs = (int) allNodesIterator.getSize();
            log.info("Reading all doing Jobs Nodes..." + doingjobs);

        } catch (PathNotFoundException e) {
            e.printStackTrace();
        } catch (RepositoryException e) {
            e.printStackTrace();
        }
        return doingjobs;
    }

    public int numberOfExecutableDoingjobs(String executable) {
        int doingjobs = 0;
        try {
            // Read all pendings Jobs and notify the first one to the manager

            session = repository.loginAdministrative(null);
            Node addedNode = session.getRootNode().getNode(DOING_PATH.substring(1));
            NodeIterator allNodesIterator = addedNode.getNodes();

            while (allNodesIterator.hasNext()) {
                Node myNode = (Node) allNodesIterator.next();
                if (myNode.hasProperty("executable")) {

                    if (myNode.getProperty("executable").getString().equals(executable)) {

                        doingjobs = doingjobs + 1;
                    }

                }

            }
        } catch (PathNotFoundException e) {
            e.printStackTrace();
        } catch (RepositoryException e) {
            e.printStackTrace();
        }
        return doingjobs;
    }

    public void checkFrozenDoingJobs() {

        // Read all pendings Jobs and notify the first one to the manager
        log.info("Reading pending Jobs...");
        try {
            session = repository.loginAdministrative(null);
            Node addedNode = session.getRootNode().getNode(DOING_PATH.substring(1));
            NodeIterator allNodesIterator = addedNode.getNodes();
            while (allNodesIterator.hasNext()) {
                // Notify the first tone
                log.info("Checking Frozen Node.");
                Node doingJob = (Node) allNodesIterator.next();
                String actualDate = "";
                String nodeDate = "";
                actualDate = CalendarTools.getTimeStamp();

                nodeDate = doingJob.getProperty("timeStamp").getValue().getString();

                long timeDiff = Long.parseLong(actualDate) - Long.parseLong(nodeDate);
                // format YYYYMMDDHHMMSSmmm
                // more than 2 days will be
                // 200810192253995 - 200810212253995 = 20000000
                if (timeDiff > 20000000) {
                    log.info(doingJob.getName() + " is more tan 2 days --> Moving to Error");
                    moveJobToError(doingJob);
                }
            } // end while
        } catch (RepositoryException e1) {

            e1.printStackTrace();
        }
    }

    /**
     * 
     * This method set (or creates if dosn't exists) the property "state" in the
     * jobNode with state passed through sate param.
     * 
     * @param String
     *          new state.
     * @param jobNode
     *          Node to change the state
     */
    private void setJobState(String state, Node jobNode) {

        try {
            jobNode.setProperty("state", state);
            jobNode.save();
            String response = notificateStatus(state, jobNode);
        } catch (ValueFormatException e) {

            e.printStackTrace();
        } catch (VersionException e) {

            e.printStackTrace();
        } catch (LockException e) {

            e.printStackTrace();
        } catch (ConstraintViolationException e) {

            e.printStackTrace();
        } catch (RepositoryException e) {

            e.printStackTrace();
        }

    }

    /**
     * This method adds (or creates if dosn't exists) the property "log" in the
     * jobNode with a message.
     * 
     * @param String
     *          message to add.
     * @param jobNode
     *          Node to add the log
     */
    private void addTojobLog(String message, Node jobNode) {
        String log = "";
        try {
            if (jobNode.hasProperty("log")) {
                log = jobNode.getProperty("log").getValue().getString();
                String newLog = log.concat(", " + message);
                jobNode.setProperty("log", newLog);
                jobNode.save();

            }
        } catch (ValueFormatException e) {

            e.printStackTrace();
        } catch (IllegalStateException e) {

            e.printStackTrace();
        } catch (PathNotFoundException e) {

            e.printStackTrace();
        } catch (VersionException e) {

            e.printStackTrace();
        } catch (LockException e) {

            e.printStackTrace();
        } catch (ConstraintViolationException e) {

            e.printStackTrace();
        } catch (AccessDeniedException e) {

            e.printStackTrace();
        } catch (ItemExistsException e) {

            e.printStackTrace();
        } catch (InvalidItemStateException e) {

            e.printStackTrace();
        } catch (ReferentialIntegrityException e) {

            e.printStackTrace();
        } catch (NoSuchNodeTypeException e) {

            e.printStackTrace();
        } catch (RepositoryException e) {

            e.printStackTrace();
        }
    }

    private boolean isFFmpegJob(Node jobNode) {
        String exec = "";

        try {
            if (jobNode.hasProperty("executable")) {
                exec = jobNode.getProperty("executable").getValue().getString();
                if (exec.toUpperCase().equals("FFMPEG")) {
                    return true;
                } else {
                    return false;
                }

            }
        } catch (RepositoryException e) {

            e.printStackTrace();
            return false;
        }
        return false;
    }

    private void deleteFile(String pathtoFile) {
        log.info("Deleting..." + pathtoFile);
        // We must be sure that we're not deleting files from the input repository
        if (pathtoFile.startsWith(Constantes.getworkingDir())) {
            String fileName = pathtoFile;
            // A File object to represent the filename
            File f = new File(fileName);

            // Make sure the file or directory exists and isn't write protected
            if (!f.exists()) {
                log.info("File " + pathtoFile + " doesn't exist. ");
                throw new IllegalArgumentException("Delete: no such file or directory: " + fileName);
            }
            if (!f.canWrite()) {
                log.info("Write protected for File " + pathtoFile);
                throw new IllegalArgumentException("Delete: write protected: " + fileName);
            }
            // If it is a directory, make sure it is empty
            if (f.isDirectory()) {
                String[] files = f.list();
                if (files.length > 0) {
                    log.info("Directory not empty. It can not be deleted " + pathtoFile);
                    throw new IllegalArgumentException("Delete: directory not empty: " + fileName);
                }
            }

            // Attempt to delete it
            boolean success = f.delete();

            if (!success) {
                log.info("Some error deleting " + pathtoFile);
                throw new IllegalArgumentException("Delete: deletion failed");
            } else {
                log.info("OK. Deleted: " + pathtoFile);

            }
        } else {
            log.info("The file's not on tmp Folder so We're not going to delete " + pathtoFile);
        }

    }

    @Override
    public void startFirstPendingJob() {

    }

}