blob: ad0e7bc12c2cc76e9b6942296aec97584cf3ebe1 [file] [log] [blame]
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();
}
}