001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.maven.enforcer.rules;
020
021import javax.inject.Inject;
022import javax.inject.Named;
023
024import java.util.ArrayList;
025import java.util.List;
026import java.util.Map;
027import java.util.Objects;
028
029import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
030import org.apache.maven.project.MavenProject;
031
032/**
033 * This rule checks that some profiles are active.
034 *
035 * @author <a href="mailto:brianf@apache.org">Brian Fox</a>
036 */
037@Named("requireActiveProfile")
038public final class RequireActiveProfile extends AbstractStandardEnforcerRule {
039
040    /** Comma separated list of profiles to check.
041     */
042    private String profiles = null;
043
044    /** If all profiles must be active. If false, only one must be active
045     */
046    private boolean all = true;
047
048    private final MavenProject project;
049
050    @Inject
051    public RequireActiveProfile(MavenProject project) {
052        this.project = Objects.requireNonNull(project);
053    }
054
055    public String getProfiles() {
056        return profiles;
057    }
058
059    public void setProfiles(String profiles) {
060        this.profiles = profiles;
061    }
062
063    public boolean isAll() {
064        return all;
065    }
066
067    public void setAll(boolean all) {
068        this.all = all;
069    }
070
071    @Override
072    public void execute() throws EnforcerRuleException {
073        List<String> missingProfiles = new ArrayList<>();
074        if (profiles != null && !profiles.isEmpty()) {
075            String[] profileIds = profiles.split(",");
076            for (String profileId : profileIds) {
077                if (!isProfileActive(project, profileId)) {
078                    missingProfiles.add(profileId);
079                }
080            }
081
082            boolean fail = false;
083            if (!missingProfiles.isEmpty()) {
084                if (all || missingProfiles.size() == profileIds.length) {
085                    fail = true;
086                }
087            }
088
089            if (fail) {
090                String message = getMessage();
091                StringBuilder buf = new StringBuilder();
092                if (message != null) {
093                    buf.append(message + System.lineSeparator());
094                }
095
096                for (String profile : missingProfiles) {
097                    buf.append("Profile \"" + profile + "\" is not activated." + System.lineSeparator());
098                }
099
100                throw new EnforcerRuleException(buf.toString());
101            }
102        }
103    }
104
105    /**
106     * Checks if profile is active.
107     *
108     * @param project the project
109     * @param profileId the profile name
110     * @return <code>true</code> if profile is active, otherwise <code>false</code>
111     */
112    private boolean isProfileActive(MavenProject project, String profileId) {
113        for (Map.Entry<String, List<String>> entry :
114                project.getInjectedProfileIds().entrySet()) {
115            if (entry.getValue().contains(profileId)) {
116                return true;
117            }
118        }
119        return false;
120    }
121
122    @Override
123    public String toString() {
124        return String.format("RequireActiveProfile[message=%s, profiles=%s, all=%b]", getMessage(), profiles, all);
125    }
126}