/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
/**
* This class acts as a sink for ProgressObject. It registers itself
* as ProgressObject listener for multiple deployment actions and
* tunnel all events to registered ProgressObject listener.
*<p>
*Whenever this class receives a progress event from one of its sources (one of the deploymentFacility
*actions) it forwards that event on to the sink's listeners, changing the state of the event to
*"running." Then, after the sink receives the completion or failure event from the last source,
*it forwards that event as running (as it had all earlier events) and then sends one final
*aggregate completion or failure event.
*<p>
*The sink always follows this pattern, even if it encapsulates only a single source. JSR88 clients should
*be aware of this behavior.
*
* @author Jerome Dochez
*/
/* aggregate state starts as successful and is changed only if at least one source operation fails */
new LocalStringManagerImpl(ProgressObjectSink.class);
private boolean completedStatusReady = false;
/**
* register to a new ProgressObject for ProgressEvent notifications
*/
/*
*The following two statements must appear in the order shown. Otherwise, a race condition can exist.
*/
source.addProgressListener(this);
}
/**
* receives notification of a progress event from one of our
* registered interface.
*/
// we intercept all events...
if (!forwardedDS.isRunning()) {
// this mean we are either completed or failed...
if (forwardedDS.isFailed()) {
/*
*Once at least one operation fails, we know that the aggregate state will have
*to be failed.
*/
}
// since this is the completion event
// we are done with that progress listener;
if (source instanceof ProgressObject) {
po.removeProgressListener(this);
if (forwardedDS.isCompleted()) {
}
}
} else {
"enterprise.deployment.client.noprogressobject",
"Progress event does not contain a ProgressObject source"
));
}
/*
*Update the completionStatus by adding a stage to it and recording the completion
*of this event as the newest stage.
*/
// now we change our event state to running. We always forward every event from a
// source to the listeners with "running" status because the sink is not yet completely
// finished. We will also send a final aggregate completion event
// if this is a completion event from our last source (see below).
} else {
// This is a "running" event from one of our sources, so we just need to swap the source...
}
// we need to fire the received event to our listeners
synchronized(registeredPL) {
/*
*If we are done with all of our sources, let's wrap up by creating a final event that will
*be broadcast to the listeners along with the forwarded event. Also create the completed status
*that meets the requirements of the JESProgressObject interface.
*/
"enterprise.deployment.client.aggregatefailure",
"At least one operation failed"
));
} else {
"enterprise.deployment.client.aggregatesuccess",
"All operations completed successfully"
));
}
}
}
}
/*
*Send the final event if there is one.
*/
if (finalEvent != null) {
}
}
}
/**
* Register a new ProgressListener
* @param the new listener instance
*/
synchronized(registeredPL) {
// now let's deliver all the events we already received.
}
}
}
/**
* removes a ProgressListener from our list of listeners
* @param the ProgressListener to remove
*/
}
public javax.enterprise.deploy.spi.status.ClientConfiguration getClientConfiguration(TargetModuleID targetModuleID) {
// since we are never called upon deploying, I don't
// have to deal with this at this time.
return null;
}
} else {
}
return status;
}
return ids;
}
public boolean isCancelSupported() {
// if only one of our sources does not support cancel, we don't
if (!source.isCancelSupported()) {
return false;
}
}
return true;
}
public boolean isStopSupported() {
// if only one of our sources does not support stop, we don't
if (!source.isStopSupported()) {
return false;
}
}
return true;
}
if (!isCancelSupported()) {
throw new OperationUnsupportedException("cancel");
}
}
}
if (!isStopSupported()) {
throw new OperationUnsupportedException("stop");
}
}
}
}
private void prepareCompletedStatus() {
/*
*The substages may have status values of success when in fact a warning is present
*in a substage. Traverse all the substages, composing the true aggregate state and
*message based on the most severe state that is present in the entire stage tree.
*/
completedStatusReady = true;
}
private Status aggregateStages(Status worstStatusSoFar, StringBuffer msgs, DFDeploymentStatus stage) {
/*
*Starting with the stage passed in, see if its severity is more urgent than that seen so far.
*If so, then discard the messages accumulated so far for the less urgent severity and save
*this stage's message and severity as the worst seen so far.
*/
}
/*
*If the stage's severity is the same as the currently worst seen, then add this stage's message
*to the aggregate message.
*/
if (stageStatus == worstStatusSoFar) {
}
/*
*Now, do the same for each substage.
*/
}
return worstStatusSoFar;
}
/**
*Report completed status for deploytool.
*@return null if not completed, or the DFDeploymentStatus set to reflect the completion
*/
if (completedStatusReady) {
}
return answer;
}
/*
*If the status passed in is already a backend.DeploymentStatus then add it as a new stage to the
*completed status. Otherwise, create a new backend.DeploymentStatus, fill it in as much as
*possible, and add it as the next stage.
*/
if (ds instanceof DeploymentStatusImpl) {
} else {
/*
*Create a new status stage and add it to the completed status.
*/
/*
*The new state status depends on the DeploymentStatus outcome.
*/
int stageStatus = -1;
}
if (newStageStatus != null) {
/*
*Update the final status state if this new stage's state is worse than the final status's
*current state.
*/
/*
*The status being reported may say it is successful but there could be warnings in substages
*(or substages of substages...). So the truly final state and message for the completed
*status is determined once, after the last source of events is removed.
*/
} else {
}
}
if (ds.isCompleted()) {
/*
*The deployment status for this source was successful.
*/
msgKey = "enterprise.deployment.client.action_completed";
} else {
/*
*The deployment status for this source failed.
*/
msgKey = "enterprise.deployment.client.action_failed";
}
}
}