| package org.apache.maven.plugins.enforcer; |
| |
| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| import org.apache.maven.enforcer.rule.api.EnforcerRule; |
| import org.apache.maven.enforcer.rule.api.EnforcerRuleException; |
| import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper; |
| import org.apache.maven.plugin.MojoExecution; |
| import org.codehaus.plexus.classworlds.realm.ClassRealm; |
| import org.codehaus.plexus.component.configurator.ComponentConfigurator; |
| import org.codehaus.plexus.component.repository.exception.ComponentLookupException; |
| import org.codehaus.plexus.configuration.PlexusConfiguration; |
| import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration; |
| import org.codehaus.plexus.util.xml.Xpp3DomBuilder; |
| import org.codehaus.plexus.util.xml.pull.XmlPullParserException; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.nio.file.Files; |
| |
| /** |
| * An enforcer rule that will invoke rules from an external resource |
| * |
| * @author <a href="mailto:gastaldi@apache.org">George Gastaldi</a> |
| */ |
| public class ExternalRules extends AbstractNonCacheableEnforcerRule |
| { |
| private static final String LOCATION_PREFIX_CLASSPATH = "classpath:"; |
| |
| /** |
| * The external rules location. If it starts with "classpath:", the resource is read from the classpath. |
| * Otherwise, it is handled as a filesystem path, either absolute, or relative to <code>${project.basedir}</code> |
| */ |
| String location; |
| |
| public ExternalRules() |
| { |
| } |
| |
| public ExternalRules( String location ) |
| { |
| this.location = location; |
| } |
| |
| @Override |
| public void execute( EnforcerRuleHelper helper ) throws EnforcerRuleException |
| { |
| // Find descriptor |
| EnforcerDescriptor enforcerDescriptor = getEnforcerDescriptor( helper ); |
| for ( EnforcerRule rule : enforcerDescriptor.getRules() ) |
| { |
| rule.execute( helper ); |
| } |
| } |
| |
| /** |
| * Resolve the {@link EnforcerDescriptor} based on the provided {@link #descriptor} or {@link #descriptorRef} |
| * |
| * @param helper used to build the {@link EnforcerDescriptor} |
| * @return an {@link EnforcerDescriptor} for this rule |
| * @throws EnforcerRuleException if any failure happens while reading the descriptor |
| */ |
| EnforcerDescriptor getEnforcerDescriptor( EnforcerRuleHelper helper ) |
| throws EnforcerRuleException |
| { |
| try ( InputStream descriptorStream = resolveDescriptor( helper ) ) |
| { |
| EnforcerDescriptor descriptor = new EnforcerDescriptor(); |
| // To get configuration from the enforcer-plugin mojo do: |
| //helper.evaluate(helper.getComponent(MojoExecution.class).getConfiguration().getChild("fail").getValue()) |
| // Configure EnforcerDescriptor from the XML |
| ComponentConfigurator configurator = helper.getComponent( ComponentConfigurator.class, "basic" ); |
| configurator.configureComponent( descriptor, toPlexusConfiguration( descriptorStream ), helper, |
| getClassRealm( helper ) ); |
| return descriptor; |
| } |
| catch ( EnforcerRuleException e ) |
| { |
| throw e; |
| } |
| catch ( Exception e ) |
| { |
| throw new EnforcerRuleException( "Error while enforcing rules", e ); |
| } |
| } |
| |
| private InputStream resolveDescriptor( EnforcerRuleHelper helper ) |
| throws ComponentLookupException, EnforcerRuleException |
| { |
| InputStream descriptorStream; |
| if ( location != null ) |
| { |
| if ( location.startsWith( LOCATION_PREFIX_CLASSPATH ) ) |
| { |
| String classpathLocation = location.substring( LOCATION_PREFIX_CLASSPATH.length() ); |
| ClassLoader classRealm = getClassRealm( helper ); |
| descriptorStream = classRealm.getResourceAsStream( classpathLocation ); |
| if ( descriptorStream == null ) |
| { |
| throw new EnforcerRuleException( "Location '" + classpathLocation + "' not found in classpath" ); |
| } |
| } |
| else |
| { |
| File descriptorFile = helper.alignToBaseDirectory( new File( location ) ); |
| try |
| { |
| descriptorStream = Files.newInputStream( descriptorFile.toPath() ); |
| } |
| catch ( IOException e ) |
| { |
| throw new EnforcerRuleException( "Could not read descriptor in " + descriptorFile, e ); |
| } |
| } |
| } |
| else |
| { |
| throw new EnforcerRuleException( "No location provided" ); |
| } |
| return descriptorStream; |
| } |
| |
| private static PlexusConfiguration toPlexusConfiguration( InputStream descriptorStream ) |
| throws XmlPullParserException, IOException |
| { |
| return new XmlPlexusConfiguration( Xpp3DomBuilder.build( descriptorStream, "UTF-8" ) ); |
| } |
| |
| private ClassRealm getClassRealm( EnforcerRuleHelper helper ) throws ComponentLookupException |
| { |
| return helper.getComponent( MojoExecution.class ).getMojoDescriptor().getRealm(); |
| } |
| |
| } |