Package org.jberet.job.model

Source Code of org.jberet.job.model.StepMerger

/*
* Copyright (c) 2014 Red Hat, Inc. and/or its affiliates.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cheng Fang - Initial API and implementation
*/

package org.jberet.job.model;

import java.util.List;
import javax.batch.operations.JobStartException;

import org.jberet._private.BatchLogger;
import org.jberet.creation.ArchiveXmlLoader;

public final class StepMerger extends AbstractMerger<Step> {
    public StepMerger(final Job job, final Step child, final ClassLoader classLoader, final List<Job> loadedJobs)
            throws JobStartException {
        super(job, classLoader, loadedJobs);
        this.child = child;
        final String parentName = child.getParent();
        final String jslName = child.getJslName();
        if (jslName == null || jslName.equals("*") || jslName.equals(job.id)) {
            for (final JobElement e : job.getJobElements()) {
                if (parentName.equals(e.getId())) {
                    this.parent = (Step) e;
                    break;
                }
            }
        } else { // jslName points to a different jsl document
            final Job jobOfParentStep = ArchiveXmlLoader.loadJobXml(jslName, classLoader, loadedJobs);
            for (final JobElement e : jobOfParentStep.getJobElements()) {
                if (parentName.equals(e.getId())) {
                    this.parent = (Step) e;
                }
            }
        }
    }

    public void merge() throws JobStartException {
        checkInheritingElements(this.parent, this.parent.getId());
        if (parent.getParent() != null) {
            final StepMerger merger2 = new StepMerger(currentJob, parent, classLoader, loadedJobs);
            recordInheritingElements(merger2);
            merger2.merge();
        }

        if (child.getAttributeNext() == null) {
            child.setAttributeNext(parent.getAttributeNext());
        }
        if (child.getStartLimit() == null) {
            child.setStartLimit(parent.getStartLimit());
        }
        if (child.getAllowStartIfComplete() == null) {
            child.setAllowStartIfComplete(parent.getAllowStartIfComplete());
        }

        mergeProperties(parent, child);
        mergeListeners(parent, child);

        //merge batchlet or chunk element
        final RefArtifact parentBatchlet = parent.getBatchlet();
        final RefArtifact childBatchlet = child.getBatchlet();
        final Chunk parentChunk = parent.getChunk();
        final Chunk childChunk = child.getChunk();

        if (childChunk != null && childBatchlet == null) {  //child has chunk type
            if (parentChunk != null) {
                mergeChunk(parentChunk, childChunk);
            }
        } else if (childChunk == null && childBatchlet != null) {  //child has batchlet type
            //nothing to do. Parent and child batchlet elements may refer to different artifacts and they cannot be
            //merged in a meaninful way.
        } else if (childChunk == null) {  //if child has no batchlet or chunk, inherit from parent
            if (parentChunk != null) {
                child.setChunk(parentChunk.clone());
            } else if (parentBatchlet != null) {
                child.setBatchlet(parentBatchlet.clone());
            }
        } else //if child contains both chunk and batchlet
            BatchLogger.LOGGER.cannotContainBothChunkAndBatchlet(child.getId());
            throw new JobStartException();
        }

        //if child has no partition, use parent partition
        //if child has partition, always use child partition and ignore parent partition
        final Partition parentPartition = parent.getPartition();
        if (child.getPartition() == null && parentPartition != null) {
            child.setPartition(parentPartition.clone());
        }
        child.setParentAndJslName(null, null);
    }

    private void mergeChunk(final Chunk parentChunk, final Chunk childChunk) {
        if (childChunk.checkpointPolicy == null && parentChunk.checkpointPolicy != null) {
            childChunk.checkpointPolicy = parentChunk.checkpointPolicy;
        }
        if (childChunk.skipLimit == null && parentChunk.skipLimit != null) {
            childChunk.skipLimit = parentChunk.skipLimit;
        }
        if (childChunk.retryLimit == null && parentChunk.retryLimit != null) {
            childChunk.retryLimit = parentChunk.retryLimit;
        }
        if (childChunk.itemCount == null && parentChunk.itemCount != null) {
            childChunk.itemCount = parentChunk.itemCount;
        }
        if (childChunk.timeLimit == null && parentChunk.timeLimit != null) {
            childChunk.timeLimit = parentChunk.timeLimit;
        }

        //no properties or listeners directly under chunk
        if (childChunk.reader == null && parentChunk.reader != null) {
            childChunk.reader = parentChunk.reader.clone();
        }
        //if both parentChunk and childChunk have reader element, whether they refer to the same artifact or not,
        //do not attempt to merge them, assuming childChunk reader element overrides parentChunk reader element as a whole.

        if (childChunk.writer == null && parentChunk.writer != null) {
            childChunk.writer = parentChunk.writer.clone();
        }

        if (childChunk.processor == null && parentChunk.processor != null) {
            childChunk.processor = parentChunk.processor.clone();
        }

        if (childChunk.checkpointAlgorithm == null && parentChunk.checkpointAlgorithm != null) {
            childChunk.checkpointAlgorithm = parentChunk.checkpointAlgorithm.clone();
        }
        //childChunk and parentChunk checkpoint algorithm may refer to different artifacts that entail different properties,
        //so their properties cannot be merged in a meaningful way

        if (parentChunk.skippableExceptionClasses != null) {
            if (childChunk.skippableExceptionClasses == null) {
                //cannot assign parentSkippable directly to childChunk, since property resolution should happen independently
                childChunk.skippableExceptionClasses = parentChunk.skippableExceptionClasses.clone();
            } else if (childChunk.skippableExceptionClasses.isMerge()) {
                childChunk.skippableExceptionClasses.include.addAll(parentChunk.skippableExceptionClasses.include);
                childChunk.skippableExceptionClasses.exclude.addAll(parentChunk.skippableExceptionClasses.exclude);
            }
        }

        if (parentChunk.retryableExceptionClasses != null) {
            if (childChunk.retryableExceptionClasses == null) {
                childChunk.retryableExceptionClasses = parentChunk.retryableExceptionClasses.clone();
            } else if (childChunk.retryableExceptionClasses.isMerge()) {
                childChunk.retryableExceptionClasses.include.addAll(parentChunk.retryableExceptionClasses.include);
                childChunk.retryableExceptionClasses.exclude.addAll(parentChunk.retryableExceptionClasses.exclude);
            }
        }

        if (parentChunk.noRollbackExceptionClasses != null) {
            if (childChunk.noRollbackExceptionClasses == null) {
                childChunk.noRollbackExceptionClasses = parentChunk.noRollbackExceptionClasses.clone();
            } else if (childChunk.noRollbackExceptionClasses.isMerge()) {
                childChunk.noRollbackExceptionClasses.include.addAll(parentChunk.noRollbackExceptionClasses.include);
                childChunk.noRollbackExceptionClasses.exclude.addAll(parentChunk.noRollbackExceptionClasses.exclude);
            }
        }
    }
}
TOP

Related Classes of org.jberet.job.model.StepMerger

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.