1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.doxia.tools;
20
21 import javax.inject.Inject;
22 import javax.inject.Named;
23 import javax.inject.Singleton;
24
25 import java.io.File;
26 import java.io.IOException;
27 import java.io.Reader;
28 import java.io.StringReader;
29 import java.io.StringWriter;
30 import java.net.MalformedURLException;
31 import java.net.URL;
32 import java.nio.file.Files;
33 import java.util.AbstractMap;
34 import java.util.ArrayList;
35 import java.util.Arrays;
36 import java.util.Collections;
37 import java.util.List;
38 import java.util.Locale;
39 import java.util.Map;
40 import java.util.Objects;
41 import java.util.StringTokenizer;
42
43 import org.apache.commons.io.FilenameUtils;
44 import org.apache.maven.RepositoryUtils;
45 import org.apache.maven.artifact.Artifact;
46 import org.apache.maven.artifact.DefaultArtifact;
47 import org.apache.maven.artifact.handler.ArtifactHandler;
48 import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
49 import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
50 import org.apache.maven.artifact.versioning.VersionRange;
51 import org.apache.maven.doxia.site.Banner;
52 import org.apache.maven.doxia.site.Body;
53 import org.apache.maven.doxia.site.Image;
54 import org.apache.maven.doxia.site.LinkItem;
55 import org.apache.maven.doxia.site.Logo;
56 import org.apache.maven.doxia.site.Menu;
57 import org.apache.maven.doxia.site.MenuItem;
58 import org.apache.maven.doxia.site.PublishDate;
59 import org.apache.maven.doxia.site.SiteModel;
60 import org.apache.maven.doxia.site.Skin;
61 import org.apache.maven.doxia.site.Version;
62 import org.apache.maven.doxia.site.decoration.DecorationModel;
63 import org.apache.maven.doxia.site.decoration.io.xpp3.DecorationXpp3Reader;
64 import org.apache.maven.doxia.site.inheritance.SiteModelInheritanceAssembler;
65 import org.apache.maven.doxia.site.io.xpp3.SiteXpp3Reader;
66 import org.apache.maven.doxia.site.io.xpp3.SiteXpp3Writer;
67 import org.apache.maven.model.DistributionManagement;
68 import org.apache.maven.model.Plugin;
69 import org.apache.maven.project.MavenProject;
70 import org.apache.maven.project.ProjectBuilder;
71 import org.apache.maven.reporting.MavenReport;
72 import org.codehaus.plexus.i18n.I18N;
73 import org.codehaus.plexus.interpolation.EnvarBasedValueSource;
74 import org.codehaus.plexus.interpolation.InterpolationException;
75 import org.codehaus.plexus.interpolation.InterpolationPostProcessor;
76 import org.codehaus.plexus.interpolation.MapBasedValueSource;
77 import org.codehaus.plexus.interpolation.PrefixedObjectValueSource;
78 import org.codehaus.plexus.interpolation.PrefixedPropertiesValueSource;
79 import org.codehaus.plexus.interpolation.RegexBasedInterpolator;
80 import org.codehaus.plexus.util.IOUtil;
81 import org.codehaus.plexus.util.ReaderFactory;
82 import org.codehaus.plexus.util.StringUtils;
83 import org.codehaus.plexus.util.xml.Xpp3Dom;
84 import org.codehaus.plexus.util.xml.pull.MXParser;
85 import org.codehaus.plexus.util.xml.pull.XmlPullParser;
86 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
87 import org.eclipse.aether.RepositorySystem;
88 import org.eclipse.aether.RepositorySystemSession;
89 import org.eclipse.aether.repository.LocalArtifactRequest;
90 import org.eclipse.aether.repository.LocalArtifactResult;
91 import org.eclipse.aether.repository.LocalRepositoryManager;
92 import org.eclipse.aether.repository.RemoteRepository;
93 import org.eclipse.aether.resolution.ArtifactRequest;
94 import org.eclipse.aether.resolution.ArtifactResolutionException;
95 import org.eclipse.aether.resolution.ArtifactResult;
96 import org.eclipse.aether.transfer.ArtifactNotFoundException;
97 import org.slf4j.Logger;
98 import org.slf4j.LoggerFactory;
99
100
101
102
103
104
105 @Singleton
106 @Named
107 public class DefaultSiteTool implements SiteTool {
108 private static final Logger LOGGER = LoggerFactory.getLogger(DefaultSiteTool.class);
109
110
111
112
113
114
115
116
117 @Inject
118 protected RepositorySystem repositorySystem;
119
120
121
122
123 @Inject
124 private ArtifactHandlerManager artifactHandlerManager;
125
126
127
128
129 @Inject
130 protected I18N i18n;
131
132
133
134
135 @Inject
136 protected SiteModelInheritanceAssembler assembler;
137
138
139
140
141 @Inject
142 protected ProjectBuilder projectBuilder;
143
144
145
146
147
148
149 public Artifact getSkinArtifactFromRepository(
150 RepositorySystemSession repoSession, List<RemoteRepository> remoteProjectRepositories, Skin skin)
151 throws SiteToolException {
152 Objects.requireNonNull(repoSession, "repoSession cannot be null");
153 Objects.requireNonNull(remoteProjectRepositories, "remoteProjectRepositories cannot be null");
154 Objects.requireNonNull(skin, "skin cannot be null");
155
156 String version = skin.getVersion();
157 try {
158 if (version == null) {
159 version = Artifact.RELEASE_VERSION;
160 }
161 VersionRange versionSpec = VersionRange.createFromVersionSpec(version);
162 String type = "jar";
163 Artifact artifact = new DefaultArtifact(
164 skin.getGroupId(),
165 skin.getArtifactId(),
166 versionSpec,
167 Artifact.SCOPE_RUNTIME,
168 type,
169 null,
170 artifactHandlerManager.getArtifactHandler(type));
171 ArtifactRequest request =
172 new ArtifactRequest(RepositoryUtils.toArtifact(artifact), remoteProjectRepositories, "remote-skin");
173 ArtifactResult result = repositorySystem.resolveArtifact(repoSession, request);
174
175 return RepositoryUtils.toArtifact(result.getArtifact());
176 } catch (InvalidVersionSpecificationException e) {
177 throw new SiteToolException("The skin version '" + version + "' is not valid", e);
178 } catch (ArtifactResolutionException e) {
179 if (e.getCause() instanceof ArtifactNotFoundException) {
180 throw new SiteToolException("The skin does not exist", e.getCause());
181 }
182
183 throw new SiteToolException("Unable to find skin", e);
184 }
185 }
186
187
188
189
190
191
192 @Deprecated
193 public String getRelativePath(String to, String from) {
194 Objects.requireNonNull(to, "to cannot be null");
195 Objects.requireNonNull(from, "from cannot be null");
196
197 if (to.contains(":") && from.contains(":")) {
198 String toScheme = to.substring(0, to.lastIndexOf(':'));
199 String fromScheme = from.substring(0, from.lastIndexOf(':'));
200 if (!toScheme.equals(fromScheme)) {
201 return to;
202 }
203 }
204
205 URL toUrl = null;
206 URL fromUrl = null;
207
208 String toPath = to;
209 String fromPath = from;
210
211 try {
212 toUrl = new URL(to);
213 } catch (MalformedURLException e) {
214 try {
215 toUrl = new File(getNormalizedPath(to)).toURI().toURL();
216 } catch (MalformedURLException e1) {
217 LOGGER.warn("Unable to load a URL for '" + to + "'", e);
218 return to;
219 }
220 }
221
222 try {
223 fromUrl = new URL(from);
224 } catch (MalformedURLException e) {
225 try {
226 fromUrl = new File(getNormalizedPath(from)).toURI().toURL();
227 } catch (MalformedURLException e1) {
228 LOGGER.warn("Unable to load a URL for '" + from + "'", e);
229 return to;
230 }
231 }
232
233 if (toUrl != null && fromUrl != null) {
234
235
236 if ((toUrl.getProtocol().equalsIgnoreCase(fromUrl.getProtocol()))
237 && (toUrl.getHost().equalsIgnoreCase(fromUrl.getHost()))
238 && (toUrl.getPort() == fromUrl.getPort())) {
239
240
241 toPath = toUrl.getFile();
242 fromPath = fromUrl.getFile();
243 } else {
244
245
246 return to;
247 }
248 } else if ((toUrl != null && fromUrl == null) || (toUrl == null && fromUrl != null)) {
249
250
251 return to;
252 }
253
254
255
256
257
258 String relativePath = getRelativeFilePath(fromPath, toPath);
259
260 if (relativePath == null) {
261 relativePath = to;
262 }
263
264 if (LOGGER.isDebugEnabled() && !relativePath.toString().equals(to)) {
265 LOGGER.debug("Mapped url: " + to + " to relative path: " + relativePath);
266 }
267
268 return relativePath;
269 }
270
271 private static String getRelativeFilePath(final String oldPath, final String newPath) {
272
273
274 String fromPath = new File(oldPath).getPath();
275 String toPath = new File(newPath).getPath();
276
277
278 if (toPath.matches("^\\[a-zA-Z]:")) {
279 toPath = toPath.substring(1);
280 }
281 if (fromPath.matches("^\\[a-zA-Z]:")) {
282 fromPath = fromPath.substring(1);
283 }
284
285
286 if (fromPath.startsWith(":", 1)) {
287 fromPath = Character.toLowerCase(fromPath.charAt(0)) + fromPath.substring(1);
288 }
289 if (toPath.startsWith(":", 1)) {
290 toPath = Character.toLowerCase(toPath.charAt(0)) + toPath.substring(1);
291 }
292
293
294
295
296 if ((toPath.startsWith(":", 1) && fromPath.startsWith(":", 1))
297 && (!toPath.substring(0, 1).equals(fromPath.substring(0, 1)))) {
298
299
300
301 return null;
302 }
303
304 if ((toPath.startsWith(":", 1) && !fromPath.startsWith(":", 1))
305 || (!toPath.startsWith(":", 1) && fromPath.startsWith(":", 1))) {
306
307
308
309
310 return null;
311 }
312
313 final String relativePath = buildRelativePath(toPath, fromPath, File.separatorChar);
314
315 return relativePath.toString();
316 }
317
318
319 public File getSiteDescriptor(File siteDirectory, Locale locale) {
320 Objects.requireNonNull(siteDirectory, "siteDirectory cannot be null");
321 Objects.requireNonNull(locale, "locale cannot be null");
322
323 String variant = locale.getVariant();
324 String country = locale.getCountry();
325 String language = locale.getLanguage();
326
327 File siteDescriptor = null;
328
329 if (!variant.isEmpty()) {
330 siteDescriptor = new File(siteDirectory, "site_" + language + "_" + country + "_" + variant + ".xml");
331 }
332
333 if ((siteDescriptor == null || !siteDescriptor.isFile()) && !country.isEmpty()) {
334 siteDescriptor = new File(siteDirectory, "site_" + language + "_" + country + ".xml");
335 }
336
337 if ((siteDescriptor == null || !siteDescriptor.isFile()) && !language.isEmpty()) {
338 siteDescriptor = new File(siteDirectory, "site_" + language + ".xml");
339 }
340
341 if (siteDescriptor == null || !siteDescriptor.isFile()) {
342 siteDescriptor = new File(siteDirectory, "site.xml");
343 }
344
345 return siteDescriptor;
346 }
347
348
349
350
351
352
353
354
355
356
357
358
359
360 File getSiteDescriptorFromRepository(
361 MavenProject project,
362 RepositorySystemSession repoSession,
363 List<RemoteRepository> remoteProjectRepositories,
364 Locale locale)
365 throws SiteToolException {
366 Objects.requireNonNull(project, "project cannot be null");
367 Objects.requireNonNull(repoSession, "repoSession cannot be null");
368 Objects.requireNonNull(remoteProjectRepositories, "remoteProjectRepositories cannot be null");
369 Objects.requireNonNull(locale, "locale cannot be null");
370
371 try {
372 File siteDescriptor = resolveSiteDescriptor(project, repoSession, remoteProjectRepositories, locale);
373 if (siteDescriptor == null) {
374 LOGGER.debug("Site descriptor not found");
375 return null;
376 } else {
377 return siteDescriptor;
378 }
379 } catch (ArtifactResolutionException e) {
380 throw new SiteToolException("Unable to locate site descriptor", e);
381 }
382 }
383
384
385 public SiteModel getSiteModel(
386 File siteDirectory,
387 Locale locale,
388 MavenProject project,
389 List<MavenProject> reactorProjects,
390 RepositorySystemSession repoSession,
391 List<RemoteRepository> remoteProjectRepositories)
392 throws SiteToolException {
393 Objects.requireNonNull(locale, "locale cannot be null");
394 Objects.requireNonNull(project, "project cannot be null");
395 Objects.requireNonNull(reactorProjects, "reactorProjects cannot be null");
396 Objects.requireNonNull(repoSession, "repoSession cannot be null");
397 Objects.requireNonNull(remoteProjectRepositories, "remoteProjectRepositories cannot be null");
398
399 LOGGER.debug("Computing site model of '" + project.getId() + "' for "
400 + (locale.equals(SiteTool.DEFAULT_LOCALE) ? "default locale" : "locale '" + locale + "'"));
401
402 Map.Entry<SiteModel, MavenProject> result =
403 getSiteModel(0, siteDirectory, locale, project, repoSession, remoteProjectRepositories);
404 SiteModel siteModel = result.getKey();
405 MavenProject parentProject = result.getValue();
406
407 if (siteModel == null) {
408 LOGGER.debug("Using default site descriptor");
409 siteModel = getDefaultSiteModel();
410 }
411
412
413 String siteDescriptorContent = siteModelToString(siteModel);
414
415
416 siteDescriptorContent = getInterpolatedSiteDescriptorContent(project, siteDescriptorContent, false);
417
418 siteModel = readSiteModel(siteDescriptorContent, project, locale);
419
420 if (parentProject != null) {
421 populateParentMenu(siteModel, locale, project, parentProject, true);
422 }
423
424 try {
425 populateModulesMenu(siteModel, locale, project, reactorProjects, true);
426 } catch (IOException e) {
427 throw new SiteToolException("Error while populating modules menu", e);
428 }
429
430 return siteModel;
431 }
432
433
434 public String getInterpolatedSiteDescriptorContent(
435 Map<String, String> props, MavenProject aProject, String siteDescriptorContent) throws SiteToolException {
436 Objects.requireNonNull(props, "props cannot be null");
437
438
439 return getInterpolatedSiteDescriptorContent(aProject, siteDescriptorContent, false);
440 }
441
442 private String getInterpolatedSiteDescriptorContent(
443 MavenProject aProject, String siteDescriptorContent, boolean isEarly) throws SiteToolException {
444 Objects.requireNonNull(aProject, "aProject cannot be null");
445 Objects.requireNonNull(siteDescriptorContent, "siteDescriptorContent cannot be null");
446
447 RegexBasedInterpolator interpolator = new RegexBasedInterpolator();
448
449 if (isEarly) {
450 interpolator.addValueSource(new PrefixedObjectValueSource("this.", aProject));
451 interpolator.addValueSource(new PrefixedPropertiesValueSource("this.", aProject.getProperties()));
452 } else {
453 interpolator.addValueSource(new PrefixedObjectValueSource("project.", aProject));
454 interpolator.addValueSource(new MapBasedValueSource(aProject.getProperties()));
455
456 try {
457 interpolator.addValueSource(new EnvarBasedValueSource());
458 } catch (IOException e) {
459
460 throw new SiteToolException("Cannot interpolate environment properties", e);
461 }
462 }
463
464 interpolator.addPostProcessor(new InterpolationPostProcessor() {
465 @Override
466 public Object execute(String expression, Object value) {
467 if (value != null) {
468
469 return value.toString()
470 .replace("&", "&")
471 .replace("<", "<")
472 .replace(">", ">")
473 .replace("\"", """)
474 .replace("'", "'");
475 }
476 return null;
477 }
478 });
479
480 try {
481 return interpolator.interpolate(siteDescriptorContent);
482 } catch (InterpolationException e) {
483 throw new SiteToolException("Cannot interpolate site descriptor", e);
484 }
485 }
486
487
488
489
490
491
492
493
494
495
496
497 private void populateParentMenu(
498 SiteModel siteModel,
499 Locale locale,
500 MavenProject project,
501 MavenProject parentProject,
502 boolean keepInheritedRefs) {
503 Objects.requireNonNull(siteModel, "siteModel cannot be null");
504 Objects.requireNonNull(locale, "locale cannot be null");
505 Objects.requireNonNull(project, "project cannot be null");
506 Objects.requireNonNull(parentProject, "parentProject cannot be null");
507
508 Menu menu = siteModel.getMenuRef("parent");
509
510 if (menu == null) {
511 return;
512 }
513
514 if (keepInheritedRefs && menu.isInheritAsRef()) {
515 return;
516 }
517
518 String parentUrl = getDistMgmntSiteUrl(parentProject);
519
520 if (parentUrl != null) {
521 if (parentUrl.endsWith("/")) {
522 parentUrl += "index.html";
523 } else {
524 parentUrl += "/index.html";
525 }
526
527 parentUrl = getRelativePath(parentUrl, getDistMgmntSiteUrl(project));
528 } else {
529
530 File parentBasedir = parentProject.getBasedir();
531
532 if (parentBasedir != null) {
533
534 String parentPath = parentBasedir.getAbsolutePath();
535 String projectPath = project.getBasedir().getAbsolutePath();
536 parentUrl = getRelativePath(parentPath, projectPath) + "/index.html";
537 }
538 }
539
540
541 if (parentUrl == null) {
542 LOGGER.warn("Unable to find a URL to the parent project. The parent menu will NOT be added.");
543 } else {
544 if (menu.getName() == null) {
545 menu.setName(i18n.getString("site-tool", locale, "siteModel.menu.parentproject"));
546 }
547
548 MenuItem item = new MenuItem();
549 item.setName(parentProject.getName());
550 item.setHref(parentUrl);
551 menu.addItem(item);
552 }
553 }
554
555
556
557
558
559
560
561
562
563
564
565
566
567 private void populateModulesMenu(
568 SiteModel siteModel,
569 Locale locale,
570 MavenProject project,
571 List<MavenProject> reactorProjects,
572 boolean keepInheritedRefs)
573 throws SiteToolException, IOException {
574 Objects.requireNonNull(siteModel, "siteModel cannot be null");
575 Objects.requireNonNull(locale, "locale cannot be null");
576 Objects.requireNonNull(project, "project cannot be null");
577 Objects.requireNonNull(reactorProjects, "reactorProjects cannot be null");
578
579 Menu menu = siteModel.getMenuRef("modules");
580
581 if (menu == null) {
582 return;
583 }
584
585 if (keepInheritedRefs && menu.isInheritAsRef()) {
586 return;
587 }
588
589
590 if (!project.getModules().isEmpty()) {
591 if (menu.getName() == null) {
592 menu.setName(i18n.getString("site-tool", locale, "siteModel.menu.projectmodules"));
593 }
594
595 for (String module : project.getModules()) {
596 MavenProject moduleProject = getModuleFromReactor(project, reactorProjects, module);
597
598 if (moduleProject == null) {
599 LOGGER.debug("Module " + module + " not found in reactor");
600 continue;
601 }
602
603 final String pluginId = "org.apache.maven.plugins:maven-site-plugin";
604 String skipFlag = getPluginParameter(moduleProject, pluginId, "skip");
605 if (skipFlag == null) {
606 skipFlag = moduleProject.getProperties().getProperty("maven.site.skip");
607 }
608
609 String siteUrl = "true".equalsIgnoreCase(skipFlag) ? null : getDistMgmntSiteUrl(moduleProject);
610 String itemName =
611 (moduleProject.getName() == null) ? moduleProject.getArtifactId() : moduleProject.getName();
612 String defaultSiteUrl = "true".equalsIgnoreCase(skipFlag) ? null : moduleProject.getArtifactId();
613
614 appendMenuItem(project, menu, itemName, siteUrl, defaultSiteUrl);
615 }
616 } else if (siteModel.getMenuRef("modules").getInherit() == null) {
617
618 siteModel.removeMenuRef("modules");
619 }
620 }
621
622 private MavenProject getModuleFromReactor(MavenProject project, List<MavenProject> reactorProjects, String module)
623 throws IOException {
624 File moduleBasedir = new File(project.getBasedir(), module).getCanonicalFile();
625
626 for (MavenProject reactorProject : reactorProjects) {
627 if (moduleBasedir.equals(reactorProject.getBasedir())) {
628 return reactorProject;
629 }
630 }
631
632
633 return null;
634 }
635
636
637 public void populateReportsMenu(SiteModel siteModel, Locale locale, Map<String, List<MavenReport>> categories) {
638 Objects.requireNonNull(siteModel, "siteModel cannot be null");
639 Objects.requireNonNull(locale, "locale cannot be null");
640 Objects.requireNonNull(categories, "categories cannot be null");
641
642 Menu menu = siteModel.getMenuRef("reports");
643
644 if (menu == null) {
645 return;
646 }
647
648 if (menu.getName() == null) {
649 menu.setName(i18n.getString("site-tool", locale, "siteModel.menu.projectdocumentation"));
650 }
651
652 boolean found = false;
653 if (menu.getItems().isEmpty()) {
654 List<MavenReport> categoryReports = categories.get(MavenReport.CATEGORY_PROJECT_INFORMATION);
655 if (!isEmptyList(categoryReports)) {
656 MenuItem item = createCategoryMenu(
657 i18n.getString("site-tool", locale, "siteModel.menu.projectinformation"),
658 "/project-info.html",
659 categoryReports,
660 locale);
661 menu.getItems().add(item);
662 found = true;
663 }
664
665 categoryReports = categories.get(MavenReport.CATEGORY_PROJECT_REPORTS);
666 if (!isEmptyList(categoryReports)) {
667 MenuItem item = createCategoryMenu(
668 i18n.getString("site-tool", locale, "siteModel.menu.projectreports"),
669 "/project-reports.html",
670 categoryReports,
671 locale);
672 menu.getItems().add(item);
673 found = true;
674 }
675 }
676 if (!found) {
677 siteModel.removeMenuRef("reports");
678 }
679 }
680
681
682 public List<Locale> getSiteLocales(String locales) {
683 if (locales == null) {
684 return Collections.singletonList(DEFAULT_LOCALE);
685 }
686
687 String[] localesArray = StringUtils.split(locales, ",");
688 List<Locale> localesList = new ArrayList<>(localesArray.length);
689 List<Locale> availableLocales = Arrays.asList(Locale.getAvailableLocales());
690
691 for (String localeString : localesArray) {
692 Locale locale = codeToLocale(localeString);
693
694 if (locale == null) {
695 continue;
696 }
697
698 if (!availableLocales.contains(locale)) {
699 if (LOGGER.isWarnEnabled()) {
700 LOGGER.warn("The locale defined by '" + locale
701 + "' is not available in this Java Virtual Machine ("
702 + System.getProperty("java.version")
703 + " from " + System.getProperty("java.vendor") + ") - IGNORING");
704 }
705 continue;
706 }
707
708 Locale bundleLocale = i18n.getBundle("site-tool", locale).getLocale();
709 if (!(bundleLocale.equals(locale) || bundleLocale.getLanguage().equals(locale.getLanguage()))) {
710 if (LOGGER.isWarnEnabled()) {
711 LOGGER.warn("The locale '" + locale + "' (" + locale.getDisplayName(Locale.ENGLISH)
712 + ") is not currently supported by Maven Site - IGNORING."
713 + System.lineSeparator() + "Contributions are welcome and greatly appreciated!"
714 + System.lineSeparator() + "If you want to contribute a new translation, please visit "
715 + "https://maven.apache.org/plugins/localization.html for detailed instructions.");
716 }
717
718 continue;
719 }
720
721 localesList.add(locale);
722 }
723
724 if (localesList.isEmpty()) {
725 localesList = Collections.singletonList(DEFAULT_LOCALE);
726 }
727
728 return localesList;
729 }
730
731
732
733
734
735
736
737
738
739
740
741
742
743 private Locale codeToLocale(String localeCode) {
744 if (localeCode == null) {
745 return null;
746 }
747
748 if ("system".equalsIgnoreCase(localeCode)) {
749 return Locale.getDefault();
750 }
751
752 if ("default".equalsIgnoreCase(localeCode)) {
753 return SiteTool.DEFAULT_LOCALE;
754 }
755
756 String language = "";
757 String country = "";
758 String variant = "";
759
760 StringTokenizer tokenizer = new StringTokenizer(localeCode, "_");
761 final int maxTokens = 3;
762 if (tokenizer.countTokens() > maxTokens) {
763 if (LOGGER.isWarnEnabled()) {
764 LOGGER.warn("Invalid java.util.Locale format for '" + localeCode + "' entry - IGNORING");
765 }
766 return null;
767 }
768
769 if (tokenizer.hasMoreTokens()) {
770 language = tokenizer.nextToken();
771 if (tokenizer.hasMoreTokens()) {
772 country = tokenizer.nextToken();
773 if (tokenizer.hasMoreTokens()) {
774 variant = tokenizer.nextToken();
775 }
776 }
777 }
778
779 return new Locale(language, country, variant);
780 }
781
782
783
784
785
786
787
788
789
790
791 protected static String getNormalizedPath(String path) {
792 String normalized = FilenameUtils.normalize(path);
793 if (normalized == null) {
794 normalized = path;
795 }
796 return (normalized == null) ? null : normalized.replace('\\', '/');
797 }
798
799
800
801
802
803
804
805
806
807
808
809 private ArtifactRequest createSiteDescriptorArtifactRequest(
810 MavenProject project, String localeStr, List<RemoteRepository> remoteProjectRepositories) {
811 String type = "xml";
812 ArtifactHandler artifactHandler = artifactHandlerManager.getArtifactHandler(type);
813 Artifact artifact = new DefaultArtifact(
814 project.getGroupId(),
815 project.getArtifactId(),
816 project.getVersion(),
817 Artifact.SCOPE_RUNTIME,
818 type,
819 "site" + (localeStr.isEmpty() ? "" : "_" + localeStr),
820 artifactHandler);
821 return new ArtifactRequest(
822 RepositoryUtils.toArtifact(artifact), remoteProjectRepositories, "remote-site-descriptor");
823 }
824
825
826
827
828
829
830
831
832
833 private File resolveSiteDescriptor(
834 MavenProject project,
835 RepositorySystemSession repoSession,
836 List<RemoteRepository> remoteProjectRepositories,
837 Locale locale)
838 throws ArtifactResolutionException {
839 String variant = locale.getVariant();
840 String country = locale.getCountry();
841 String language = locale.getLanguage();
842
843 String localeStr = null;
844 File siteDescriptor = null;
845 boolean found = false;
846
847 if (!variant.isEmpty()) {
848 localeStr = language + "_" + country + "_" + variant;
849 ArtifactRequest request =
850 createSiteDescriptorArtifactRequest(project, localeStr, remoteProjectRepositories);
851
852 deletePseudoSiteDescriptorMarkerFile(repoSession, request);
853
854 try {
855 ArtifactResult result = repositorySystem.resolveArtifact(repoSession, request);
856
857 siteDescriptor = result.getArtifact().getFile();
858 found = true;
859 } catch (ArtifactResolutionException e) {
860
861 if (e.getResult().getExceptions().stream().anyMatch(re -> re instanceof ArtifactNotFoundException)) {
862 LOGGER.debug("No site descriptor found for '" + project.getId() + "' for locale '" + localeStr
863 + "', trying without variant...");
864 } else {
865 throw e;
866 }
867 }
868 }
869
870 if (!found && !country.isEmpty()) {
871 localeStr = language + "_" + country;
872 ArtifactRequest request =
873 createSiteDescriptorArtifactRequest(project, localeStr, remoteProjectRepositories);
874
875 deletePseudoSiteDescriptorMarkerFile(repoSession, request);
876
877 try {
878 ArtifactResult result = repositorySystem.resolveArtifact(repoSession, request);
879
880 siteDescriptor = result.getArtifact().getFile();
881 found = true;
882 } catch (ArtifactResolutionException e) {
883
884 if (e.getResult().getExceptions().stream().anyMatch(re -> re instanceof ArtifactNotFoundException)) {
885 LOGGER.debug("No site descriptor found for '" + project.getId() + "' for locale '" + localeStr
886 + "', trying without country...");
887 } else {
888 throw e;
889 }
890 }
891 }
892
893 if (!found && !language.isEmpty()) {
894 localeStr = language;
895 ArtifactRequest request =
896 createSiteDescriptorArtifactRequest(project, localeStr, remoteProjectRepositories);
897
898 deletePseudoSiteDescriptorMarkerFile(repoSession, request);
899
900 try {
901 ArtifactResult result = repositorySystem.resolveArtifact(repoSession, request);
902
903 siteDescriptor = result.getArtifact().getFile();
904 found = true;
905 } catch (ArtifactResolutionException e) {
906
907 if (e.getResult().getExceptions().stream().anyMatch(re -> re instanceof ArtifactNotFoundException)) {
908 LOGGER.debug("No site descriptor found for '" + project.getId() + "' for locale '" + localeStr
909 + "', trying without language (default locale)...");
910 } else {
911 throw e;
912 }
913 }
914 }
915
916 if (!found) {
917 localeStr = SiteTool.DEFAULT_LOCALE.toString();
918 ArtifactRequest request =
919 createSiteDescriptorArtifactRequest(project, localeStr, remoteProjectRepositories);
920
921 deletePseudoSiteDescriptorMarkerFile(repoSession, request);
922
923 try {
924 ArtifactResult result = repositorySystem.resolveArtifact(repoSession, request);
925
926 siteDescriptor = result.getArtifact().getFile();
927 } catch (ArtifactResolutionException e) {
928
929 if (e.getResult().getExceptions().stream().anyMatch(re -> re instanceof ArtifactNotFoundException)) {
930 LOGGER.debug("No site descriptor found for '" + project.getId() + "' with default locale");
931 return null;
932 }
933
934 throw e;
935 }
936 }
937
938 return siteDescriptor;
939 }
940
941
942 private void deletePseudoSiteDescriptorMarkerFile(RepositorySystemSession repoSession, ArtifactRequest request) {
943 LocalRepositoryManager lrm = repoSession.getLocalRepositoryManager();
944
945 LocalArtifactRequest localRequest =
946 new LocalArtifactRequest(request.getArtifact(), request.getRepositories(), request.getRequestContext());
947
948 LocalArtifactResult localResult = lrm.find(repoSession, localRequest);
949 File localArtifactFile = localResult.getFile();
950
951 try {
952 if (localResult.isAvailable() && Files.size(localArtifactFile.toPath()) == 0L) {
953 LOGGER.debug(
954 "Deleting 0-byte pseudo marker file for artifact '{}' at '{}'",
955 localRequest.getArtifact(),
956 localArtifactFile);
957 Files.delete(localArtifactFile.toPath());
958 }
959 } catch (IOException e) {
960 LOGGER.debug("Failed to delete 0-byte pseudo marker file for artifact '{}'", localRequest.getArtifact(), e);
961 }
962 }
963
964
965
966
967
968
969
970
971
972
973
974 private Map.Entry<SiteModel, MavenProject> getSiteModel(
975 int depth,
976 File siteDirectory,
977 Locale locale,
978 MavenProject project,
979 RepositorySystemSession repoSession,
980 List<RemoteRepository> remoteProjectRepositories)
981 throws SiteToolException {
982
983 File siteDescriptor;
984 if (project.getBasedir() == null) {
985
986 try {
987 siteDescriptor =
988 getSiteDescriptorFromRepository(project, repoSession, remoteProjectRepositories, locale);
989 } catch (SiteToolException e) {
990 throw new SiteToolException("The site descriptor cannot be resolved from the repository", e);
991 }
992 } else {
993
994 siteDescriptor = getSiteDescriptor(siteDirectory, locale);
995 }
996
997
998 SiteModel siteModel = null;
999 Reader siteDescriptorReader = null;
1000 try {
1001 if (siteDescriptor != null && siteDescriptor.exists()) {
1002 LOGGER.debug("Reading" + (depth == 0 ? "" : (" parent level " + depth)) + " site descriptor from "
1003 + siteDescriptor);
1004
1005 siteDescriptorReader = ReaderFactory.newXmlReader(siteDescriptor);
1006
1007 String siteDescriptorContent = IOUtil.toString(siteDescriptorReader);
1008
1009
1010 siteDescriptorContent = getInterpolatedSiteDescriptorContent(project, siteDescriptorContent, true);
1011
1012 siteModel = readSiteModel(siteDescriptorContent, project, locale);
1013 siteModel.setLastModified(siteDescriptor.lastModified());
1014 } else {
1015 LOGGER.debug("No" + (depth == 0 ? "" : (" parent level " + depth)) + " site descriptor");
1016 }
1017 } catch (IOException e) {
1018 throw new SiteToolException(
1019 "The site descriptor for '" + project.getId() + "' cannot be read from " + siteDescriptor, e);
1020 } finally {
1021 IOUtil.close(siteDescriptorReader);
1022 }
1023
1024
1025 MavenProject parentProject = project.getParent();
1026
1027
1028 if (parentProject != null && (siteModel == null || siteModel.isMergeParent())) {
1029 depth++;
1030 LOGGER.debug("Looking for site descriptor of level " + depth + " parent project: " + parentProject.getId());
1031
1032 File parentSiteDirectory = null;
1033 if (parentProject.getBasedir() != null) {
1034
1035 String siteRelativePath = getRelativeFilePath(
1036 project.getBasedir().getAbsolutePath(),
1037 siteDescriptor.getParentFile().getAbsolutePath());
1038
1039 parentSiteDirectory = new File(parentProject.getBasedir(), siteRelativePath);
1040
1041
1042 }
1043
1044 SiteModel parentSiteModel = getSiteModel(
1045 depth, parentSiteDirectory, locale, parentProject, repoSession, remoteProjectRepositories)
1046 .getKey();
1047
1048
1049
1050 if (siteModel == null && parentSiteModel != null) {
1051
1052
1053 siteModel = new SiteModel();
1054 }
1055
1056 String name = project.getName();
1057 if (siteModel != null && StringUtils.isNotEmpty(siteModel.getName())) {
1058 name = siteModel.getName();
1059 }
1060
1061
1062 String projectDistMgmnt = getDistMgmntSiteUrl(project);
1063 String parentDistMgmnt = getDistMgmntSiteUrl(parentProject);
1064 if (LOGGER.isDebugEnabled()) {
1065 LOGGER.debug("Site model inheritance: assembling child with level " + depth
1066 + " parent: distributionManagement.site.url child = " + projectDistMgmnt + " and parent = "
1067 + parentDistMgmnt);
1068 }
1069 assembler.assembleModelInheritance(
1070 name,
1071 siteModel,
1072 parentSiteModel,
1073 projectDistMgmnt,
1074 parentDistMgmnt == null ? projectDistMgmnt : parentDistMgmnt);
1075 }
1076
1077 return new AbstractMap.SimpleEntry<>(siteModel, parentProject);
1078 }
1079
1080
1081
1082
1083
1084
1085 private SiteModel readSiteModel(String siteDescriptorContent, MavenProject project, Locale locale)
1086 throws SiteToolException {
1087 try {
1088 if (project != null && isOldSiteModel(siteDescriptorContent)) {
1089 LOGGER.warn(
1090 "Site model of '" + project.getId() + "' for "
1091 + (locale.equals(SiteTool.DEFAULT_LOCALE)
1092 ? "default locale"
1093 : "locale '" + locale + "'")
1094 + " is still using the old pre-version 2.0.0 model. You MUST migrate to the new model as soon as possible otherwise your build will break in the future!");
1095 return convertOldToNewSiteModel(
1096 new DecorationXpp3Reader().read(new StringReader(siteDescriptorContent)));
1097 } else {
1098 return new SiteXpp3Reader().read(new StringReader(siteDescriptorContent));
1099 }
1100 } catch (XmlPullParserException e) {
1101 throw new SiteToolException("Error parsing site descriptor", e);
1102 } catch (IOException e) {
1103 throw new SiteToolException("Error reading site descriptor", e);
1104 }
1105 }
1106
1107 private SiteModel convertOldToNewSiteModel(DecorationModel oldModel) {
1108 SiteModel newModel = new SiteModel();
1109 newModel.setName(oldModel.getName());
1110 newModel.setCombineSelf(oldModel.getCombineSelf());
1111 if (oldModel.getBannerLeft() != null) {
1112 newModel.setBannerLeft(convertBanner(oldModel.getBannerLeft()));
1113 }
1114 if (oldModel.getBannerRight() != null) {
1115 newModel.setBannerRight(convertBanner(oldModel.getBannerRight()));
1116 }
1117 if (!oldModel.isDefaultPublishDate()) {
1118 PublishDate newPublishDate = new PublishDate();
1119 newPublishDate.setFormat(oldModel.getPublishDate().getFormat());
1120 newPublishDate.setPosition(oldModel.getPublishDate().getPosition());
1121 newPublishDate.setTimezone(oldModel.getPublishDate().getTimezone());
1122 newModel.setPublishDate(newPublishDate);
1123 }
1124 if (!oldModel.isDefaultVersion()) {
1125 Version newVersion = new Version();
1126 newVersion.setPosition(oldModel.getVersion().getPosition());
1127 newModel.setVersion(newVersion);
1128 }
1129 newModel.setEdit(oldModel.getEdit());
1130 if (oldModel.getSkin() != null) {
1131 Skin newSkin = new Skin();
1132 newSkin.setGroupId(oldModel.getSkin().getGroupId());
1133 newSkin.setArtifactId(oldModel.getSkin().getArtifactId());
1134 newSkin.setVersion(oldModel.getSkin().getVersion());
1135 newModel.setSkin(newSkin);
1136 }
1137
1138 for (org.apache.maven.doxia.site.decoration.Logo oldLogo : oldModel.getPoweredBy()) {
1139 Logo newLogo = new Logo();
1140 newLogo.setName(oldLogo.getName());
1141 newLogo.setHref(oldLogo.getHref());
1142 newLogo.setTarget(oldLogo.getTarget());
1143 if (oldLogo.getImg() != null) {
1144 newLogo.setImage(convertImage(
1145 oldLogo.getImg(),
1146 oldLogo.getPosition(),
1147 oldLogo.getHeight(),
1148 oldLogo.getWidth(),
1149 oldLogo.getBorder(),
1150 oldLogo.getAlt()));
1151 }
1152 newModel.addPoweredBy(newLogo);
1153 }
1154 newModel.setLastModified(oldModel.getLastModified());
1155 if (oldModel.getBody() != null) {
1156 Body newBody = new Body();
1157 newBody.setHead(oldModel.getBody().getHead());
1158 for (org.apache.maven.doxia.site.decoration.LinkItem oldLink :
1159 oldModel.getBody().getLinks()) {
1160 newBody.addLink(convertLinkItem(oldLink));
1161 }
1162 for (org.apache.maven.doxia.site.decoration.LinkItem oldBreadcrumb :
1163 oldModel.getBody().getBreadcrumbs()) {
1164 newBody.addBreadcrumb(convertLinkItem(oldBreadcrumb));
1165 }
1166
1167 for (org.apache.maven.doxia.site.decoration.Menu oldMenu :
1168 oldModel.getBody().getMenus()) {
1169 Menu newMenu = new Menu();
1170 newMenu.setName(oldMenu.getName());
1171 newMenu.setInherit(oldMenu.getInherit());
1172 newMenu.setInheritAsRef(oldMenu.isInheritAsRef());
1173 newMenu.setRef(oldMenu.getRef());
1174 if (oldMenu.getImg() != null) {
1175 newMenu.setImage(convertImage(
1176 oldMenu.getImg(),
1177 oldMenu.getPosition(),
1178 oldMenu.getHeight(),
1179 oldMenu.getWidth(),
1180 oldMenu.getBorder(),
1181 oldMenu.getAlt()));
1182 }
1183 newMenu.setItems(convertMenuItems(oldMenu.getItems()));
1184 newBody.addMenu(newMenu);
1185 }
1186
1187 newBody.setFooter(oldModel.getBody().getFooter());
1188 newModel.setBody(newBody);
1189 }
1190 newModel.setCustom(oldModel.getCustom());
1191
1192 return newModel;
1193 }
1194
1195 private Banner convertBanner(org.apache.maven.doxia.site.decoration.Banner oldBanner) {
1196 Banner newBanner = new Banner();
1197 newBanner.setName(oldBanner.getName());
1198 newBanner.setHref(oldBanner.getHref());
1199 if (oldBanner.getSrc() != null) {
1200 newBanner.setImage(convertImage(
1201 oldBanner.getSrc(),
1202 null,
1203 oldBanner.getHeight(),
1204 oldBanner.getWidth(),
1205 oldBanner.getBorder(),
1206 oldBanner.getAlt()));
1207 }
1208
1209 return newBanner;
1210 }
1211
1212 private Image convertImage(String src, String position, String height, String width, String border, String alt) {
1213 Image newImage = new Image();
1214 newImage.setSrc(src);
1215 newImage.setPosition(position);
1216 newImage.setHeight(height);
1217 newImage.setWidth(width);
1218 if (border != null) {
1219 newImage.setStyle("border: " + border + ";");
1220 }
1221 newImage.setAlt(alt);
1222
1223 return newImage;
1224 }
1225
1226 private LinkItem convertLinkItem(org.apache.maven.doxia.site.decoration.LinkItem oldLinkItem) {
1227 LinkItem newLinkItem = new LinkItem();
1228 newLinkItem.setName(oldLinkItem.getName());
1229 newLinkItem.setHref(oldLinkItem.getHref());
1230 newLinkItem.setTarget(oldLinkItem.getTarget());
1231 if (oldLinkItem.getImg() != null) {
1232 newLinkItem.setImage(convertImage(
1233 oldLinkItem.getImg(),
1234 oldLinkItem.getPosition(),
1235 oldLinkItem.getHeight(),
1236 oldLinkItem.getWidth(),
1237 oldLinkItem.getBorder(),
1238 oldLinkItem.getAlt()));
1239 }
1240
1241 return newLinkItem;
1242 }
1243
1244 private List<MenuItem> convertMenuItems(List<org.apache.maven.doxia.site.decoration.MenuItem> oldMenuItems) {
1245 List<MenuItem> newMenuItems = new ArrayList<>();
1246 for (org.apache.maven.doxia.site.decoration.MenuItem oldMenuItem : oldMenuItems) {
1247 MenuItem newMenuItem = new MenuItem();
1248 newMenuItem.setName(oldMenuItem.getName());
1249 newMenuItem.setHref(oldMenuItem.getHref());
1250 newMenuItem.setTarget(oldMenuItem.getTarget());
1251 newMenuItem.setCollapse(oldMenuItem.isCollapse());
1252 newMenuItem.setRef(oldMenuItem.getRef());
1253 newMenuItem.setItems(convertMenuItems(oldMenuItem.getItems()));
1254 if (oldMenuItem.getImg() != null) {
1255 newMenuItem.setImage(convertImage(
1256 oldMenuItem.getImg(),
1257 oldMenuItem.getPosition(),
1258 oldMenuItem.getHeight(),
1259 oldMenuItem.getWidth(),
1260 oldMenuItem.getBorder(),
1261 oldMenuItem.getAlt()));
1262 }
1263 newMenuItems.add(newMenuItem);
1264 }
1265
1266 return newMenuItems;
1267 }
1268
1269 private boolean isOldSiteModel(String siteDescriptorContent) throws XmlPullParserException, IOException {
1270 XmlPullParser parser = new MXParser();
1271 parser.setInput(new StringReader(siteDescriptorContent));
1272
1273 if (!(parser.getEventType() == XmlPullParser.START_DOCUMENT && parser.next() == XmlPullParser.START_TAG)) {
1274 return false;
1275 }
1276 if ("project".equals(parser.getName())) {
1277 return true;
1278 }
1279
1280 return false;
1281 }
1282
1283 private SiteModel getDefaultSiteModel() throws SiteToolException {
1284 String siteDescriptorContent;
1285
1286 Reader reader = null;
1287 try {
1288 reader = ReaderFactory.newXmlReader(getClass().getResourceAsStream("/default-site.xml"));
1289 siteDescriptorContent = IOUtil.toString(reader);
1290 } catch (IOException e) {
1291 throw new SiteToolException("Error reading default site descriptor", e);
1292 } finally {
1293 IOUtil.close(reader);
1294 }
1295
1296 return readSiteModel(siteDescriptorContent, null, SiteTool.DEFAULT_LOCALE);
1297 }
1298
1299 private String siteModelToString(SiteModel siteModel) throws SiteToolException {
1300 StringWriter writer = new StringWriter();
1301
1302 try {
1303 new SiteXpp3Writer().write(writer, siteModel);
1304 return writer.toString();
1305 } catch (IOException e) {
1306 throw new SiteToolException("Error reading site descriptor", e);
1307 } finally {
1308 IOUtil.close(writer);
1309 }
1310 }
1311
1312 private static String buildRelativePath(final String toPath, final String fromPath, final char separatorChar) {
1313
1314 StringTokenizer toTokeniser = new StringTokenizer(toPath, String.valueOf(separatorChar));
1315 StringTokenizer fromTokeniser = new StringTokenizer(fromPath, String.valueOf(separatorChar));
1316
1317 int count = 0;
1318
1319
1320 while (toTokeniser.hasMoreTokens() && fromTokeniser.hasMoreTokens()) {
1321 if (separatorChar == '\\') {
1322 if (!fromTokeniser.nextToken().equalsIgnoreCase(toTokeniser.nextToken())) {
1323 break;
1324 }
1325 } else {
1326 if (!fromTokeniser.nextToken().equals(toTokeniser.nextToken())) {
1327 break;
1328 }
1329 }
1330
1331 count++;
1332 }
1333
1334
1335
1336
1337 toTokeniser = new StringTokenizer(toPath, String.valueOf(separatorChar));
1338 fromTokeniser = new StringTokenizer(fromPath, String.valueOf(separatorChar));
1339
1340 while (count-- > 0) {
1341 fromTokeniser.nextToken();
1342 toTokeniser.nextToken();
1343 }
1344
1345 StringBuilder relativePath = new StringBuilder();
1346
1347
1348 while (fromTokeniser.hasMoreTokens()) {
1349 fromTokeniser.nextToken();
1350
1351 relativePath.append("..");
1352
1353 if (fromTokeniser.hasMoreTokens()) {
1354 relativePath.append(separatorChar);
1355 }
1356 }
1357
1358 if (relativePath.length() != 0 && toTokeniser.hasMoreTokens()) {
1359 relativePath.append(separatorChar);
1360 }
1361
1362
1363 while (toTokeniser.hasMoreTokens()) {
1364 relativePath.append(toTokeniser.nextToken());
1365
1366 if (toTokeniser.hasMoreTokens()) {
1367 relativePath.append(separatorChar);
1368 }
1369 }
1370 return relativePath.toString();
1371 }
1372
1373
1374
1375
1376
1377
1378
1379
1380 private void appendMenuItem(MavenProject project, Menu menu, String name, String href, String defaultHref) {
1381 String selectedHref = href;
1382
1383 if (selectedHref == null) {
1384 selectedHref = defaultHref;
1385 }
1386
1387 MenuItem item = new MenuItem();
1388 item.setName(name);
1389
1390 if (selectedHref != null) {
1391 String baseUrl = getDistMgmntSiteUrl(project);
1392 if (baseUrl != null) {
1393 selectedHref = getRelativePath(selectedHref, baseUrl);
1394 }
1395
1396 if (selectedHref.endsWith("/")) {
1397 item.setHref(selectedHref + "index.html");
1398 } else {
1399 item.setHref(selectedHref + "/index.html");
1400 }
1401 }
1402 menu.addItem(item);
1403 }
1404
1405
1406
1407
1408
1409
1410
1411
1412 private MenuItem createCategoryMenu(String name, String href, List<MavenReport> categoryReports, Locale locale) {
1413 MenuItem item = new MenuItem();
1414 item.setName(name);
1415 item.setCollapse(true);
1416 item.setHref(href);
1417
1418
1419
1420
1421 for (MavenReport report : categoryReports) {
1422 MenuItem subitem = new MenuItem();
1423 subitem.setName(report.getName(locale));
1424 subitem.setHref(report.getOutputName() + ".html");
1425 item.getItems().add(subitem);
1426 }
1427
1428 return item;
1429 }
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441 private static boolean isEmptyList(List<?> list) {
1442 return list == null || list.isEmpty();
1443 }
1444
1445
1446
1447
1448
1449
1450
1451 private static String getDistMgmntSiteUrl(MavenProject project) {
1452 return getDistMgmntSiteUrl(project.getDistributionManagement());
1453 }
1454
1455 private static String getDistMgmntSiteUrl(DistributionManagement distMgmnt) {
1456 if (distMgmnt != null
1457 && distMgmnt.getSite() != null
1458 && distMgmnt.getSite().getUrl() != null) {
1459
1460 return urlEncode(distMgmnt.getSite().getUrl());
1461 }
1462
1463 return null;
1464 }
1465
1466
1467
1468
1469
1470
1471 private static Plugin getPlugin(MavenProject project, String pluginId) {
1472 if ((project.getBuild() == null) || (project.getBuild().getPluginsAsMap() == null)) {
1473 return null;
1474 }
1475
1476 Plugin plugin = project.getBuild().getPluginsAsMap().get(pluginId);
1477
1478 if ((plugin == null)
1479 && (project.getBuild().getPluginManagement() != null)
1480 && (project.getBuild().getPluginManagement().getPluginsAsMap() != null)) {
1481 plugin = project.getBuild().getPluginManagement().getPluginsAsMap().get(pluginId);
1482 }
1483
1484 return plugin;
1485 }
1486
1487
1488
1489
1490
1491
1492
1493 private static String getPluginParameter(MavenProject project, String pluginId, String param) {
1494 Plugin plugin = getPlugin(project, pluginId);
1495 if (plugin != null) {
1496 Xpp3Dom xpp3Dom = (Xpp3Dom) plugin.getConfiguration();
1497 if (xpp3Dom != null
1498 && xpp3Dom.getChild(param) != null
1499 && StringUtils.isNotEmpty(xpp3Dom.getChild(param).getValue())) {
1500 return xpp3Dom.getChild(param).getValue();
1501 }
1502 }
1503
1504 return null;
1505 }
1506
1507 private static String urlEncode(final String url) {
1508 if (url == null) {
1509 return null;
1510 }
1511
1512 try {
1513 return new File(url).toURI().toURL().toExternalForm();
1514 } catch (MalformedURLException ex) {
1515 return url;
1516 }
1517 }
1518 }