/*
 * ProActive Parallel Suite(TM):
 * The Open Source library for parallel and distributed
 * Workflows & Scheduling, Orchestration, Cloud Automation
 * and Big Data Analysis on Enterprise Grids & Clouds.
 *
 * Copyright (c) 2007 - 2017 ActiveEon
 * Contact: contact@activeeon.com
 *
 * This library is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License
 * as published by the Free Software Foundation: version 3 of
 * the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 * If needed, contact us to obtain a release under GPL Version 2 or 3
 * or a different license than the AGPL.
 */
package org.ow2.proactive.scheduling.api.graphql.fetchers;

import java.util.Comparator;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.ow2.proactive.scheduler.core.db.JobData;
import org.ow2.proactive.scheduling.api.graphql.fetchers.converter.JobInputConverter;
import org.ow2.proactive.scheduling.api.graphql.fetchers.converter.JobTaskFilterInputBiFunction;
import org.ow2.proactive.scheduling.api.graphql.fetchers.cursors.JobCursorMapper;
import org.ow2.proactive.scheduling.api.graphql.schema.type.DataManagement;
import org.ow2.proactive.scheduling.api.graphql.schema.type.Job;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.base.CaseFormat;
import com.google.common.collect.ImmutableMap;

import graphql.schema.DataFetchingEnvironment;


/**
 * @author ActiveEon Team
 */
@Component
@Transactional(readOnly = true)
public class JobDataFetcher extends DatabaseConnectionFetcher<JobData, Job> {

    @Override
    public Object get(DataFetchingEnvironment environment) {

        Function<Root<JobData>, Path<? extends Number>> entityId = root -> root.get("id");

        BiFunction<CriteriaBuilder, Root<JobData>, List<Predicate[]>> criteria = new JobTaskFilterInputBiFunction(new JobInputConverter(),
                                                                                                                  environment);

        return createPaginatedConnection(environment,
                                         JobData.class,
                                         entityId,
                                         Comparator.comparingLong(JobData::getId),
                                         criteria,
                                         new JobCursorMapper());
    }

    @Override
    protected Stream<Job> dataMapping(Stream<JobData> dataStream) {
        return dataStream.parallel()
                         .map(jobData -> Job.builder()
                                            .dataManagement(DataManagement.builder()
                                                                          .globalSpaceUrl(jobData.getGlobalSpace())
                                                                          .inputSpaceUrl(jobData.getInputSpace())
                                                                          .outputSpaceUrl(jobData.getOutputSpace())
                                                                          .userSpaceUrl(jobData.getUserSpace())
                                                                          .build())
                                            .description(jobData.getDescription())
                                            .finishedTime(jobData.getFinishedTime())
                                            .genericInformation(jobData.getGenericInformation())
                                            .id(jobData.getId())
                                            .inErrorTime(jobData.getInErrorTime())
                                            .lastUpdatedTime(jobData.getLastUpdatedTime())
                                            .maxNumberOfExecution(jobData.getMaxNumberOfExecution())
                                            .name(jobData.getJobName())
                                            .numberOfFailedTasks(jobData.getNumberOfFailedTasks())
                                            .numberOfFaultyTasks(jobData.getNumberOfFaultyTasks())
                                            .numberOfFinishedTasks(jobData.getNumberOfFinishedTasks())
                                            .numberOfInErrorTasks(jobData.getNumberOfInErrorTasks())
                                            .numberOfPendingTasks(jobData.getNumberOfPendingTasks())
                                            .numberOfRunningTasks(jobData.getNumberOfRunningTasks())
                                            .onTaskError(CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE,
                                                                                   jobData.getOnTaskErrorString()))
                                            .owner(jobData.getOwner())
                                            .priority(jobData.getPriority().name())
                                            .projectName(jobData.getProjectName())
                                            .removedTime(jobData.getRemovedTime())
                                            .status(jobData.getStatus().name())
                                            .startTime(jobData.getStartTime())
                                            .submittedTime(jobData.getSubmittedTime())
                                            .totalNumberOfTasks(jobData.getTotalNumberOfTasks())
                                            // TODO Currently map the JobVariable object to a simple string (its value). Need to map the whole object later
                                            .variables(jobData.getVariables() == null ? ImmutableMap.of()
                                                                                      : jobData.getVariables()
                                                                                               .entrySet()
                                                                                               .stream()
                                                                                               .collect(Collectors.toMap(e -> e.getKey(),
                                                                                                                         e -> e.getValue()
                                                                                                                               .getValue())))
                                            .build());
    }

}

@@ -1128,16 +1128,38 @@
 l.List;%0A
+import java.util.Map;%0A
 import j
@@ -1180,32 +1180,32 @@
 ion.BiFunction;%0A
-
 import java.util
@@ -3252,45 +3252,8 @@
 ream
-.parallel()%0A                         
 .map
@@ -6198,16 +6198,63 @@
  value).
+%0A                                            //
  Need to
@@ -6336,24 +6336,16 @@
 riables(
-jobData.
 getVaria
@@ -6353,36 +6353,16 @@
 les(
-) == null ? ImmutableMap.of(
+jobData)
 )%0A  
@@ -6407,72 +6407,154 @@
     
+.build());%0A
     
+%7D%0A%0A
     
+/**%0A
      
-                             : jobData.getV
+* Transform Variables from a JobData into a simple Map.%0A     * @param jobData The jobData to retrieve the v
 ariables
 ()%0A 
@@ -6553,627 +6553,494 @@
 bles
-()
+ from
 %0A     
-                     
+* @return the Map of all variables in the form key -%3E value%0A
      
+*/%0A
     
-                                                            .entrySet()%0A                                                                                               .stream()%0A                                                                                               .collect(Collectors.toMap(e -%3E e.getKey(),%0A                                                                                                                         e -%3E e.getValue()%0A                                                                                                                               
+protected Map%3CString, String%3E getVariables(JobData jobData) %7B%0A        if (jobData.getVariables() == null %7C%7C jobData.getVariables().size() == 0) %7B%0A            return ImmutableMap.of();%0A        %7D else %7B%0A            return jobData.getVariables()%0A                          .entrySet()%0A                          .stream()%0A                          .collect(Collectors.toMap(e -%3E e.getKey(), e -%3E e.getValue()
 .get
@@ -7048,17 +7048,17 @@
 alue()))
-)
+;
 %0A       
@@ -7062,54 +7062,9 @@
     
-                                    .build());
+%7D
 %0A   

Remove the debugging stuff and refactor the code