1 | |
package org.apache.maven.artifact.ant; |
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | |
|
16 | |
|
17 | |
|
18 | |
|
19 | |
|
20 | |
|
21 | |
|
22 | |
import org.apache.maven.artifact.Artifact; |
23 | |
import org.apache.maven.artifact.repository.ArtifactRepository; |
24 | |
import org.apache.maven.model.Build; |
25 | |
import org.apache.maven.model.CiManagement; |
26 | |
import org.apache.maven.model.Contributor; |
27 | |
import org.apache.maven.model.Dependency; |
28 | |
import org.apache.maven.model.DependencyManagement; |
29 | |
import org.apache.maven.model.Developer; |
30 | |
import org.apache.maven.model.DistributionManagement; |
31 | |
import org.apache.maven.model.IssueManagement; |
32 | |
import org.apache.maven.model.License; |
33 | |
import org.apache.maven.model.MailingList; |
34 | |
import org.apache.maven.model.Model; |
35 | |
import org.apache.maven.model.Organization; |
36 | |
import org.apache.maven.model.Parent; |
37 | |
import org.apache.maven.model.Reporting; |
38 | |
import org.apache.maven.model.Repository; |
39 | |
import org.apache.maven.model.Scm; |
40 | |
import org.apache.maven.profiles.ProfileManager; |
41 | |
import org.apache.maven.project.DefaultProjectBuilderConfiguration; |
42 | |
import org.apache.maven.project.MavenProject; |
43 | |
import org.apache.maven.project.MavenProjectBuilder; |
44 | |
import org.apache.maven.project.MavenProjectHelper; |
45 | |
import org.apache.maven.project.ProjectBuilderConfiguration; |
46 | |
import org.apache.maven.project.ProjectBuildingException; |
47 | |
import org.apache.maven.project.inheritance.ModelInheritanceAssembler; |
48 | |
import org.apache.maven.project.injection.ModelDefaultsInjector; |
49 | |
import org.apache.maven.project.interpolation.ModelInterpolationException; |
50 | |
import org.apache.tools.ant.BuildException; |
51 | |
import org.apache.tools.ant.Project; |
52 | |
import org.apache.tools.ant.PropertyHelper; |
53 | |
import org.codehaus.plexus.util.StringUtils; |
54 | |
|
55 | |
import java.io.File; |
56 | |
import java.util.ArrayList; |
57 | |
import java.util.Hashtable; |
58 | |
import java.util.Iterator; |
59 | |
import java.util.List; |
60 | |
import java.util.Properties; |
61 | |
|
62 | |
|
63 | |
|
64 | |
|
65 | |
|
66 | |
|
67 | |
|
68 | |
|
69 | |
|
70 | |
|
71 | 5 | public class Pom |
72 | |
extends AbstractArtifactWithRepositoryTask |
73 | |
{ |
74 | |
|
75 | |
|
76 | |
|
77 | |
private String refid; |
78 | |
|
79 | |
|
80 | |
|
81 | |
|
82 | |
String antId; |
83 | |
|
84 | |
|
85 | |
|
86 | |
|
87 | |
private MavenProject mavenProject; |
88 | |
|
89 | |
|
90 | |
|
91 | |
|
92 | |
private File file; |
93 | |
|
94 | |
|
95 | |
|
96 | |
|
97 | 5 | private List<Profile> profiles = new ArrayList<Profile>(); |
98 | |
|
99 | 5 | private boolean inheritAllProperties = true; |
100 | |
|
101 | |
|
102 | |
|
103 | |
|
104 | 5 | private final POMPropertyHelper helper = new POMPropertyHelper( this ); |
105 | |
|
106 | |
public String getRefid() |
107 | |
{ |
108 | 0 | return refid; |
109 | |
} |
110 | |
|
111 | |
|
112 | |
|
113 | |
|
114 | |
|
115 | |
|
116 | |
public void setRefid( String refid ) |
117 | |
{ |
118 | 0 | this.refid = refid; |
119 | 0 | } |
120 | |
|
121 | |
|
122 | |
|
123 | |
|
124 | |
|
125 | |
|
126 | |
public void setId( String id ) |
127 | |
{ |
128 | 0 | this.antId = id; |
129 | 0 | } |
130 | |
|
131 | |
|
132 | |
|
133 | |
|
134 | |
|
135 | |
|
136 | |
|
137 | |
protected void getPomFromAntProject( String refid ) |
138 | |
{ |
139 | 0 | if ( refid == null ) |
140 | |
{ |
141 | 0 | throw new BuildException( "POM refid is null." ); |
142 | |
} |
143 | |
|
144 | 0 | if ( getProject().getReference( refid ) == null ) |
145 | |
{ |
146 | 0 | throw new BuildException( "Unable to locate POM reference: '" + refid + "'" ); |
147 | |
} |
148 | |
|
149 | 0 | Pom thePom = (Pom) getProject().getReference( refid ); |
150 | 0 | mavenProject = thePom.getMavenProject(); |
151 | 0 | file = thePom.getFile(); |
152 | 0 | } |
153 | |
|
154 | |
public void setMavenProject( MavenProject mavenProject ) |
155 | |
{ |
156 | 0 | this.mavenProject = mavenProject; |
157 | 0 | } |
158 | |
|
159 | |
public File getFile() |
160 | |
{ |
161 | 0 | return file; |
162 | |
} |
163 | |
|
164 | |
public void setFile( File file ) |
165 | |
{ |
166 | 0 | this.file = file; |
167 | 0 | } |
168 | |
|
169 | |
public List<Profile> getProfiles() |
170 | |
{ |
171 | 0 | return profiles; |
172 | |
} |
173 | |
|
174 | |
public void addProfile( Profile activeProfile ) |
175 | |
{ |
176 | 0 | this.profiles.add( activeProfile ); |
177 | 0 | } |
178 | |
|
179 | |
public Artifact getArtifact() |
180 | |
{ |
181 | 0 | return getMavenProject().getArtifact(); |
182 | |
} |
183 | |
|
184 | |
public void attach( AttachedArtifact attached ) |
185 | |
{ |
186 | 0 | MavenProjectHelper helper = (MavenProjectHelper) lookup( MavenProjectHelper.ROLE ); |
187 | 0 | MavenProject project = getMavenProject(); |
188 | 0 | if ( attached.getClassifier() != null ) |
189 | |
{ |
190 | 0 | helper.attachArtifact( project, attached.getType(), attached.getClassifier(), attached.getFile() ); |
191 | |
} |
192 | |
else |
193 | |
{ |
194 | 0 | helper.attachArtifact( project, attached.getType(), attached.getFile() ); |
195 | |
} |
196 | 0 | } |
197 | |
|
198 | |
public List<Artifact> getAttachedArtifacts() |
199 | |
{ |
200 | 0 | return getMavenProject().getAttachedArtifacts(); |
201 | |
} |
202 | |
|
203 | |
public void initialiseMavenProject( MavenProjectBuilder builder, ArtifactRepository localRepository ) |
204 | |
{ |
205 | 0 | if ( file != null ) |
206 | |
{ |
207 | 0 | addAntRepositoriesToProfileManager(); |
208 | 0 | ProjectBuilderConfiguration builderConfig = this.createProjectBuilderConfig( localRepository ); |
209 | |
try |
210 | |
{ |
211 | 0 | mavenProject = builder.build( file, builderConfig ); |
212 | |
|
213 | 0 | builder.calculateConcreteState( mavenProject, builderConfig, false ); |
214 | |
} |
215 | 0 | catch ( ProjectBuildingException pbe ) |
216 | |
{ |
217 | 0 | throw new BuildException( "Unable to initialize POM " + file.getName() + ": " + pbe.getMessage(), pbe ); |
218 | |
} |
219 | 0 | catch ( ModelInterpolationException mie ) |
220 | |
{ |
221 | 0 | throw new BuildException( "Unable to interpolate POM " + file.getName() + ": " + mie.getMessage(), mie ); |
222 | 0 | } |
223 | 0 | } |
224 | 0 | else if ( refid != null ) |
225 | |
{ |
226 | 0 | this.getPomFromAntProject( refid ); |
227 | |
} |
228 | 0 | else if ( mavenProject != null ) |
229 | |
{ |
230 | 0 | addAntRepositoriesToProfileManager(); |
231 | 0 | ProjectBuilderConfiguration builderConfig = this.createProjectBuilderConfig( localRepository ); |
232 | |
try |
233 | |
{ |
234 | 0 | builder.calculateConcreteState( mavenProject, builderConfig, false ); |
235 | |
} |
236 | 0 | catch ( ModelInterpolationException mie ) |
237 | |
{ |
238 | 0 | throw new BuildException( "Unable to interpolate POM " + file.getName() + ": " + mie.getMessage(), mie ); |
239 | 0 | } |
240 | |
|
241 | |
} |
242 | 0 | if ( mavenProject != null && mavenProject.getModel().getParent() != null ) |
243 | |
{ |
244 | 0 | String parentGroupId = mavenProject.getModel().getParent().getGroupId(); |
245 | 0 | String parentArtifactId = mavenProject.getModel().getParent().getArtifactId(); |
246 | 0 | String parentVersion = mavenProject.getModel().getParent().getVersion(); |
247 | 0 | Iterator i = getAntReactorPoms().iterator(); |
248 | 0 | while ( i.hasNext() ) |
249 | |
{ |
250 | 0 | Pom pom = (Pom)i.next(); |
251 | 0 | if ( StringUtils.equals( parentGroupId, pom.getGroupId() ) |
252 | |
&& StringUtils.equals( parentArtifactId, pom.getArtifactId() ) |
253 | |
&& StringUtils.equals( parentVersion, pom.getVersion() ) ) |
254 | |
{ |
255 | 0 | pom.initialiseMavenProject( builder, localRepository ); |
256 | 0 | mavenProject.setParent( pom.getMavenProject() ); |
257 | 0 | ModelInheritanceAssembler modelInheritanceAssembler = |
258 | |
(ModelInheritanceAssembler) lookup( ModelInheritanceAssembler. ROLE ); |
259 | 0 | modelInheritanceAssembler.assembleModelInheritance( mavenProject.getModel(), pom.getModel() ); |
260 | 0 | break; |
261 | |
} |
262 | 0 | } |
263 | |
} |
264 | 0 | ModelDefaultsInjector modelDefaultsInjector = (ModelDefaultsInjector) lookup( ModelDefaultsInjector.ROLE ); |
265 | 0 | modelDefaultsInjector.injectDefaults(mavenProject.getModel()); |
266 | 0 | } |
267 | |
|
268 | |
protected MavenProject getMavenProject() |
269 | |
{ |
270 | 0 | if ( mavenProject == null ) |
271 | |
{ |
272 | 0 | mavenProject = createMinimalProject( createLocalArtifactRepository() ); |
273 | |
} |
274 | 0 | return mavenProject; |
275 | |
} |
276 | |
|
277 | |
public String getArtifactId() |
278 | |
{ |
279 | 0 | return getMavenProject().getArtifactId(); |
280 | |
} |
281 | |
|
282 | |
public Build getBuild() |
283 | |
{ |
284 | 0 | return getMavenProject().getBuild(); |
285 | |
} |
286 | |
|
287 | |
public CiManagement getCiManagement() |
288 | |
{ |
289 | 0 | return getMavenProject().getCiManagement(); |
290 | |
} |
291 | |
|
292 | |
public List getContributors() |
293 | |
{ |
294 | 0 | return getMavenProject().getContributors(); |
295 | |
} |
296 | |
|
297 | |
public List<Dependency> getDependencies() |
298 | |
{ |
299 | 0 | return getMavenProject().getDependencies(); |
300 | |
} |
301 | |
|
302 | |
public DependencyManagement getDependencyManagement() |
303 | |
{ |
304 | 0 | return getMavenProject().getDependencyManagement(); |
305 | |
} |
306 | |
|
307 | |
public String getDescription() |
308 | |
{ |
309 | 0 | return getMavenProject().getDescription(); |
310 | |
} |
311 | |
|
312 | |
public List getDevelopers() |
313 | |
{ |
314 | 0 | return getMavenProject().getDevelopers(); |
315 | |
} |
316 | |
|
317 | |
public DistributionManagement getDistributionManagement() |
318 | |
{ |
319 | 0 | return getMavenProject().getDistributionManagement(); |
320 | |
} |
321 | |
|
322 | |
public String getGroupId() |
323 | |
{ |
324 | 0 | return getMavenProject().getGroupId(); |
325 | |
} |
326 | |
|
327 | |
public String getInceptionYear() |
328 | |
{ |
329 | 0 | return getMavenProject().getInceptionYear(); |
330 | |
} |
331 | |
|
332 | |
public IssueManagement getIssueManagement() |
333 | |
{ |
334 | 0 | return getMavenProject().getIssueManagement(); |
335 | |
} |
336 | |
|
337 | |
public List getLicenses() |
338 | |
{ |
339 | 0 | return getMavenProject().getLicenses(); |
340 | |
} |
341 | |
|
342 | |
public List getMailingLists() |
343 | |
{ |
344 | 0 | return getMavenProject().getMailingLists(); |
345 | |
} |
346 | |
|
347 | |
public String getModelVersion() |
348 | |
{ |
349 | 0 | return getMavenProject().getModelVersion(); |
350 | |
} |
351 | |
|
352 | |
public List getModules() |
353 | |
{ |
354 | 0 | return getMavenProject().getModules(); |
355 | |
} |
356 | |
|
357 | |
public String getName() |
358 | |
{ |
359 | 0 | return getMavenProject().getName(); |
360 | |
} |
361 | |
|
362 | |
public Organization getOrganization() |
363 | |
{ |
364 | 0 | return getMavenProject().getOrganization(); |
365 | |
} |
366 | |
|
367 | |
public String getPackaging() |
368 | |
{ |
369 | 0 | return getMavenProject().getPackaging(); |
370 | |
} |
371 | |
|
372 | |
public List getPluginRepositories() |
373 | |
{ |
374 | 0 | return getMavenProject().getPluginRepositories(); |
375 | |
} |
376 | |
|
377 | |
public Reporting getReporting() |
378 | |
{ |
379 | 0 | return getMavenProject().getReporting(); |
380 | |
} |
381 | |
|
382 | |
public List<Repository> getRepositories() |
383 | |
{ |
384 | 0 | return getMavenProject().getRepositories(); |
385 | |
} |
386 | |
|
387 | |
public Scm getScm() |
388 | |
{ |
389 | 0 | return getMavenProject().getScm(); |
390 | |
} |
391 | |
|
392 | |
public String getUrl() |
393 | |
{ |
394 | 0 | return getMavenProject().getUrl(); |
395 | |
} |
396 | |
|
397 | |
public String getVersion() |
398 | |
{ |
399 | 0 | return getMavenProject().getVersion(); |
400 | |
} |
401 | |
|
402 | |
public String getId() |
403 | |
{ |
404 | 0 | return getMavenProject().getId(); |
405 | |
} |
406 | |
|
407 | |
|
408 | |
|
409 | |
|
410 | |
protected void doExecute() |
411 | |
{ |
412 | 0 | if ( getId() == null ) |
413 | |
{ |
414 | 0 | throw new BuildException( "id required for pom task" ); |
415 | |
} |
416 | 0 | ArtifactRepository localRepo = createLocalArtifactRepository(); |
417 | 0 | MavenProjectBuilder projectBuilder = (MavenProjectBuilder) lookup( MavenProjectBuilder.ROLE ); |
418 | 0 | initialiseMavenProject( projectBuilder, localRepo ); |
419 | |
|
420 | 0 | Project antProject = getProject(); |
421 | |
|
422 | |
|
423 | 0 | antProject.addReference( antId, this ); |
424 | |
|
425 | |
|
426 | 0 | PropertyHelper phelper = PropertyHelper.getPropertyHelper( antProject ); |
427 | |
try |
428 | |
{ |
429 | |
|
430 | 0 | POMPropertyEvaluator.register( this, phelper ); |
431 | |
} |
432 | 0 | catch ( LinkageError e ) |
433 | |
{ |
434 | |
|
435 | 0 | helper.setNext( phelper.getNext() ); |
436 | 0 | helper.setProject( antProject ); |
437 | 0 | phelper.setNext( helper ); |
438 | 0 | } |
439 | 0 | } |
440 | |
|
441 | |
|
442 | |
|
443 | |
|
444 | |
|
445 | |
private void addAntRepositoriesToProfileManager() |
446 | |
{ |
447 | 0 | List<RemoteRepository> remoteRepositories = this.getRemoteRepositories(); |
448 | |
|
449 | 0 | if ( remoteRepositories == null || remoteRepositories.isEmpty() ) |
450 | |
{ |
451 | 0 | return; |
452 | |
} |
453 | 0 | org.apache.maven.model.Profile repositoriesProfile = new org.apache.maven.model.Profile(); |
454 | 0 | repositoriesProfile.setId( "maven-ant-tasks-repo-profile" ); |
455 | |
|
456 | 0 | for ( RemoteRepository antRepo : remoteRepositories ) |
457 | |
{ |
458 | 0 | Repository mavenRepo = new Repository(); |
459 | 0 | mavenRepo.setId( antRepo.getId() ); |
460 | 0 | mavenRepo.setUrl( antRepo.getUrl() ); |
461 | 0 | repositoriesProfile.addRepository( mavenRepo ); |
462 | 0 | } |
463 | |
|
464 | 0 | getProfileManager().addProfile( repositoriesProfile ); |
465 | 0 | getProfileManager().explicitlyActivate( repositoriesProfile.getId() ); |
466 | 0 | } |
467 | |
|
468 | |
private ProfileManager getActivatedProfiles() |
469 | |
{ |
470 | 0 | ProfileManager profileManager = getProfileManager(); |
471 | |
|
472 | 0 | for ( Profile profile : getProfiles() ) |
473 | |
{ |
474 | 0 | if ( profile.getId() == null ) |
475 | |
{ |
476 | 0 | throw new BuildException( "Attribute \"id\" is required for profile in pom type." ); |
477 | |
} |
478 | |
|
479 | 0 | if ( profile.getActive() == null || Boolean.valueOf( profile.getActive() ).booleanValue() ) |
480 | |
{ |
481 | 0 | profileManager.explicitlyActivate( profile.getId() ); |
482 | |
} |
483 | |
else |
484 | |
{ |
485 | 0 | profileManager.explicitlyDeactivate( profile.getId() ); |
486 | |
} |
487 | |
|
488 | |
} |
489 | 0 | return profileManager; |
490 | |
} |
491 | |
|
492 | |
|
493 | |
|
494 | |
|
495 | |
|
496 | |
|
497 | |
private ProjectBuilderConfiguration createProjectBuilderConfig( ArtifactRepository localArtifactRepository ) |
498 | |
{ |
499 | 0 | ProjectBuilderConfiguration builderConfig = new DefaultProjectBuilderConfiguration(); |
500 | 0 | builderConfig.setLocalRepository( localArtifactRepository ); |
501 | 0 | builderConfig.setGlobalProfileManager( this.getActivatedProfiles() ); |
502 | 0 | builderConfig.setUserProperties( getAntProjectProperties() ); |
503 | 0 | builderConfig.setExecutionProperties( getAntProjectProperties() ); |
504 | |
|
505 | 0 | return builderConfig; |
506 | |
} |
507 | |
|
508 | |
|
509 | |
|
510 | |
|
511 | |
|
512 | |
|
513 | |
public Properties getAntProjectProperties() |
514 | |
{ |
515 | 0 | Properties properties = new Properties(); |
516 | 0 | Hashtable propsTable = null; |
517 | 0 | if ( this.isInheritAllProperties() ) |
518 | |
{ |
519 | 0 | propsTable = getProject().getProperties(); |
520 | |
} |
521 | |
else |
522 | |
{ |
523 | 0 | propsTable = getProject().getUserProperties(); |
524 | |
} |
525 | 0 | Iterator propsIter = propsTable.keySet().iterator(); |
526 | |
|
527 | 0 | while ( propsIter.hasNext() ) |
528 | |
{ |
529 | 0 | String key = (String) propsIter.next(); |
530 | 0 | String value = (String) propsTable.get( key ); |
531 | 0 | properties.setProperty( key, value ); |
532 | 0 | } |
533 | |
|
534 | 0 | return properties; |
535 | |
} |
536 | |
|
537 | |
|
538 | |
|
539 | |
|
540 | |
|
541 | |
|
542 | |
|
543 | |
public void setInheritAllProperties( boolean inheritAllProperties ) |
544 | |
{ |
545 | 0 | this.inheritAllProperties = inheritAllProperties; |
546 | 0 | } |
547 | |
|
548 | |
public boolean isInheritAllProperties() |
549 | |
{ |
550 | 0 | return inheritAllProperties; |
551 | |
} |
552 | |
|
553 | |
public Model getModel() |
554 | |
{ |
555 | 0 | return getMavenProject().getModel(); |
556 | |
} |
557 | |
|
558 | |
public void setGroupId( String groupId ) |
559 | |
{ |
560 | 0 | getMavenProject().setGroupId( groupId ); |
561 | 0 | } |
562 | |
|
563 | |
public void setArtifactId( String artifactId ) |
564 | |
{ |
565 | 0 | getMavenProject().setArtifactId( artifactId ); |
566 | 0 | } |
567 | |
|
568 | |
public void setVersion( String version ) |
569 | |
{ |
570 | 0 | getMavenProject().setVersion( version ); |
571 | 0 | } |
572 | |
|
573 | |
public void addConfiguredParent( Parent parent ) |
574 | |
{ |
575 | 0 | getMavenProject().getModel().setParent( parent ); |
576 | 0 | } |
577 | |
|
578 | |
public void addConfiguredCiManagement( CiManagement ciManagement ) |
579 | |
{ |
580 | 0 | getMavenProject().setCiManagement( ciManagement ); |
581 | 0 | } |
582 | |
|
583 | |
public void addConfiguredContributor ( Contributor contributor ) |
584 | |
{ |
585 | 0 | getMavenProject().addContributor( contributor ); |
586 | 0 | } |
587 | |
|
588 | |
public void addConfiguredDependency( Dependency dependency ) |
589 | |
{ |
590 | 0 | getMavenProject().getDependencies().add( dependency ); |
591 | 0 | } |
592 | |
|
593 | |
public void addConfiguredDependencyManagement( DependencyManagement dependencyManagement ) |
594 | |
{ |
595 | 0 | if ( getMavenProject().getDependencyManagement() == null ) |
596 | |
{ |
597 | |
|
598 | 0 | getMavenProject().getModel().setDependencyManagement(new DependencyManagement()); |
599 | |
} |
600 | 0 | getMavenProject().getDependencyManagement().setDependencies( dependencyManagement.getDependencies() ); |
601 | 0 | } |
602 | |
|
603 | |
public void setDescription( String description ) |
604 | |
{ |
605 | 0 | getMavenProject().setDescription( description ); |
606 | 0 | } |
607 | |
|
608 | |
public void addConfiguredDeveloper( Developer developer ) |
609 | |
{ |
610 | 0 | getMavenProject().addDeveloper( developer ); |
611 | 0 | } |
612 | |
|
613 | |
public void setInceptionYear( String inceptionYear ) |
614 | |
{ |
615 | 0 | getMavenProject().setInceptionYear( inceptionYear ); |
616 | 0 | } |
617 | |
|
618 | |
public void addConfiguredIssueManagement( IssueManagement issueManagement ) |
619 | |
{ |
620 | 0 | getMavenProject().setIssueManagement( issueManagement ); |
621 | 0 | } |
622 | |
|
623 | |
public void addConfiguredLicense ( License license ) |
624 | |
{ |
625 | 0 | getMavenProject().addLicense( license ); |
626 | 0 | } |
627 | |
|
628 | |
public void addConfiguredMailingLists( MailingList mailingList ) |
629 | |
{ |
630 | 0 | getMavenProject().addMailingList( mailingList ); |
631 | 0 | } |
632 | |
|
633 | |
public void setName( String name ) |
634 | |
{ |
635 | 0 | getMavenProject().setName( name ); |
636 | 0 | } |
637 | |
|
638 | |
public void addConfiguredOrganization( Organization organization ) |
639 | |
{ |
640 | 0 | getMavenProject().setOrganization( organization ); |
641 | 0 | } |
642 | |
|
643 | |
public void setPackaging( String packaging ) |
644 | |
{ |
645 | 0 | getMavenProject().setPackaging( packaging ); |
646 | 0 | } |
647 | |
|
648 | |
public void addConfiguredScm( Scm scm ) |
649 | |
{ |
650 | 0 | getMavenProject().setScm( scm ); |
651 | 0 | } |
652 | |
|
653 | |
public void setUrl( String url ) |
654 | |
{ |
655 | 0 | getMavenProject().setUrl( url ); |
656 | 0 | } |
657 | |
|
658 | |
} |