View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.cling;
20  
21  import java.io.IOException;
22  
23  import org.apache.maven.api.cli.Invoker;
24  import org.apache.maven.api.cli.InvokerException;
25  import org.apache.maven.api.cli.InvokerRequest;
26  import org.apache.maven.api.cli.Options;
27  import org.apache.maven.api.cli.ParserException;
28  import org.codehaus.plexus.classworlds.ClassWorld;
29  
30  import static java.util.Objects.requireNonNull;
31  
32  /**
33   * The CLI "new-gen".
34   *
35   * @param <O> the options type
36   * @param <R> the request type
37   */
38  public abstract class ClingSupport<O extends Options, R extends InvokerRequest<O>> {
39      static final String CORE_CLASS_REALM_ID = "plexus.core";
40  
41      protected final ClassWorld classWorld;
42      protected final boolean classWorldManaged;
43  
44      /**
45       * Ctor that creates "managed" ClassWorld. This constructor is not used in "normal" circumstances.
46       */
47      public ClingSupport() {
48          this(new ClassWorld(CORE_CLASS_REALM_ID, Thread.currentThread().getContextClassLoader()), true);
49      }
50  
51      /**
52       * Ctor to be used when running in ClassWorlds Launcher.
53       */
54      public ClingSupport(ClassWorld classWorld) {
55          this(classWorld, false);
56      }
57  
58      private ClingSupport(ClassWorld classWorld, boolean classWorldManaged) {
59          this.classWorld = requireNonNull(classWorld);
60          this.classWorldManaged = classWorldManaged;
61      }
62  
63      /**
64       * The main entry point.
65       */
66      public int run(String[] args) throws IOException {
67          try (Invoker<R> invoker = createInvoker()) {
68              return invoker.invoke(parseArguments(args));
69          } catch (ParserException e) {
70              System.err.println(e.getMessage());
71              return 1;
72          } catch (InvokerException e) {
73              return 1;
74          } finally {
75              if (classWorldManaged) {
76                  classWorld.close();
77              }
78          }
79      }
80  
81      protected abstract Invoker<R> createInvoker();
82  
83      protected abstract R parseArguments(String[] args) throws ParserException, IOException;
84  }