| /* | |
| * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved. | |
| * | |
| * This program and the accompanying materials are made available under the | |
| * terms of the Eclipse Public License v. 2.0, which is available at | |
| * http://www.eclipse.org/legal/epl-2.0. | |
| * | |
| * This Source Code may also be made available under the following Secondary | |
| * Licenses when the conditions for such availability set forth in the | |
| * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, | |
| * version 2 with the GNU Classpath Exception, which is available at | |
| * https://www.gnu.org/software/classpath/license.html. | |
| * | |
| * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 | |
| */ | |
| /* | |
| * TestProgressObjectImpl.java | |
| * | |
| * Created on January 15, 2004, 10:10 AM | |
| */ | |
| import javax.enterprise.deploy.spi.status.ProgressListener; | |
| import org.glassfish.deployapi.ProgressObjectImpl; | |
| import org.glassfish.deployapi.TargetImpl; | |
| import org.glassfish.deployment.client.DeploymentFacilityFactory; | |
| import org.glassfish.deployment.client.DeploymentFacility; | |
| import org.glassfish.deployment.client.AbstractDeploymentFacility; | |
| import javax.enterprise.deploy.shared.StateType; | |
| import java.io.File; | |
| import java.io.PrintStream; | |
| import java.io.FileOutputStream; | |
| import java.io.FileNotFoundException; | |
| /** | |
| *Makes sure that the ProgressObjectImpl class functions correctly. | |
| *<p> | |
| *In particular, bug 4977764 reported that the ProgressObjectImpl class was susceptible to | |
| *concurrent update failures in the vector that holds registered progress listeners. The | |
| *fireProgressEvent method worked with the vector of listeners itself rather than a clone of the vector. | |
| *One of the listeners unregistered itself from the progress object, so when the iterator tried to | |
| *get the next element it detected the concurrent update. So, the progress object now clones the vector | |
| *temporarily in fireProgressEvent and iterates through the clone. | |
| * | |
| * @author tjquinn | |
| */ | |
| public class TestProgressObjectImpl { | |
| private static final String here = "devtests/deployment/jsr88/misc"; | |
| /** | |
| *Provides a concrete implementation of the progress object for testing. Note that the behavior being | |
| *tested is actually that of the superclass ProgressObjectImpl. | |
| */ | |
| public class MyProgressObjectImpl extends ProgressObjectImpl { | |
| public MyProgressObjectImpl(TargetImpl target) { | |
| super(target); | |
| } | |
| /** | |
| *Required by the abstract class definition but not used during testing. | |
| */ | |
| public void run() {} | |
| /** | |
| *Stands in as an operation that fires an event to registered listeners. | |
| */ | |
| public void act() { | |
| fireProgressEvent(StateType.RUNNING, "starting"); | |
| /* | |
| *This is where any real work would be done. It's useful to test with two events just in case | |
| *that would uncover any problems. | |
| */ | |
| fireProgressEvent(StateType.COMPLETED, "done"); | |
| } | |
| } | |
| /** | |
| *Adds a new listener during the event handling. | |
| */ | |
| public class MeddlingListenerAdder implements ProgressListener { | |
| public void handleProgressEvent(javax.enterprise.deploy.spi.status.ProgressEvent progressEvent) { | |
| /* | |
| *Meddle in the listener list by adding a new listener to the list. This should trigger the error | |
| *in the original version of ProgressObjectImpl but should not in the fixed version. | |
| */ | |
| TestProgressObjectImpl.this.theProgressObjectImpl.addProgressListener(new TestProgressObjectImpl.MeddlingListenerRemover()); | |
| } | |
| } | |
| /** | |
| *Removes itself as a listener during the event handling. | |
| */ | |
| public class MeddlingListenerRemover implements ProgressListener { | |
| public void handleProgressEvent(javax.enterprise.deploy.spi.status.ProgressEvent progressEvent) { | |
| /* | |
| *Meddle in the listener list by removing itself from the list. This should trigger the error | |
| *in the original version of ProgressObjectImpl but should not in the fixed version. | |
| */ | |
| TestProgressObjectImpl.this.theProgressObjectImpl.removeProgressListener(this); | |
| } | |
| } | |
| /* Local progress object implementation to be tested. */ | |
| private MyProgressObjectImpl theProgressObjectImpl; | |
| /** Creates a new instance of TestProgressObjectImpl */ | |
| public TestProgressObjectImpl() { | |
| } | |
| /** | |
| * @param args the command line arguments | |
| */ | |
| public static void main(String[] args) { | |
| TestProgressObjectImpl test = new TestProgressObjectImpl(); | |
| try { | |
| test.run(args); | |
| test.pass(); | |
| } catch (Throwable th) { | |
| th.printStackTrace(System.out); | |
| test.fail(); | |
| } | |
| } | |
| public void run(String[] args) { | |
| addNewListenerDuringEventHandling(); | |
| } | |
| /** | |
| * Tamper with the listener list by adding a new listener during event handling. | |
| */ | |
| private void addNewListenerDuringEventHandling() { | |
| /* | |
| *Create a TargetImpl just to satisfy the signature of the constructor for the progress object implementation. | |
| */ | |
| DeploymentFacility df = DeploymentFacilityFactory.getDeploymentFacility(); | |
| TargetImpl target = new TargetImpl((AbstractDeploymentFacility)df, "test", "test"); | |
| theProgressObjectImpl = new MyProgressObjectImpl(target); | |
| TestProgressObjectImpl.MeddlingListenerAdder meddlingListener1 = new TestProgressObjectImpl.MeddlingListenerAdder(); | |
| TestProgressObjectImpl.MeddlingListenerAdder meddlingListener2 = new TestProgressObjectImpl.MeddlingListenerAdder(); | |
| theProgressObjectImpl.addProgressListener(meddlingListener1); | |
| theProgressObjectImpl.addProgressListener(meddlingListener2); | |
| /* | |
| *Fire an event that will change the listener set. | |
| */ | |
| theProgressObjectImpl.act(); | |
| } | |
| private void log(String message) { | |
| System.out.println("[TestProgressObjectImpl]:: " + message); | |
| } | |
| private void pass() { | |
| log("PASSED: " + here); | |
| System.exit(0); | |
| } | |
| private void fail() { | |
| log("FAILED: " + here); | |
| System.exit(-1); | |
| } | |
| } |