View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.shared.release.transform.jdom2;
20  
21  import java.util.ArrayList;
22  import java.util.Collections;
23  import java.util.List;
24  import java.util.Properties;
25  
26  import org.apache.maven.model.Build;
27  import org.apache.maven.model.Dependency;
28  import org.apache.maven.model.DependencyManagement;
29  import org.apache.maven.model.Model;
30  import org.apache.maven.model.Parent;
31  import org.apache.maven.model.Profile;
32  import org.apache.maven.model.Reporting;
33  import org.apache.maven.model.Scm;
34  import org.apache.maven.shared.release.phase.AbstractRewritePomsPhase;
35  import org.jdom2.Document;
36  import org.jdom2.Element;
37  import org.jdom2.Text;
38  
39  /**
40   * JDOM2 implementation of poms PROJECT element
41   *
42   * @author Robert Scholte
43   * @since 3.0
44   */
45  public class JDomModel extends Model {
46      private final Element project;
47  
48      private final JDomModelBase modelBase;
49  
50      /**
51       * <p>Constructor for JDomModel.</p>
52       *
53       * @param document a {@link org.jdom2.Document} object
54       */
55      public JDomModel(Document document) {
56          this(document.getRootElement());
57      }
58  
59      /**
60       * <p>Constructor for JDomModel.</p>
61       *
62       * @param project a {@link org.jdom2.Element} object
63       */
64      public JDomModel(Element project) {
65          this.project = project;
66          this.modelBase = new JDomModelBase(project);
67      }
68  
69      @Override
70      public Build getBuild() {
71          return modelBase.getBuild();
72      }
73  
74      @Override
75      public List<Dependency> getDependencies() {
76          return modelBase.getDependencies();
77      }
78  
79      @Override
80      public DependencyManagement getDependencyManagement() {
81          return modelBase.getDependencyManagement();
82      }
83  
84      @Override
85      public Parent getParent() {
86          Element elm = getParentElement();
87          if (elm == null) {
88              return null;
89          } else {
90              // this way scm setters change DOM tree immediately
91              return new JDomParent(elm);
92          }
93      }
94  
95      private Element getParentElement() {
96          return project.getChild("parent", project.getNamespace());
97      }
98  
99      @Override
100     public List<Profile> getProfiles() {
101         Element profilesElm = project.getChild("profiles", project.getNamespace());
102         if (profilesElm == null) {
103             return Collections.emptyList();
104         } else {
105             List<Element> profileElms = profilesElm.getChildren("profile", project.getNamespace());
106 
107             List<Profile> profiles = new ArrayList<>(profileElms.size());
108 
109             for (Element profileElm : profileElms) {
110                 profiles.add(new JDomProfile(profileElm));
111             }
112 
113             return profiles;
114         }
115     }
116 
117     @Override
118     public Properties getProperties() {
119         Element properties = project.getChild("properties", project.getNamespace());
120 
121         if (properties == null) {
122             return null;
123         } else {
124             return new JDomProperties(properties);
125         }
126     }
127 
128     @Override
129     public Reporting getReporting() {
130         Element reporting = project.getChild("reporting", project.getNamespace());
131 
132         if (reporting == null) {
133             return null;
134         } else {
135             return new JDomReporting(reporting);
136         }
137     }
138 
139     @Override
140     public void setScm(Scm scm) {
141         if (scm == null) {
142             JDomUtils.rewriteElement("scm", null, project, project.getNamespace());
143         } else {
144             Element scmRoot = new Element("scm");
145             scmRoot.addContent("\n  ");
146 
147             // Write current values to JDOM2 tree
148             Scm jdomScm = new JDomScm(scmRoot);
149             jdomScm.setConnection(scm.getConnection());
150             jdomScm.setDeveloperConnection(scm.getDeveloperConnection());
151             jdomScm.setTag(scm.getTag());
152             jdomScm.setUrl(scm.getUrl());
153 
154             project.addContent("\n  ").addContent(scmRoot).addContent("\n");
155         }
156     }
157 
158     @Override
159     public Scm getScm() {
160         Element elm = project.getChild("scm", project.getNamespace());
161         if (elm == null) {
162             return null;
163         } else {
164             // this way scm setters change DOM tree immediately
165             return new JDomScm(elm);
166         }
167     }
168 
169     @Override
170     public void setVersion(String version) {
171         Element versionElement = project.getChild("version", project.getNamespace());
172 
173         String parentVersion;
174         Element parent = getParentElement();
175         if (parent != null) {
176             parentVersion = parent.getChildTextTrim("version", project.getNamespace());
177         } else {
178             parentVersion = null;
179         }
180 
181         if (versionElement == null) {
182             // never add version when parent references CI friendly property
183             if (!(parentVersion != null && AbstractRewritePomsPhase.isCiFriendlyVersion(parentVersion))
184                     && !version.equals(parentVersion)) {
185                 // we will add this after artifactId, since it was missing but different from the inherited version
186                 Element artifactIdElement = project.getChild("artifactId", project.getNamespace());
187                 int index = project.indexOf(artifactIdElement);
188 
189                 versionElement = new Element("version", project.getNamespace());
190                 versionElement.setText(version);
191                 project.addContent(index + 1, new Text("\n  "));
192                 project.addContent(index + 2, versionElement);
193             }
194         } else {
195             if (AbstractRewritePomsPhase.isCiFriendlyVersion(versionElement.getTextNormalize())) {
196                 // try to rewrite property if CI friendly expression is used
197                 String ciFriendlyPropertyName =
198                         AbstractRewritePomsPhase.extractPropertyFromExpression(versionElement.getTextNormalize());
199                 Properties properties = getProperties();
200                 if (properties != null) {
201                     properties.computeIfPresent(ciFriendlyPropertyName, (k, v) -> version);
202                 }
203             } else {
204                 JDomUtils.rewriteValue(versionElement, version);
205             }
206         }
207     }
208 }