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.config.ReleaseDescriptor;
35  import org.apache.maven.shared.release.util.CiFriendlyVersion;
36  import org.jdom2.Document;
37  import org.jdom2.Element;
38  import org.jdom2.Text;
39  
40  /**
41   * JDOM2 implementation of poms PROJECT element.
42   *
43   * @author Robert Scholte
44   * @since 3.0
45   */
46  public class JDomModel extends Model {
47      private final Element project;
48  
49      private final JDomModelBase modelBase;
50  
51      /**
52       * The ReleaseDescriptor after a commit performed.
53       */
54      private final ReleaseDescriptor releaseDescriptor;
55  
56      /**
57       * <p>Constructor for JDomModel.</p>
58       *
59       * @param document a {@link org.jdom2.Document} object
60       */
61      public JDomModel(Document document, ReleaseDescriptor releaseDescriptor) {
62          this(document.getRootElement(), releaseDescriptor);
63      }
64  
65      /**
66       * <p>Constructor for JDomModel.</p>
67       *
68       * @param project a {@link org.jdom2.Element} object
69       */
70      public JDomModel(Element project, ReleaseDescriptor releaseDescriptor) {
71          this.project = project;
72          this.releaseDescriptor = releaseDescriptor;
73          this.modelBase = new JDomModelBase(project);
74      }
75  
76      @Override
77      public Build getBuild() {
78          return modelBase.getBuild();
79      }
80  
81      @Override
82      public List<Dependency> getDependencies() {
83          return modelBase.getDependencies();
84      }
85  
86      @Override
87      public DependencyManagement getDependencyManagement() {
88          return modelBase.getDependencyManagement();
89      }
90  
91      @Override
92      public Parent getParent() {
93          Element elm = getParentElement();
94          if (elm == null) {
95              return null;
96          } else {
97              // this way scm setters change DOM tree immediately
98              return new JDomParent(elm);
99          }
100     }
101 
102     private Element getParentElement() {
103         return project.getChild("parent", project.getNamespace());
104     }
105 
106     @Override
107     public List<Profile> getProfiles() {
108         Element profilesElm = project.getChild("profiles", project.getNamespace());
109         if (profilesElm == null) {
110             return Collections.emptyList();
111         } else {
112             List<Element> profileElms = profilesElm.getChildren("profile", project.getNamespace());
113 
114             List<Profile> profiles = new ArrayList<>(profileElms.size());
115 
116             for (Element profileElm : profileElms) {
117                 profiles.add(new JDomProfile(profileElm));
118             }
119 
120             return profiles;
121         }
122     }
123 
124     @Override
125     public Properties getProperties() {
126         Element properties = project.getChild("properties", project.getNamespace());
127 
128         if (properties == null) {
129             return null;
130         } else {
131             return new JDomProperties(properties);
132         }
133     }
134 
135     @Override
136     public Reporting getReporting() {
137         Element reporting = project.getChild("reporting", project.getNamespace());
138 
139         if (reporting == null) {
140             return null;
141         } else {
142             return new JDomReporting(reporting);
143         }
144     }
145 
146     @Override
147     public void setScm(Scm scm) {
148         if (scm == null) {
149             JDomUtils.rewriteElement("scm", null, project, project.getNamespace());
150         } else {
151             Element scmRoot = new Element("scm");
152             scmRoot.addContent("\n  ");
153 
154             // Write current values to JDOM2 tree
155             Scm jdomScm = new JDomScm(scmRoot);
156             jdomScm.setConnection(scm.getConnection());
157             jdomScm.setDeveloperConnection(scm.getDeveloperConnection());
158             jdomScm.setTag(scm.getTag());
159             jdomScm.setUrl(scm.getUrl());
160 
161             project.addContent("\n  ").addContent(scmRoot).addContent("\n");
162         }
163     }
164 
165     @Override
166     public Scm getScm() {
167         Element elm = project.getChild("scm", project.getNamespace());
168         if (elm == null) {
169             return null;
170         } else {
171             // this way scm setters change DOM tree immediately
172             return new JDomScm(elm);
173         }
174     }
175 
176     @Override
177     public void setVersion(String version) {
178         Element versionElement = project.getChild("version", project.getNamespace());
179 
180         String parentVersion;
181         Element parent = getParentElement();
182         if (parent != null) {
183             parentVersion = parent.getChildTextTrim("version", project.getNamespace());
184         } else {
185             parentVersion = null;
186         }
187 
188         if (versionElement == null) {
189             // never add version when parent references CI friendly property
190             if (!(parentVersion != null && CiFriendlyVersion.isCiFriendlyVersion(parentVersion))
191                     && !version.equals(parentVersion)) {
192                 // we will add this after artifactId, since it was missing but different from the inherited version
193                 Element artifactIdElement = project.getChild("artifactId", project.getNamespace());
194                 int index = project.indexOf(artifactIdElement);
195 
196                 versionElement = new Element("version", project.getNamespace());
197                 versionElement.setText(version);
198                 project.addContent(index + 1, new Text("\n  "));
199                 project.addContent(index + 2, versionElement);
200             }
201         } else {
202             if (CiFriendlyVersion.isCiFriendlyVersion(versionElement.getTextNormalize())) {
203                 // try to rewrite property if CI friendly expression is used
204                 CiFriendlyVersion.rewriteCiFriendlyProperties(version, getProperties(), releaseDescriptor);
205             } else {
206                 JDomUtils.rewriteValue(versionElement, version);
207             }
208         }
209     }
210 }