| /* |
| * 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); |
| } |
| } |