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 }