001    package org.apache.maven.model.profile.activation;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *   http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import java.io.File;
023    
024    import org.apache.maven.model.Activation;
025    import org.apache.maven.model.ActivationFile;
026    import org.apache.maven.model.Profile;
027    import org.apache.maven.model.building.ModelProblemCollector;
028    import org.apache.maven.model.building.ModelProblem.Severity;
029    import org.apache.maven.model.building.ModelProblem.Version;
030    import org.apache.maven.model.building.ModelProblemCollectorRequest;
031    import org.apache.maven.model.path.PathTranslator;
032    import org.apache.maven.model.profile.ProfileActivationContext;
033    import org.codehaus.plexus.component.annotations.Component;
034    import org.codehaus.plexus.component.annotations.Requirement;
035    import org.codehaus.plexus.interpolation.AbstractValueSource;
036    import org.codehaus.plexus.interpolation.MapBasedValueSource;
037    import org.codehaus.plexus.interpolation.RegexBasedInterpolator;
038    import org.codehaus.plexus.util.StringUtils;
039    
040    /**
041     * Determines profile activation based on the existence/absence of some file.
042     * 
043     * @author Benjamin Bentmann
044     * @see ActivationFile
045     */
046    @Component( role = ProfileActivator.class, hint = "file" )
047    public class FileProfileActivator
048        implements ProfileActivator
049    {
050    
051        @Requirement
052        private PathTranslator pathTranslator;
053    
054        public FileProfileActivator setPathTranslator( PathTranslator pathTranslator )
055        {
056            this.pathTranslator = pathTranslator;
057            return this;
058        }
059    
060        public boolean isActive( Profile profile, ProfileActivationContext context, ModelProblemCollector problems )
061        {
062            Activation activation = profile.getActivation();
063    
064            if ( activation == null )
065            {
066                return false;
067            }
068    
069            ActivationFile file = activation.getFile();
070    
071            if ( file == null )
072            {
073                return false;
074            }
075    
076            String path;
077            boolean missing;
078    
079            if ( StringUtils.isNotEmpty( file.getExists() ) )
080            {
081                path = file.getExists();
082                missing = false;
083            }
084            else if ( StringUtils.isNotEmpty( file.getMissing() ) )
085            {
086                path = file.getMissing();
087                missing = true;
088            }
089            else
090            {
091                return false;
092            }
093    
094            RegexBasedInterpolator interpolator = new RegexBasedInterpolator();
095    
096            final File basedir = context.getProjectDirectory();
097    
098            if ( basedir != null )
099            {
100                interpolator.addValueSource( new AbstractValueSource( false )
101                {
102                    public Object getValue( String expression )
103                    {
104                        /*
105                         * NOTE: We intentionally only support ${basedir} and not ${project.basedir} as the latter form
106                         * would suggest that other project.* expressions can be used which is however beyond the design.
107                         */
108                        if ( "basedir".equals( expression ) )
109                        {
110                            return basedir.getAbsolutePath();
111                        }
112                        return null;
113                    }
114                } );
115            }
116            else if ( path.contains( "${basedir}" ) )
117            {
118                return false;
119            }
120    
121            interpolator.addValueSource( new MapBasedValueSource( context.getProjectProperties() ) );
122    
123            interpolator.addValueSource( new MapBasedValueSource( context.getUserProperties() ) );
124    
125            interpolator.addValueSource( new MapBasedValueSource( context.getSystemProperties() ) );
126    
127            try
128            {
129                path = interpolator.interpolate( path, "" );
130            }
131            catch ( Exception e )
132            {
133                problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
134                        .setMessage( "Failed to interpolate file location " + path + " for profile " + profile.getId() + ": " + e.getMessage() )
135                        .setLocation( file.getLocation( missing ? "missing" : "exists" ) )
136                        .setException( e ) );
137                return false;
138            }
139    
140            path = pathTranslator.alignToBaseDirectory( path, basedir );
141    
142            File f = new File( path );
143    
144            if ( !f.isAbsolute() )
145            {
146                return false;
147            }
148    
149            boolean fileExists = f.exists();
150    
151            return missing ? !fileExists : fileExists;
152        }
153    
154    }