View Javadoc

1   package org.apache.maven.shared.runtime;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.net.URL;
25  import java.net.URLConnection;
26  import java.util.ArrayList;
27  import java.util.Collections;
28  import java.util.List;
29  
30  import org.apache.maven.model.Model;
31  import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
32  import org.apache.maven.project.DuplicateProjectException;
33  import org.apache.maven.project.MavenProject;
34  import org.apache.maven.project.ProjectSorter;
35  import org.codehaus.plexus.util.IOUtil;
36  import org.codehaus.plexus.util.ReaderFactory;
37  import org.codehaus.plexus.util.dag.CycleDetectedException;
38  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
39  
40  /**
41   * A visitor that parses and collects Maven project XML files.
42   * 
43   * @author <a href="mailto:markh@apache.org">Mark Hobson</a>
44   * @version $Id: XMLMavenRuntimeVisitor.java 1341416 2012-05-22 11:38:54Z markh $
45   */
46  class XMLMavenRuntimeVisitor implements MavenRuntimeVisitor
47  {
48      // fields -----------------------------------------------------------------
49  
50      /**
51       * A list of the collected Maven projects.
52       */
53      private final List<MavenProject> projects;
54  
55      // constructors -----------------------------------------------------------
56  
57      /**
58       * Creates a new {@code XMLMavenRuntimeVisitor}.
59       */
60      public XMLMavenRuntimeVisitor()
61      {
62          projects = new ArrayList<MavenProject>();
63      }
64  
65      // MavenRuntimeVisitor methods --------------------------------------------
66  
67      /**
68       * {@inheritDoc}
69       */
70      public void visitProjectProperties( URL url ) throws MavenRuntimeException
71      {
72          // no-op
73      }
74  
75      /**
76       * {@inheritDoc}
77       */
78      public void visitProjectXML( URL url ) throws MavenRuntimeException
79      {
80          MavenProject project = parseProjectXML( url );
81  
82          projects.add( project );
83      }
84  
85      // public methods ---------------------------------------------------------
86  
87      /**
88       * Gets the collected Maven projects.
89       * 
90       * @return an unmodifiable list of the collected Maven projects
91       */
92      public List<MavenProject> getProjects()
93      {
94          return Collections.unmodifiableList( projects );
95      }
96  
97      /**
98       * Gets the collected Maven projects ordered by dependencies.
99       * 
100      * @return an unmodifiable list of the collected Maven projects ordered by dependencies
101      * @throws MavenRuntimeException
102      *             if an error occurred ordering the projects
103      */
104     public List<MavenProject> getSortedProjects() throws MavenRuntimeException
105     {
106         // mediate dependency versions since declared versions can differ from runtime versions
107         List<MavenProject> mediatedProjects = new ArrayList<MavenProject>( projects );
108         MavenProjectUtils.mediateDependencyVersions( mediatedProjects );
109         
110         try
111         {
112             ProjectSorter projectSorter = new ProjectSorter( mediatedProjects );
113 
114             return genericList( projectSorter.getSortedProjects(), MavenProject.class );
115         }
116         catch ( CycleDetectedException exception )
117         {
118             throw new MavenRuntimeException( "Cannot sort projects", exception );
119         }
120         catch ( DuplicateProjectException exception )
121         {
122             throw new MavenRuntimeException( "Cannot sort projects", exception );
123         }
124     }
125 
126     // private methods --------------------------------------------------------
127 
128     /**
129      * Parses the specified Maven project XML into a {@code MavenProject} object.
130      * 
131      * @param url
132      *            a URL to the Maven project XML
133      * @return a {@code MavenProject} object that represents the XML
134      * @throws MavenRuntimeException
135      *             if an error occurs parsing the XML
136      */
137     private MavenProject parseProjectXML( URL url ) throws MavenRuntimeException
138     {
139         MavenXpp3Reader reader = new MavenXpp3Reader();
140 
141         InputStream in = null;
142 
143         try
144         {
145             URLConnection connection = url.openConnection();
146             connection.setUseCaches( false );
147 
148             in = connection.getInputStream();
149 
150             Model model = reader.read( ReaderFactory.newXmlReader( in ) );
151 
152             return new MavenProject( model );
153         }
154         catch ( XmlPullParserException exception )
155         {
156             throw new MavenRuntimeException( "Cannot read project XML: " + url, exception );
157         }
158         catch ( IOException exception )
159         {
160             throw new MavenRuntimeException( "Cannot read project XML: " + url, exception );
161         }
162         finally
163         {
164             IOUtil.close( in );
165         }
166     }
167     
168     /**
169      * Converts the specified raw list to a generic list of a specified type by explicitly casting each element.
170      * 
171      * @param <T>
172      *            the type of the required generic list
173      * @param list
174      *            the raw type
175      * @param type
176      *            the class that represents the type of the required generic list
177      * @return the generic list
178      */
179     private static <T> List<T> genericList( List<?> list, Class<T> type )
180     {
181         List<T> genericList = new ArrayList<T>();
182 
183         for ( Object element : list )
184         {
185             genericList.add( type.cast( element ) );
186         }
187 
188         return genericList;
189     }
190 }