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.internal.impl;
20  
21  import javax.inject.Inject;
22  import javax.inject.Named;
23  import javax.inject.Singleton;
24  
25  import java.util.ArrayList;
26  import java.util.Map;
27  import java.util.concurrent.ConcurrentHashMap;
28  
29  import org.apache.maven.api.DependencyProperties;
30  import org.apache.maven.api.Type;
31  import org.apache.maven.api.annotations.Nonnull;
32  import org.apache.maven.api.services.TypeRegistry;
33  import org.apache.maven.artifact.handler.ArtifactHandler;
34  import org.apache.maven.artifact.handler.manager.LegacyArtifactHandlerManager;
35  import org.apache.maven.eventspy.AbstractEventSpy;
36  import org.apache.maven.execution.ExecutionEvent;
37  
38  import static org.apache.maven.internal.impl.Utils.nonNull;
39  
40  @Named
41  @Singleton
42  public class DefaultTypeRegistry extends AbstractEventSpy implements TypeRegistry {
43      private final Map<String, Type> types;
44  
45      private final ConcurrentHashMap<String, Type> usedTypes;
46  
47      private final ConcurrentHashMap<String, Type> legacyTypes;
48  
49      private final LegacyArtifactHandlerManager manager;
50  
51      @Inject
52      public DefaultTypeRegistry(Map<String, Type> types, LegacyArtifactHandlerManager manager) {
53          this.types = nonNull(types, "types");
54          this.usedTypes = new ConcurrentHashMap<>();
55          this.legacyTypes = new ConcurrentHashMap<>();
56          this.manager = nonNull(manager, "artifactHandlerManager");
57      }
58  
59      @Override
60      public void onEvent(Object event) {
61          if (event instanceof ExecutionEvent) {
62              ExecutionEvent executionEvent = (ExecutionEvent) event;
63              if (executionEvent.getType() == ExecutionEvent.Type.SessionEnded) {
64                  usedTypes.clear();
65                  legacyTypes.clear();
66              }
67          }
68      }
69  
70      @Override
71      @Nonnull
72      public Type getType(String id) {
73          nonNull(id, "id");
74          return usedTypes.computeIfAbsent(id, i -> {
75              Type type = types.get(id);
76              if (type == null) {
77                  // legacy types ALWAYS return type (AHM never returns null)
78                  type = legacyTypes.computeIfAbsent(id, k -> {
79                      // Copy data as the ArtifactHandler is not immutable, but Type should be.
80                      ArtifactHandler handler = manager.getArtifactHandler(id);
81                      ArrayList<String> flags = new ArrayList<>();
82                      if (handler.isAddedToClasspath()) {
83                          flags.add(DependencyProperties.FLAG_CLASS_PATH_CONSTITUENT);
84                      }
85                      if (handler.isIncludesDependencies()) {
86                          flags.add(DependencyProperties.FLAG_INCLUDES_DEPENDENCIES);
87                      }
88                      return new DefaultType(
89                              id,
90                              handler.getLanguage(),
91                              handler.getExtension(),
92                              handler.getClassifier(),
93                              new DefaultDependencyProperties(flags));
94                  });
95              }
96              return type;
97          });
98      }
99  }