Java tutorial
package org.apache.maven.settings.building; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.File; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.util.Collections; import java.util.List; import java.util.Map; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; import org.apache.maven.building.FileSource; import org.apache.maven.building.Source; import org.apache.maven.settings.Settings; import org.apache.maven.settings.TrackableBase; import org.apache.maven.settings.io.SettingsParseException; import org.apache.maven.settings.io.SettingsReader; import org.apache.maven.settings.io.SettingsWriter; import org.apache.maven.settings.merge.MavenSettingsMerger; import org.apache.maven.settings.validation.SettingsValidator; import org.codehaus.plexus.interpolation.EnvarBasedValueSource; import org.codehaus.plexus.interpolation.InterpolationException; import org.codehaus.plexus.interpolation.InterpolationPostProcessor; import org.codehaus.plexus.interpolation.PropertiesBasedValueSource; import org.codehaus.plexus.interpolation.RegexBasedInterpolator; /** * Builds the effective settings from a user settings file and/or a global settings file. * * @author Benjamin Bentmann */ @Named @Singleton public class DefaultSettingsBuilder implements SettingsBuilder { private SettingsReader settingsReader; private SettingsWriter settingsWriter; private SettingsValidator settingsValidator; private final MavenSettingsMerger settingsMerger = new MavenSettingsMerger(); @Inject public DefaultSettingsBuilder(SettingsReader settingsReader, SettingsWriter settingsWriter, SettingsValidator settingsValidator) { this.settingsReader = settingsReader; this.settingsWriter = settingsWriter; this.settingsValidator = settingsValidator; } public DefaultSettingsBuilder setSettingsReader(SettingsReader settingsReader) { this.settingsReader = settingsReader; return this; } public DefaultSettingsBuilder setSettingsWriter(SettingsWriter settingsWriter) { this.settingsWriter = settingsWriter; return this; } public DefaultSettingsBuilder setSettingsValidator(SettingsValidator settingsValidator) { this.settingsValidator = settingsValidator; return this; } @Override public SettingsBuildingResult build(SettingsBuildingRequest request) throws SettingsBuildingException { DefaultSettingsProblemCollector problems = new DefaultSettingsProblemCollector(null); Source globalSettingsSource = getSettingsSource(request.getGlobalSettingsFile(), request.getGlobalSettingsSource()); Settings globalSettings = readSettings(globalSettingsSource, request, problems); Source userSettingsSource = getSettingsSource(request.getUserSettingsFile(), request.getUserSettingsSource()); Settings userSettings = readSettings(userSettingsSource, request, problems); settingsMerger.merge(userSettings, globalSettings, TrackableBase.GLOBAL_LEVEL); problems.setSource(""); userSettings = interpolate(userSettings, request, problems); // for the special case of a drive-relative Windows path, make sure it's absolute to save plugins from trouble String localRepository = userSettings.getLocalRepository(); if (localRepository != null && localRepository.length() > 0) { File file = new File(localRepository); if (!file.isAbsolute() && file.getPath().startsWith(File.separator)) { userSettings.setLocalRepository(file.getAbsolutePath()); } } if (hasErrors(problems.getProblems())) { throw new SettingsBuildingException(problems.getProblems()); } return new DefaultSettingsBuildingResult(userSettings, problems.getProblems()); } private boolean hasErrors(List<SettingsProblem> problems) { if (problems != null) { for (SettingsProblem problem : problems) { if (SettingsProblem.Severity.ERROR.compareTo(problem.getSeverity()) >= 0) { return true; } } } return false; } private Source getSettingsSource(File settingsFile, Source settingsSource) { if (settingsSource != null) { return settingsSource; } else if (settingsFile != null && settingsFile.exists()) { return new FileSource(settingsFile); } return null; } private Settings readSettings(Source settingsSource, SettingsBuildingRequest request, DefaultSettingsProblemCollector problems) { if (settingsSource == null) { return new Settings(); } problems.setSource(settingsSource.getLocation()); Settings settings; try { Map<String, ?> options = Collections.singletonMap(SettingsReader.IS_STRICT, Boolean.TRUE); try { settings = settingsReader.read(settingsSource.getInputStream(), options); } catch (SettingsParseException e) { options = Collections.singletonMap(SettingsReader.IS_STRICT, Boolean.FALSE); settings = settingsReader.read(settingsSource.getInputStream(), options); problems.add(SettingsProblem.Severity.WARNING, e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e); } } catch (SettingsParseException e) { problems.add(SettingsProblem.Severity.FATAL, "Non-parseable settings " + settingsSource.getLocation() + ": " + e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e); return new Settings(); } catch (IOException e) { problems.add(SettingsProblem.Severity.FATAL, "Non-readable settings " + settingsSource.getLocation() + ": " + e.getMessage(), -1, -1, e); return new Settings(); } settingsValidator.validate(settings, problems); return settings; } private Settings interpolate(Settings settings, SettingsBuildingRequest request, SettingsProblemCollector problems) { StringWriter writer = new StringWriter(1024 * 4); try { settingsWriter.write(writer, null, settings); } catch (IOException e) { throw new IllegalStateException("Failed to serialize settings to memory", e); } String serializedSettings = writer.toString(); RegexBasedInterpolator interpolator = new RegexBasedInterpolator(); interpolator.addValueSource(new PropertiesBasedValueSource(request.getUserProperties())); interpolator.addValueSource(new PropertiesBasedValueSource(request.getSystemProperties())); try { interpolator.addValueSource(new EnvarBasedValueSource()); } catch (IOException e) { problems.add(SettingsProblem.Severity.WARNING, "Failed to use environment variables for interpolation: " + e.getMessage(), -1, -1, e); } interpolator.addPostProcessor(new InterpolationPostProcessor() { @Override public Object execute(String expression, Object value) { if (value != null) { // we're going to parse this back in as XML so we need to escape XML markup value = value.toString().replace("&", "&").replace("<", "<").replace(">", ">"); return value; } return null; } }); try { serializedSettings = interpolator.interpolate(serializedSettings, "settings"); } catch (InterpolationException e) { problems.add(SettingsProblem.Severity.ERROR, "Failed to interpolate settings: " + e.getMessage(), -1, -1, e); return settings; } Settings result; try { Map<String, ?> options = Collections.singletonMap(SettingsReader.IS_STRICT, Boolean.FALSE); result = settingsReader.read(new StringReader(serializedSettings), options); } catch (IOException e) { problems.add(SettingsProblem.Severity.ERROR, "Failed to interpolate settings: " + e.getMessage(), -1, -1, e); return settings; } return result; } }