7
7
import com .github .lombrozo .xnav .Filter ;
8
8
import com .github .lombrozo .xnav .Xnav ;
9
9
import com .jcabi .log .Logger ;
10
+ import com .jcabi .xml .XML ;
10
11
import com .jcabi .xml .XMLDocument ;
12
+ import java .io .FileNotFoundException ;
11
13
import java .io .IOException ;
12
14
import java .nio .file .Path ;
15
+ import java .util .ArrayList ;
13
16
import java .util .List ;
14
17
import java .util .stream .Collectors ;
15
18
import org .apache .maven .plugins .annotations .LifecyclePhase ;
16
19
import org .apache .maven .plugins .annotations .Mojo ;
17
20
import org .apache .maven .plugins .annotations .ResolutionScope ;
18
- import org .cactoos .Func ;
19
21
import org .cactoos .io .InputOf ;
20
22
import org .cactoos .iterable .Filtered ;
21
23
import org .eolang .parser .EoSyntax ;
24
+ import org .w3c .dom .Node ;
22
25
import org .xembly .Directives ;
23
26
import org .xembly .Xembler ;
24
27
@@ -95,15 +98,20 @@ private int parsed(final TjForeign tojo) throws Exception {
95
98
final String name = tojo .identifier ();
96
99
final Path base = this .targetDir .toPath ().resolve (ParseMojo .DIR );
97
100
final Path target = new Place (name ).make (base , AssembleMojo .XMIR );
101
+ final List <Node > refs = new ArrayList <>(1 );
98
102
tojo .withXmir (
99
103
new FpDefault (
100
- this .parse (name ),
104
+ src -> {
105
+ final Node node = this .parsed (src , name );
106
+ refs .add (node );
107
+ return new XMLDocument (node ).toString ();
108
+ },
101
109
this .cache .toPath ().resolve (ParseMojo .CACHE ),
102
110
this .plugin .getVersion (),
103
111
new TojoHash (tojo ),
104
112
base .relativize (target )
105
113
).apply (source , target )
106
- );
114
+ ). withVersion ( ParseMojo . version ( target , refs )) ;
107
115
final List <Xnav > errors = new Xnav (target )
108
116
.element ("program" )
109
117
.element ("errors" )
@@ -126,26 +134,65 @@ private int parsed(final TjForeign tojo) throws Exception {
126
134
}
127
135
128
136
/**
129
- * Function that parses EO source.
137
+ * Source parsed to {@link Node}.
138
+ * @param source Relative source path
130
139
* @param name Name of the EO object
131
- * @return Function that parses EO source
140
+ * @return Parsed EO object as {@link Node}
141
+ * @throws IOException If fails to parse
132
142
*/
133
- private Func <Path , String > parse (final String name ) {
134
- return source -> {
135
- final String parsed = new XMLDocument (
136
- new Xembler (
137
- new Directives ().xpath ("/program" ).attr (
138
- "source" , this .sourcesDir .toPath ().relativize (source .toAbsolutePath ())
139
- )
140
- ).applyQuietly (new EoSyntax (name , new InputOf (source )).parsed ().inner ())
141
- ).toString ();
142
- Logger .debug (
143
- ParseMojo .class ,
144
- "Parsed program %s:\n %s" ,
145
- name ,
146
- parsed
147
- );
148
- return parsed ;
149
- };
143
+ private Node parsed (final Path source , final String name ) throws IOException {
144
+ final XML xmir = new EoSyntax (name , new InputOf (source )).parsed ();
145
+ final Path src = this .sourcesDir .toPath ().relativize (source .toAbsolutePath ());
146
+ final Node node = new Xembler (
147
+ new Directives ().xpath ("/program" ).attr ("source" , src )
148
+ ).applyQuietly (xmir .inner ());
149
+ Logger .debug (
150
+ ParseMojo .class ,
151
+ "Parsed program '%s' from %[file]s:\n %s" ,
152
+ name , src , xmir
153
+ );
154
+ return node ;
155
+ }
156
+
157
+ /**
158
+ * Tojo version.
159
+ * The version can be extracted from:
160
+ * 1. Parsed {@link Node} if EO object was parsed for the first time
161
+ * 2. XML document that was already parsed before
162
+ * @param target Path to result XML document
163
+ * @param parsed List with either one parsed {@link Node} or empty
164
+ * @return Tojo version
165
+ * @throws FileNotFoundException If XML document file does not exist
166
+ */
167
+ private static String version (
168
+ final Path target ,
169
+ final List <Node > parsed
170
+ ) throws FileNotFoundException {
171
+ final Node node ;
172
+ if (parsed .isEmpty ()) {
173
+ node = new XMLDocument (target ).inner ();
174
+ } else {
175
+ node = parsed .get (0 );
176
+ }
177
+ return new Xnav (node )
178
+ .element ("program" )
179
+ .element ("metas" )
180
+ .elements (
181
+ Filter .all (
182
+ Filter .withName ("meta" ),
183
+ meta -> new Xnav (meta )
184
+ .elements (
185
+ Filter .all (
186
+ Filter .withName ("head" ),
187
+ head -> head .text ().map ("version" ::equals ).orElse (false )
188
+ )
189
+ )
190
+ .findAny ()
191
+ .isPresent ()
192
+ )
193
+ )
194
+ .findFirst ()
195
+ .map (meta -> meta .element ("tail" ).text ().get ())
196
+ .orElse (ParseMojo .ZERO );
150
197
}
151
198
}
0 commit comments