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.Objects;
025
026import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
027import org.apache.maven.model.DistributionManagement;
028import org.apache.maven.project.MavenProject;
029
030/**
031 * This rule will check if a pom contains a <code>distributionManagement</code> part. This should be by best practice
032 * only defined once. It could happen that you like to check the parent as well. This can be activated by using the
033 * <code>ignoreParent</code> which is by default turned off (<code>true</code>) which means not to check the parent.
034 *
035 * @author Karl Heinz Marbaise
036 * @since 1.4
037 */
038@Named("banDistributionManagement")
039public final class BanDistributionManagement extends AbstractStandardEnforcerRule {
040
041    /**
042     * Allow using a repository entry in the distributionManagement area.
043     */
044    private boolean allowRepository = false;
045
046    /**
047     * Allow snapshotRepository entry in the distributionManagement area.
048     */
049    private boolean allowSnapshotRepository = false;
050
051    /**
052     * Allow site entry in the distributionManagement area.
053     */
054    private boolean allowSite = false;
055
056    private final MavenProject project;
057
058    @Inject
059    public BanDistributionManagement(MavenProject project) {
060        this.project = Objects.requireNonNull(project);
061    }
062
063    @Override
064    public void execute() throws EnforcerRuleException {
065
066        if (project.isExecutionRoot()) {
067            if (project.getParent() == null) {
068                // Does it make sense to check something? If yes please make a JIRA ticket for it.
069                getLog().debug("We have no parent and in the root of a build we don't check anything,");
070                getLog().debug("because that is the location where we defined maven-enforcer-plugin.");
071            } else {
072                getLog().debug("We are in the root of the execution and we have a parent.");
073
074                DistributionManagementCheck check = new DistributionManagementCheck(project);
075                executeCheck(check);
076            }
077        } else {
078            getLog().debug("We are in a deeper level.");
079            DistributionManagementCheck check = new DistributionManagementCheck(project);
080            executeCheck(check);
081        }
082    }
083
084    private void executeCheck(DistributionManagementCheck check) throws EnforcerRuleException {
085        try {
086            check.execute(isAllowRepository(), isAllowSnapshotRepository(), isAllowSite());
087        } catch (EnforcerRuleException e) {
088            if (getMessage() != null) {
089                throw new EnforcerRuleException(getMessage() + "\n" + e.getMessage(), e);
090            }
091            throw e;
092        }
093    }
094
095    public boolean isAllowRepository() {
096        return allowRepository;
097    }
098
099    public void setAllowRepository(boolean allowRepository) {
100        this.allowRepository = allowRepository;
101    }
102
103    public boolean isAllowSnapshotRepository() {
104        return allowSnapshotRepository;
105    }
106
107    public void setAllowSnapshotRepository(boolean allowSnapshotRepository) {
108        this.allowSnapshotRepository = allowSnapshotRepository;
109    }
110
111    public boolean isAllowSite() {
112        return allowSite;
113    }
114
115    public void setAllowSite(boolean allowSite) {
116        this.allowSite = allowSite;
117    }
118
119    private static class DistributionManagementCheck {
120        private DistributionManagement distributionManagement;
121
122        DistributionManagementCheck(MavenProject project) {
123            this.distributionManagement = project.getOriginalModel().getDistributionManagement();
124        }
125
126        public void execute(boolean isAllowRepository, boolean isAllowSnapshotRepository, boolean isAllowSite)
127                throws EnforcerRuleException {
128            if (hasDistributionManagement()) {
129                if (!isAllowRepository && hasRepository()) {
130                    throw new EnforcerRuleException("You have defined a repository in distributionManagement.");
131                } else if (!isAllowSnapshotRepository && hasSnapshotRepository()) {
132                    throw new EnforcerRuleException("You have defined a snapshotRepository in distributionManagement.");
133                } else if (!isAllowSite && hasSite()) {
134                    throw new EnforcerRuleException("You have defined a site in distributionManagement.");
135                }
136            }
137        }
138
139        private boolean hasRepository() {
140            return getDistributionManagement().getRepository() != null;
141        }
142
143        public DistributionManagement getDistributionManagement() {
144            return distributionManagement;
145        }
146
147        public void setDistributionManagement(DistributionManagement distributionManagement) {
148            this.distributionManagement = distributionManagement;
149        }
150
151        private boolean hasSnapshotRepository() {
152            return getDistributionManagement().getSnapshotRepository() != null;
153        }
154
155        private boolean hasSite() {
156            return getDistributionManagement().getSite() != null;
157        }
158
159        private boolean hasDistributionManagement() {
160            return getDistributionManagement() != null;
161        }
162    }
163
164    @Override
165    public String toString() {
166        return String.format(
167                "BanDistributionManagement[allowRepository=%b, allowSnapshotRepository=%b, allowSite=%b]",
168                allowRepository, allowSnapshotRepository, allowSite);
169    }
170}