2016-09-16 8 views
1

У меня есть требование читать плагины в Java. Я использовал библиотеку эфира для получения зависимостей времени выполнения, компиляции зависимостей времени и т. Д. Но могу ли я использовать эфир для чтения конфигураций плагинов, основанных на файле pom?Можете ли вы получить конфигурацию плагина из POM с использованием эфира?

Что-то вроде этого

<properties> 
    <servicePort>8080</servicePort> 
    <adminPort>8081</adminPort> 
</properties> 

<build> 
    <plugins> 
    <plugin> 
     <groupId>com.company.group</groupId> 
     <artifactId>my-plugin</artifactId> 
     <version>0.1-SNAPSHOT</version> 
     <configuration> 
     <myConfig> 
      <somePropName>someProp</somePropName> 
      <portMappings> 
      <someProp>${servicePort}</someProp> 
      <someProp-admin>${adminPort}</someProp-admin> 
      </portMappings> 
     </myConfig> 
     </configuration> 
    </plugin> 
    </plugins> 
</build> 

Я хочу, чтобы быть в состоянии решить

some-Prop 8080 
some-prop-admin 8081 

из этого механизма

В настоящее время я выборки зависимостей компиляции галстука, как это

Dependency dependency = new Dependency(new DefaultArtifact(
        coordinate), COMPILE); 
CollectRequest collectRequest = new CollectRequest(); 
collectRequest.setRoot(dependency); 

collectRequest.addRepository(this.aetherSession 
     .getRemoteRepository()); 
DependencyNode node = this.aetherSession 
     .getRepoSystem() 
     .collectDependencies(this.aetherSession.getRepoSession(), 
       collectRequest).getRoot(); 
DependencyRequest dependencyRequest = new DependencyRequest(); 
dependencyRequest.setRoot(node); 
result = this.aetherSession 
     .getRepoSystem() 
     .resolveDependencies(this.aetherSession.getRepoSession(), 
       dependencyRequest).getArtifactResults(); 
FinalResult.addAll(result); 
+0

Можете ли вы опубликовать свой текущий код для получения зависимостей времени компиляции? Вы пишете плагин Maven или внешнее приложение? – Tunaki

+0

Это приложение java, я хочу прочитать конфигурацию плагина от pom, используя эфир –

ответ

0

Я не знаю, есть ли более простой способ, но вы можете использовать API Aether для разрешения интересующего вас артефакта POM, а затем построить из него модель Maven с помощью API-интерфейса Model Builder.

Прежде всего, если координаты на ваш артефакт не артефакту POM, вы должны преобразовать их в артефакт ПОМ путем создания нового DefaultArtifact с тем же GAV, но типа "pom". Чтобы разрешить артефакт, вы можете вызвать resolveArtifact в системе репозитория и получить результат с помощью getArtifact().

Как только у вас есть разрешенный артефакт, вы можете использовать maven-model-builder для создания модели Maven из файла артефакта. ModelBuilder может быть создан с использованием метода DefaultModelBuilderFactory.newInstance().

Для артефактов, имеющих родительский POM, необходимо задать ModelResolver запрос на создание модели. Тем не менее, единственная применимая реализация с Aether, которая составляет DefaultModelResolver, является закрытой для пакета внутри maven-aether-provider, поэтому нам нужно использовать API Reflection для ее создания. Необходимо ввести компоненты, которые извлекаются с помощью serviceLocator, возвращенного MavenRepositorySystemUtils.newServiceLocator(). Это должен быть тот же локатор, с которым была создана сессия эфира.

DefaultArtifact artifact = new DefaultArtifact(coordinate); 
Artifact pomArtifact = new DefaultArtifact(artifact.getGroupId(), artifact.getArtifactId(), "pom", artifact.getVersion()); 

ArtifactRequest request = new ArtifactRequest(pomArtifact, Arrays.asList(aetherSession.getRemoteRepository()), null); 
pomArtifact = aetherSession.getRepoSystem().resolveArtifact(session, request).getArtifact(); 

ModelBuilder modelBuilder = new DefaultModelBuilderFactory().newInstance(); 
ModelBuildingRequest buildingRequest = new DefaultModelBuildingRequest(); 
buildingRequest.setPomFile(pomArtifact.getFile()); 
buildingRequest.setProcessPlugins(true); 
buildingRequest.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL); 

Constructor<?> constr = Class.forName("org.apache.maven.repository.internal.DefaultModelResolver").getConstructors()[0]; 
constr.setAccessible(true); 
ModelResolver modelResolver = (ModelResolver) constr.newInstance(session, null, null, 
     serviceLocator.getService(ArtifactResolver.class), 
     serviceLocator.getService(VersionRangeResolver.class), 
     serviceLocator.getService(RemoteRepositoryManager.class), request.getRepositories()); 
buildingRequest.setModelResolver(modelResolver); 

Model model = modelBuilder.build(buildingRequest).getEffectiveModel(); 

Xpp3Dom pluginConfiguration = (Xpp3Dom) model.getBuild().getPluginsAsMap().get("com.company.group:my-plugin").getConfiguration(); 
Xpp3Dom myConfig = pluginConfiguration.getChild("myConfig"); 
System.out.println(myConfig.getChild("somePropName").getValue()); // prints "someProp" 

По умолчанию модель строитель не настроен для обработки плагинов, так что нам нужно вызвать setProcessPlugin(true). После получения эффективной модели конфигурация содержится в объекте Xpp3Dom, с помощью которого вы можете перемещаться с помощью getChild(name), чтобы получить именованный дочерний элемент XML и getValue(), чтобы получить значение элемента XML.

+0

Пытаюсь проверить вышеприведенный код, хотя он извлекает банку не pom –

+0

@user_mda Я включил код для извлечения POM, а не JAR , Посмотрите на 'Artifact pomArtifact' и' buildingRequest.setPomFile (pomArtifact.getFile()); '. – Tunaki

+0

yes Я скопировал один и тот же код, но он не смог его разобрать, так как pomArtifact.getFile() дает мне банку –