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.model.io;
20  
21  import javax.inject.Inject;
22  import javax.inject.Named;
23  import javax.inject.Singleton;
24  import javax.xml.stream.Location;
25  import javax.xml.stream.XMLInputFactory;
26  import javax.xml.stream.XMLStreamException;
27  import javax.xml.stream.XMLStreamReader;
28  
29  import java.io.File;
30  import java.io.IOException;
31  import java.io.InputStream;
32  import java.io.Reader;
33  import java.nio.file.Files;
34  import java.nio.file.Path;
35  import java.util.Map;
36  import java.util.Objects;
37  
38  import org.apache.maven.model.InputSource;
39  import org.apache.maven.model.Model;
40  import org.apache.maven.model.building.ModelSourceTransformer;
41  import org.apache.maven.model.v4.MavenStaxReader;
42  
43  /**
44   * Handles deserialization of a model from some kind of textual format like XML.
45   *
46   */
47  @Named
48  @Singleton
49  public class DefaultModelReader implements ModelReader {
50      private final ModelSourceTransformer transformer;
51  
52      @Inject
53      public DefaultModelReader(ModelSourceTransformer transformer) {
54          this.transformer = transformer;
55      }
56  
57      @Override
58      public Model read(File input, Map<String, ?> options) throws IOException {
59          Objects.requireNonNull(input, "input cannot be null");
60          return read(input.toPath(), options);
61      }
62  
63      @Override
64      public Model read(Path path, Map<String, ?> options) throws IOException {
65          Objects.requireNonNull(path, "path cannot be null");
66  
67          try (InputStream in = Files.newInputStream(path)) {
68              Model model = read(in, path, options);
69  
70              model.setPomPath(path);
71  
72              return model;
73          }
74      }
75  
76      @Override
77      public Model read(Reader input, Map<String, ?> options) throws IOException {
78          Objects.requireNonNull(input, "input cannot be null");
79  
80          try (Reader in = input) {
81              return read(in, null, options);
82          }
83      }
84  
85      @Override
86      public Model read(InputStream input, Map<String, ?> options) throws IOException {
87          Objects.requireNonNull(input, "input cannot be null");
88  
89          try (InputStream in = input) {
90              return read(input, null, options);
91          }
92      }
93  
94      private boolean isStrict(Map<String, ?> options) {
95          Object value = (options != null) ? options.get(IS_STRICT) : null;
96          return value == null || Boolean.parseBoolean(value.toString());
97      }
98  
99      private InputSource getSource(Map<String, ?> options) {
100         Object value = (options != null) ? options.get(INPUT_SOURCE) : null;
101         return (InputSource) value;
102     }
103 
104     private Path getRootDirectory(Map<String, ?> options) {
105         Object value = (options != null) ? options.get(ROOT_DIRECTORY) : null;
106         return (Path) value;
107     }
108 
109     private Model read(InputStream input, Path pomFile, Map<String, ?> options) throws IOException {
110         try {
111             XMLInputFactory factory = XMLInputFactory.newFactory();
112             factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false);
113             XMLStreamReader parser = factory.createXMLStreamReader(input);
114 
115             InputSource source = getSource(options);
116             boolean strict = isStrict(options);
117             MavenStaxReader mr = new MavenStaxReader();
118             mr.setAddLocationInformation(source != null);
119             Model model = new Model(mr.read(parser, strict, source != null ? source.toApiSource() : null));
120             return model;
121         } catch (XMLStreamException e) {
122             Location location = e.getLocation();
123             throw new ModelParseException(
124                     e.getMessage(),
125                     location != null ? location.getLineNumber() : -1,
126                     location != null ? location.getColumnNumber() : -1,
127                     e);
128         } catch (Exception e) {
129             throw new IOException("Unable to transform pom", e);
130         }
131     }
132 
133     private Model read(Reader reader, Path pomFile, Map<String, ?> options) throws IOException {
134         try {
135             XMLInputFactory factory = XMLInputFactory.newFactory();
136             factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false);
137             XMLStreamReader parser = factory.createXMLStreamReader(reader);
138 
139             InputSource source = getSource(options);
140             boolean strict = isStrict(options);
141             MavenStaxReader mr = new MavenStaxReader();
142             mr.setAddLocationInformation(source != null);
143             Model model = new Model(mr.read(parser, strict, source != null ? source.toApiSource() : null));
144             return model;
145         } catch (XMLStreamException e) {
146             Location location = e.getLocation();
147             throw new ModelParseException(
148                     e.getMessage(),
149                     location != null ? location.getLineNumber() : -1,
150                     location != null ? location.getColumnNumber() : -1,
151                     e);
152         } catch (Exception e) {
153             throw new IOException("Unable to transform pom", e);
154         }
155     }
156 }