001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.tomcat5.progress;
043:
044: import java.util.ArrayList;
045: import java.util.Arrays;
046: import java.util.List;
047: import javax.enterprise.deploy.shared.StateType;
048: import javax.enterprise.deploy.spi.TargetModuleID;
049: import javax.enterprise.deploy.spi.exceptions.OperationUnsupportedException;
050: import javax.enterprise.deploy.spi.status.ClientConfiguration;
051: import javax.enterprise.deploy.spi.status.DeploymentStatus;
052: import javax.enterprise.deploy.spi.status.ProgressEvent;
053: import javax.enterprise.deploy.spi.status.ProgressListener;
054: import javax.enterprise.deploy.spi.status.ProgressObject;
055: import org.openide.util.Parameters;
056:
057: /**
058: * MultiProgressObjectWrapper wraps multiple progress objects into a single one.
059: * <p>
060: * If all wrapped objects are in COMPLETED or FAILED state the state object
061: * will be changed to:
062: * <ul>
063: * <li>{@link StateType.COMPLETED} if all wrapped objects reached the COMPLETED state
064: * <li>{@link StateType.FAILED} if any of wrapped objects reached the FAILED state
065: * </ul>
066: * <p>
067: * Note that all wrapped objects have to be in COMPLETED or FAILED state to
068: * invoke the change of the state of this object. However this does not mean
069: * the events from the wrapped objects are not propagated to the listeners of
070: * this object.
071: * <p>
072: * The behaviour of {@link StateType.RELEASED} is quite unsure from JSR-88.
073: * This implementation does not consider it as end state of the ProgressObject.
074: *
075: * @author herolds
076: * @author Petr Hejl
077: */
078: public class MultiProgressObjectWrapper implements ProgressObject,
079: ProgressListener {
080:
081: private final ProgressEventSupport pes = new ProgressEventSupport(
082: this );
083:
084: private final ProgressObject[] progressObjects;
085:
086: private String message = ""; // NOI18N
087:
088: private StateType state = StateType.RUNNING;
089:
090: /** Creates a new instance of MultipleOpsProgressObject */
091: public MultiProgressObjectWrapper(ProgressObject[] objects) {
092: Parameters.notNull("progObjs", state);
093:
094: if (objects.length == 0) {
095: throw new IllegalArgumentException(
096: "At least one progress object must be passed."); // NOI18N
097: }
098:
099: progressObjects = new ProgressObject[objects.length];
100: System
101: .arraycopy(objects, 0, progressObjects, 0,
102: objects.length);
103:
104: for (int i = 0; i < objects.length; i++) {
105: ProgressObject po = objects[i];
106: // XXX unsafe publication
107: po.addProgressListener(this );
108: }
109:
110: updateState(null);
111: }
112:
113: /** JSR88 method. */
114: public ClientConfiguration getClientConfiguration(
115: TargetModuleID targetModuleID) {
116: return null; // PENDING
117: }
118:
119: /** JSR88 method. */
120: public synchronized DeploymentStatus getDeploymentStatus() {
121: DeploymentStatus ds = progressObjects[0].getDeploymentStatus();
122: // all deployment objects are supposed to be of the same action and command type
123: return new Status(ds.getAction(), ds.getCommand(), message,
124: state);
125: }
126:
127: /** JSR88 method. */
128: public TargetModuleID[] getResultTargetModuleIDs() {
129: List<TargetModuleID> returnVal = new ArrayList<TargetModuleID>();
130: for (int i = 0; i < progressObjects.length; i++) {
131: ProgressObject po = progressObjects[i];
132: if (po.getDeploymentStatus().isCompleted()) {
133: returnVal.addAll(Arrays.asList(po
134: .getResultTargetModuleIDs()));
135: }
136: }
137: return returnVal.toArray(new TargetModuleID[returnVal.size()]);
138: }
139:
140: /** JSR88 method. */
141: public boolean isCancelSupported() {
142: return false;
143: }
144:
145: /** JSR88 method. */
146: public void cancel() throws OperationUnsupportedException {
147: throw new OperationUnsupportedException(
148: "cancel not supported in Tomcat deployment"); // NOI18N
149: }
150:
151: /** JSR88 method. */
152: public boolean isStopSupported() {
153: return false;
154: }
155:
156: /** JSR88 method. */
157: public void stop() throws OperationUnsupportedException {
158: throw new OperationUnsupportedException(
159: "stop not supported in Tomcat deployment"); // NOI18N
160: }
161:
162: /** JSR88 method. */
163: public void addProgressListener(ProgressListener l) {
164: pes.addProgressListener(l);
165: }
166:
167: /** JSR88 method. */
168: public void removeProgressListener(ProgressListener l) {
169: pes.removeProgressListener(l);
170: }
171:
172: /**
173: * Handles the progress events from wrapped objects.
174: */
175: public synchronized void handleProgressEvent(
176: ProgressEvent progressEvent) {
177: updateState(progressEvent.getDeploymentStatus().getMessage());
178:
179: pes.fireHandleProgressEvent(progressEvent.getTargetModuleID(),
180: progressEvent.getDeploymentStatus());
181: }
182:
183: private synchronized void updateState(String receivedMessage) {
184: if (state == StateType.COMPLETED || state == StateType.FAILED) {
185: return;
186: }
187:
188: boolean completed = true;
189: boolean failed = false;
190:
191: for (ProgressObject progress : progressObjects) {
192: DeploymentStatus status = progress.getDeploymentStatus();
193:
194: if (status == null
195: || (!status.isCompleted() && !status.isFailed())) {
196: completed = false;
197: break;
198: }
199:
200: if (status.isFailed()) {
201: failed = true;
202: }
203: }
204:
205: if (completed) {
206: state = failed ? StateType.FAILED : StateType.COMPLETED;
207: message = receivedMessage == null ? "" : receivedMessage;
208: }
209: }
210: }
|