/**
   * Add a new Valve to the end of the pipeline associated with this Container. Prior to adding the
   * Valve, the Valve's <code>setContainer()</code> method will be called, if it implements <code>
   * Contained</code>, with the owning Container as an argument. The method may throw an <code>
   * IllegalArgumentException</code> if this Valve chooses not to be associated with this Container,
   * or <code>IllegalStateException</code> if it is already associated with a different Container.
   *
   * @param valve Valve to be added
   * @exception IllegalArgumentException if this Container refused to accept the specified Valve
   * @exception IllegalArgumentException if the specified Valve refuses to be associated with this
   *     Container
   * @exception IllegalStateException if the specified Valve is already associated with a different
   *     Container
   */
  public void addValve(GlassFishValve valve) {

    if (firstTcValve != null) {
      // Wrap GlassFish-style valve inside Tomcat-style valve
      addValve(new TomcatValveAdapter(valve));
      return;
    }

    // Validate that we can add this Valve
    if (valve instanceof Contained) ((Contained) valve).setContainer(this.container);

    // Start the new component if necessary
    if (started) {
      if (valve instanceof Lifecycle) {
        try {
          ((Lifecycle) valve).start();
        } catch (LifecycleException e) {
          log.log(Level.SEVERE, ADD_VALVE_EXCEPTION, e);
        }
      }
      /**
       * CR 6411114 (MBean registration moved to ValveBase.start()) // Register the newly added
       * valve registerValve(valve);
       */
    }

    // Add this Valve to the set associated with this Pipeline
    GlassFishValve results[] = new GlassFishValve[valves.length + 1];
    System.arraycopy(valves, 0, results, 0, valves.length);
    results[valves.length] = valve;
    valves = results;
  }
 /**
  * Return the set of Valves in the pipeline associated with this Container, including the basic
  * Valve (if any). If there are no such Valves, a zero-length array is returned.
  */
 public GlassFishValve[] getValves() {
   if (basic == null) {
     return (valves);
   }
   GlassFishValve results[] = new GlassFishValve[valves.length + 1];
   System.arraycopy(valves, 0, results, 0, valves.length);
   results[valves.length] = basic;
   return (results);
 }
  /**
   * Return the set of Valves in the pipeline associated with this Container, including the basic
   * Valve (if any). If there are no such Valves, a zero-length array is returned.
   */
  public Valve[] getValves() {

    if (basic == null) return (valves);
    synchronized (valves) {
      Valve results[] = new Valve[valves.length + 1];
      System.arraycopy(valves, 0, results, 0, valves.length);
      results[valves.length] = basic;
      return (results);
    }
  }
 @Override
 public void addValve(Valve valve) {
   if (valve instanceof Contained) {
     ((Contained) valve).setContainer(this.container);
   }
   synchronized (valves) {
     Valve results[] = new Valve[valves.length + 1];
     System.arraycopy(valves, 0, results, 0, valves.length);
     results[valves.length] = valve;
     valves = results;
   }
 }
  /**
   * Add a new Valve to the end of the pipeline associated with this Container. Prior to adding the
   * Valve, the Valve's <code>setContainer()</code> method will be called, if it implements <code>
   * Contained</code>, with the owning Container as an argument. The method may throw an <code>
   * IllegalArgumentException</code> if this Valve chooses not to be associated with this Container,
   * or <code>IllegalStateException</code> if it is already associated with a different Container.
   *
   * @param valve Valve to be added
   * @throws IllegalArgumentException if this Container refused to accept the specified Valve
   * @throws IllegalArgumentException if the specifie Valve refuses to be associated with this
   *     Container
   * @throws IllegalStateException if the specified Valve is already associated with a different
   *     Container
   */
  public void addValve(Valve valve) {

    // Validate that we can add this Valve
    if (valve instanceof Contained) ((Contained) valve).setContainer(this.container);

    // Start the new component if necessary
    if (started && (valve instanceof Lifecycle)) {
      try {
        ((Lifecycle) valve).start();
      } catch (LifecycleException e) {
        log("StandardPipeline.addValve: start: ", e);
      }
    }

    // Add this Valve to the set associated with this Pipeline
    synchronized (valves) {
      Valve results[] = new Valve[valves.length + 1];
      System.arraycopy(valves, 0, results, 0, valves.length);
      results[valves.length] = valve;
      valves = results;
    }
  }
  public static void main(String[] args) {

    System.setProperty("catalina.base", System.getProperty("user.dir"));
    Connector connector = new HttpConnector();

    Wrapper wrapper1 = new StandardWrapper();
    wrapper1.setName("Primitive");
    wrapper1.setServletClass("PrimitiveServlet");
    Wrapper wrapper2 = new StandardWrapper();
    wrapper2.setName("Modern");
    wrapper2.setServletClass("ModernServlet");

    Context context = new StandardContext();
    // StandardContext's start method adds a default mapper
    context.setPath("/app1");
    context.setDocBase("app1");

    context.addChild(wrapper1);
    context.addChild(wrapper2);

    LifecycleListener listener = new SimpleContextConfig();
    ((Lifecycle) context).addLifecycleListener(listener);

    Host host = new StandardHost();
    host.addChild(context);
    host.setName("localhost");
    host.setAppBase("webapps");

    Loader loader = new WebappLoader();
    context.setLoader(loader);
    // context.addServletMapping(pattern, name);
    context.addServletMapping("/Primitive", "Primitive");
    context.addServletMapping("/Modern", "Modern");

    Engine engine = new StandardEngine();
    engine.addChild(host);
    engine.setDefaultHost("localhost");

    Service service = new StandardService();
    service.setName("Stand-alone Service");
    Server server = new StandardServer();
    server.addService(service);
    service.addConnector(connector);

    // StandardService class's setContainer will call all its connector's setContainer method
    service.setContainer(engine);

    // Start the new server
    if (server instanceof Lifecycle) {
      try {
        server.initialize();
        ((Lifecycle) server).start();
        server.await();
        // the program waits until the await method returns,
        // i.e. until a shutdown command is received.
      } catch (LifecycleException e) {
        e.printStackTrace(System.out);
      }
    }

    // Shut down the server
    if (server instanceof Lifecycle) {
      try {
        ((Lifecycle) server).stop();
      } catch (LifecycleException e) {
        e.printStackTrace(System.out);
      }
    }
  }