mirror of https://github.com/apache/maven.git
o got rid of all the settings related code and use the settings builder directly and push the responsibility of
dealing with settings semantics to the client code git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@512550 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
737d36b126
commit
17a0c66920
|
@ -11,9 +11,7 @@ import org.apache.maven.model.Repository;
|
|||
import org.apache.maven.model.RepositoryBase;
|
||||
import org.apache.maven.model.RepositoryPolicy;
|
||||
import org.apache.maven.settings.MavenSettingsBuilder;
|
||||
import org.apache.maven.settings.RuntimeInfo;
|
||||
import org.apache.maven.settings.Settings;
|
||||
import org.apache.maven.settings.SettingsBuilderAdvice;
|
||||
import org.apache.maven.settings.io.jdom.SettingsJDOMWriter;
|
||||
import org.apache.maven.settings.io.xpp3.SettingsXpp3Reader;
|
||||
import org.apache.maven.settings.validation.SettingsValidationResult;
|
||||
|
@ -37,33 +35,20 @@ import java.util.ArrayList;
|
|||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Jason van Zyl
|
||||
*/
|
||||
/** @author Jason van Zyl */
|
||||
public class DefaultMavenTools
|
||||
implements MavenTools,
|
||||
Contextualizable
|
||||
implements MavenTools, Contextualizable
|
||||
{
|
||||
private ArtifactRepositoryLayout repositoryLayout;
|
||||
|
||||
private ArtifactRepositoryFactory artifactRepositoryFactory;
|
||||
|
||||
private MavenSettingsBuilder settingsBuilder;
|
||||
|
||||
private SettingsValidator settingsValidator;
|
||||
|
||||
private PlexusContainer container;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ArtifactRepository
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
public ArtifactRepository createDefaultLocalRepository()
|
||||
throws SettingsConfigurationException
|
||||
{
|
||||
return createLocalRepository( new File( getLocalRepositoryPath() ) );
|
||||
}
|
||||
|
||||
public ArtifactRepository createLocalRepository( File directory )
|
||||
{
|
||||
String localRepositoryUrl = directory.getAbsolutePath();
|
||||
|
@ -73,100 +58,17 @@ public class DefaultMavenTools
|
|||
localRepositoryUrl = "file://" + localRepositoryUrl;
|
||||
}
|
||||
|
||||
return createRepository( "local", localRepositoryUrl);
|
||||
return createRepository( "local", localRepositoryUrl );
|
||||
}
|
||||
|
||||
private ArtifactRepository createRepository( String repositoryId,
|
||||
String repositoryUrl)
|
||||
String repositoryUrl )
|
||||
{
|
||||
ArtifactRepository localRepository =
|
||||
new DefaultArtifactRepository( repositoryId, repositoryUrl, repositoryLayout );
|
||||
return localRepository;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Settings
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
public Settings buildSettings( File userSettingsPath,
|
||||
File globalSettingsPath,
|
||||
boolean interactive,
|
||||
boolean offline,
|
||||
boolean usePluginRegistry,
|
||||
boolean pluginUpdateOverride )
|
||||
throws SettingsConfigurationException
|
||||
{
|
||||
return buildSettings( userSettingsPath, globalSettingsPath, interactive, offline, usePluginRegistry,
|
||||
pluginUpdateOverride, new SettingsBuilderAdvice() );
|
||||
}
|
||||
|
||||
public Settings buildSettings( File userSettingsPath,
|
||||
File globalSettingsPath,
|
||||
boolean interactive,
|
||||
boolean offline,
|
||||
boolean usePluginRegistry,
|
||||
boolean pluginUpdateOverride,
|
||||
SettingsBuilderAdvice advice )
|
||||
throws SettingsConfigurationException
|
||||
{
|
||||
Settings settings = buildSettings( userSettingsPath, globalSettingsPath, pluginUpdateOverride, advice );
|
||||
|
||||
if ( offline )
|
||||
{
|
||||
settings.setOffline( true );
|
||||
}
|
||||
|
||||
settings.setInteractiveMode( interactive );
|
||||
|
||||
settings.setUsePluginRegistry( usePluginRegistry );
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
public Settings buildSettings( File userSettingsPath,
|
||||
File globalSettingsPath,
|
||||
boolean pluginUpdateOverride )
|
||||
throws SettingsConfigurationException
|
||||
{
|
||||
return buildSettings( userSettingsPath, globalSettingsPath, pluginUpdateOverride, new SettingsBuilderAdvice() );
|
||||
}
|
||||
|
||||
public Settings buildSettings( File userSettingsPath,
|
||||
File globalSettingsPath,
|
||||
boolean pluginUpdateOverride,
|
||||
SettingsBuilderAdvice advice )
|
||||
throws SettingsConfigurationException
|
||||
{
|
||||
Settings settings;
|
||||
|
||||
if ( advice == null )
|
||||
{
|
||||
advice = new SettingsBuilderAdvice();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
settings = settingsBuilder.buildSettings( userSettingsPath, globalSettingsPath, advice );
|
||||
}
|
||||
catch ( IOException e )
|
||||
{
|
||||
throw new SettingsConfigurationException( "Error reading settings file", e );
|
||||
}
|
||||
catch ( XmlPullParserException e )
|
||||
{
|
||||
throw new SettingsConfigurationException( e.getMessage(), e.getDetail(), e.getLineNumber(),
|
||||
e.getColumnNumber() );
|
||||
}
|
||||
|
||||
RuntimeInfo runtimeInfo = new RuntimeInfo( settings );
|
||||
|
||||
runtimeInfo.setPluginUpdateOverride( Boolean.valueOf( pluginUpdateOverride ) );
|
||||
|
||||
settings.setRuntimeInfo( runtimeInfo );
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Code snagged from ProjectUtils: this will have to be moved somewhere else
|
||||
// but just trying to collect it all in one place right now.
|
||||
|
@ -237,12 +139,15 @@ public class DefaultMavenTools
|
|||
public ArtifactRepositoryPolicy buildArtifactRepositoryPolicy( RepositoryPolicy policy )
|
||||
{
|
||||
boolean enabled = true;
|
||||
|
||||
String updatePolicy = null;
|
||||
|
||||
String checksumPolicy = null;
|
||||
|
||||
if ( policy != null )
|
||||
{
|
||||
enabled = policy.isEnabled();
|
||||
|
||||
if ( policy.getUpdatePolicy() != null )
|
||||
{
|
||||
updatePolicy = policy.getUpdatePolicy();
|
||||
|
@ -274,105 +179,6 @@ public class DefaultMavenTools
|
|||
return repositoryLayout;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Retrieve the user settings path using the followiwin search pattern:
|
||||
* <p/>
|
||||
* 1. System Property
|
||||
* 2. Optional path
|
||||
* 3. ${user.home}/.m2/settings.xml
|
||||
*/
|
||||
public File getUserSettingsPath( String optionalSettingsPath )
|
||||
{
|
||||
File userSettingsPath = new File( System.getProperty( ALT_USER_SETTINGS_XML_LOCATION ) + "" );
|
||||
|
||||
if ( !userSettingsPath.exists() )
|
||||
{
|
||||
if ( optionalSettingsPath != null )
|
||||
{
|
||||
File optionalSettingsPathFile = new File( optionalSettingsPath );
|
||||
|
||||
if ( optionalSettingsPathFile.exists() )
|
||||
{
|
||||
userSettingsPath = optionalSettingsPathFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
userSettingsPath = defaultUserSettingsFile;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
userSettingsPath = defaultUserSettingsFile;
|
||||
}
|
||||
}
|
||||
|
||||
return userSettingsPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the global settings path using the followiwin search pattern:
|
||||
* <p/>
|
||||
* 1. System Property
|
||||
* 2. CLI Option
|
||||
* 3. ${maven.home}/conf/settings.xml
|
||||
*/
|
||||
public File getGlobalSettingsPath()
|
||||
{
|
||||
File globalSettingsFile = new File( System.getProperty( ALT_GLOBAL_SETTINGS_XML_LOCATION ) + "" );
|
||||
|
||||
if ( !globalSettingsFile.exists() )
|
||||
{
|
||||
globalSettingsFile = defaultGlobalSettingsFile;
|
||||
}
|
||||
|
||||
return globalSettingsFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the local repository path using the followiwin search pattern:
|
||||
* <p/>
|
||||
* 1. System Property
|
||||
* 2. localRepository specified in user settings file
|
||||
* 3. ${user.home}/.m2/repository
|
||||
*/
|
||||
public String getLocalRepositoryPath( Settings settings )
|
||||
{
|
||||
String localRepositoryPath = System.getProperty( ALT_LOCAL_REPOSITORY_LOCATION );
|
||||
|
||||
if ( localRepositoryPath == null )
|
||||
{
|
||||
localRepositoryPath = settings.getLocalRepository();
|
||||
}
|
||||
|
||||
if ( localRepositoryPath == null )
|
||||
{
|
||||
localRepositoryPath = defaultUserLocalRepository.getAbsolutePath();
|
||||
}
|
||||
|
||||
return localRepositoryPath;
|
||||
}
|
||||
|
||||
public String getLocalRepositoryPath()
|
||||
throws SettingsConfigurationException
|
||||
{
|
||||
return getLocalRepositoryPath( buildSettings( getUserSettingsPath( null ),
|
||||
getGlobalSettingsPath(),
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false ) );
|
||||
}
|
||||
|
||||
public ArtifactRepository getLocalRepository()
|
||||
throws SettingsConfigurationException
|
||||
{
|
||||
return createLocalRepository( new File( getLocalRepositoryPath() ) );
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Lifecycle
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -382,51 +188,4 @@ public class DefaultMavenTools
|
|||
{
|
||||
container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
|
||||
}
|
||||
|
||||
public void writeSettings( Settings settings, Writer w )
|
||||
throws IOException
|
||||
{
|
||||
SettingsValidationResult validationResult = settingsValidator.validate( settings );
|
||||
|
||||
if ( validationResult.getMessageCount() > 0 )
|
||||
{
|
||||
throw new IOException( "Failed to validate Settings.\n" + validationResult.render("\n") );
|
||||
}
|
||||
|
||||
Element root = new Element( "settings" );
|
||||
|
||||
Document doc = new Document( root );
|
||||
|
||||
SettingsJDOMWriter writer = new SettingsJDOMWriter();
|
||||
|
||||
String encoding = settings.getModelEncoding() != null ? settings.getModelEncoding() : "UTF-8";
|
||||
|
||||
Format format = Format.getPrettyFormat().setEncoding( encoding );
|
||||
|
||||
writer.write( settings, doc, w, format );
|
||||
}
|
||||
|
||||
public Settings readSettings( Reader r )
|
||||
throws IOException, SettingsConfigurationException
|
||||
{
|
||||
SettingsXpp3Reader reader = new SettingsXpp3Reader();
|
||||
try
|
||||
{
|
||||
Settings settings = reader.read( r );
|
||||
|
||||
SettingsValidationResult validationResult = settingsValidator.validate( settings );
|
||||
|
||||
if ( validationResult.getMessageCount() > 0 )
|
||||
{
|
||||
throw new IOException( "Failed to validate Settings.\n" + validationResult.render("\n") );
|
||||
}
|
||||
|
||||
return settings;
|
||||
}
|
||||
catch ( XmlPullParserException e )
|
||||
{
|
||||
throw new SettingsConfigurationException( "Failed to parse settings.", e );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,9 +4,7 @@ import org.apache.maven.artifact.InvalidRepositoryException;
|
|||
import org.apache.maven.artifact.repository.ArtifactRepository;
|
||||
import org.apache.maven.model.DeploymentRepository;
|
||||
import org.apache.maven.model.Repository;
|
||||
import org.apache.maven.settings.MavenSettingsBuilder;
|
||||
import org.apache.maven.settings.Settings;
|
||||
import org.apache.maven.settings.SettingsBuilderAdvice;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
@ -21,82 +19,6 @@ public interface MavenTools
|
|||
{
|
||||
String ROLE = MavenTools.class.getName();
|
||||
|
||||
String userHome = System.getProperty( "user.home" );
|
||||
|
||||
File userMavenConfigurationHome = new File( userHome, ".m2" );
|
||||
|
||||
String mavenHome = System.getProperty( "maven.home" );
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Settings
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
File defaultUserSettingsFile = MavenSettingsBuilder.DEFAULT_USER_SETTINGS_FILE;
|
||||
|
||||
File defaultGlobalSettingsFile = MavenSettingsBuilder.DEFAULT_GLOBAL_SETTINGS_FILE;
|
||||
|
||||
String ALT_USER_SETTINGS_XML_LOCATION = "org.apache.maven.user-settings";
|
||||
|
||||
String ALT_GLOBAL_SETTINGS_XML_LOCATION = "org.apache.maven.global-settings";
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Local Repository
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
String ALT_LOCAL_REPOSITORY_LOCATION = "maven.repo.local";
|
||||
|
||||
File defaultUserLocalRepository = new File( userMavenConfigurationHome, "repository" );
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
ArtifactRepository createDefaultLocalRepository()
|
||||
throws SettingsConfigurationException;
|
||||
|
||||
ArtifactRepository createLocalRepository( File localRepositoryPath );
|
||||
|
||||
Settings buildSettings( File userSettingsPath,
|
||||
File globalSettingsPath,
|
||||
boolean interactive,
|
||||
boolean offline,
|
||||
boolean usePluginRegistry,
|
||||
boolean pluginUpdateOverride,
|
||||
SettingsBuilderAdvice advice )
|
||||
throws SettingsConfigurationException;
|
||||
|
||||
Settings buildSettings( File userSettingsPath,
|
||||
File globalSettingsPath,
|
||||
boolean interactive,
|
||||
boolean offline,
|
||||
boolean usePluginRegistry,
|
||||
boolean pluginUpdateOverride )
|
||||
throws SettingsConfigurationException;
|
||||
|
||||
Settings buildSettings( File userSettingsPath,
|
||||
File globalSettingsPath,
|
||||
boolean pluginUpdateOverride,
|
||||
SettingsBuilderAdvice advice )
|
||||
throws SettingsConfigurationException;
|
||||
|
||||
Settings buildSettings( File userSettingsPath,
|
||||
File globalSettingsPath,
|
||||
boolean pluginUpdateOverride )
|
||||
throws SettingsConfigurationException;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Methods taken from CLI
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
File getUserSettingsPath( String optionalSettingsPath );
|
||||
|
||||
File getGlobalSettingsPath();
|
||||
|
||||
String getLocalRepositoryPath( Settings settings );
|
||||
|
||||
String getLocalRepositoryPath()
|
||||
throws SettingsConfigurationException;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Methods taken from ProjectUtils
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -109,11 +31,4 @@ public interface MavenTools
|
|||
|
||||
ArtifactRepository buildArtifactRepository( Repository repo )
|
||||
throws InvalidRepositoryException;
|
||||
|
||||
void writeSettings( Settings settings, Writer writer )
|
||||
throws IOException;
|
||||
|
||||
Settings readSettings( Reader reader )
|
||||
throws IOException, SettingsConfigurationException;
|
||||
|
||||
}
|
||||
|
|
|
@ -11,12 +11,6 @@
|
|||
<requirement>
|
||||
<role>org.apache.maven.artifact.repository.ArtifactRepositoryFactory</role>
|
||||
</requirement>
|
||||
<requirement>
|
||||
<role>org.apache.maven.settings.MavenSettingsBuilder</role>
|
||||
</requirement>
|
||||
<requirement>
|
||||
<role>org.apache.maven.settings.validation.SettingsValidator</role>
|
||||
</requirement>
|
||||
</requirements>
|
||||
</component>
|
||||
</components>
|
||||
|
|
|
@ -1,192 +0,0 @@
|
|||
package org.apache.maven;
|
||||
|
||||
import org.apache.maven.settings.Profile;
|
||||
import org.apache.maven.settings.Repository;
|
||||
import org.apache.maven.settings.Settings;
|
||||
import org.apache.maven.settings.io.xpp3.SettingsXpp3Reader;
|
||||
import org.apache.maven.settings.io.xpp3.SettingsXpp3Writer;
|
||||
import org.codehaus.plexus.PlexusTestCase;
|
||||
import org.codehaus.plexus.util.IOUtil;
|
||||
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
|
||||
public abstract class AbstractMavenToolsTest
|
||||
extends PlexusTestCase
|
||||
{
|
||||
|
||||
private MavenTools mavenTools;
|
||||
|
||||
public void setUp()
|
||||
throws Exception
|
||||
{
|
||||
super.setUp();
|
||||
|
||||
mavenTools = (MavenTools) lookup( MavenTools.ROLE, getMavenToolsRoleHint() );
|
||||
}
|
||||
|
||||
protected abstract String getMavenToolsRoleHint();
|
||||
|
||||
public void testReadSettings()
|
||||
throws IOException, SettingsConfigurationException
|
||||
{
|
||||
Settings s = new Settings();
|
||||
s.setOffline( true );
|
||||
|
||||
String localRepoPath = "/path/to/local/repo";
|
||||
|
||||
s.setLocalRepository( localRepoPath );
|
||||
|
||||
File settingsFile = File.createTempFile( "mavenTools-test.settings.", "" );
|
||||
settingsFile.deleteOnExit();
|
||||
|
||||
FileWriter writer = null;
|
||||
try
|
||||
{
|
||||
writer = new FileWriter( settingsFile );
|
||||
new SettingsXpp3Writer().write( writer, s );
|
||||
}
|
||||
finally
|
||||
{
|
||||
IOUtil.close( writer );
|
||||
}
|
||||
|
||||
FileReader reader = null;
|
||||
try
|
||||
{
|
||||
reader = new FileReader( settingsFile );
|
||||
Settings result = mavenTools.readSettings( reader );
|
||||
|
||||
assertEquals( localRepoPath, result.getLocalRepository() );
|
||||
assertTrue( result.isOffline() );
|
||||
}
|
||||
finally
|
||||
{
|
||||
IOUtil.close( reader );
|
||||
}
|
||||
}
|
||||
|
||||
public void testReadSettings_shouldFailToValidate()
|
||||
throws IOException, SettingsConfigurationException
|
||||
{
|
||||
Settings s = new Settings();
|
||||
|
||||
Profile p = new Profile();
|
||||
|
||||
Repository r = new Repository();
|
||||
r.setUrl( "http://example.com" );
|
||||
|
||||
p.addRepository( r );
|
||||
s.addProfile( p );
|
||||
|
||||
File settingsFile = File.createTempFile( "mavenTools-test.settings.", "" );
|
||||
settingsFile.deleteOnExit();
|
||||
|
||||
FileWriter writer = null;
|
||||
try
|
||||
{
|
||||
writer = new FileWriter( settingsFile );
|
||||
new SettingsXpp3Writer().write( writer, s );
|
||||
}
|
||||
finally
|
||||
{
|
||||
IOUtil.close( writer );
|
||||
}
|
||||
|
||||
FileReader reader = null;
|
||||
try
|
||||
{
|
||||
reader = new FileReader( settingsFile );
|
||||
mavenTools.readSettings( reader );
|
||||
|
||||
fail( "Settings should not pass validation when being read." );
|
||||
}
|
||||
catch ( IOException e )
|
||||
{
|
||||
String message = e.getMessage();
|
||||
assertTrue( message.indexOf( "Failed to validate" ) > -1 );
|
||||
}
|
||||
finally
|
||||
{
|
||||
IOUtil.close( reader );
|
||||
}
|
||||
}
|
||||
|
||||
public void testWriteSettings()
|
||||
throws IOException, SettingsConfigurationException, XmlPullParserException
|
||||
{
|
||||
Settings s = new Settings();
|
||||
s.setOffline( true );
|
||||
|
||||
String localRepoPath = "/path/to/local/repo";
|
||||
|
||||
s.setLocalRepository( localRepoPath );
|
||||
|
||||
File settingsFile = File.createTempFile( "mavenTools-test.settings.", "" );
|
||||
settingsFile.deleteOnExit();
|
||||
|
||||
FileWriter writer = null;
|
||||
try
|
||||
{
|
||||
writer = new FileWriter( settingsFile );
|
||||
mavenTools.writeSettings( s, writer );
|
||||
}
|
||||
finally
|
||||
{
|
||||
IOUtil.close( writer );
|
||||
}
|
||||
|
||||
FileReader reader = null;
|
||||
try
|
||||
{
|
||||
reader = new FileReader( settingsFile );
|
||||
Settings result = new SettingsXpp3Reader().read( reader );
|
||||
|
||||
assertEquals( localRepoPath, result.getLocalRepository() );
|
||||
assertTrue( result.isOffline() );
|
||||
}
|
||||
finally
|
||||
{
|
||||
IOUtil.close( reader );
|
||||
}
|
||||
}
|
||||
|
||||
public void testWriteSettings_shouldFailToValidate()
|
||||
throws IOException, SettingsConfigurationException
|
||||
{
|
||||
Settings s = new Settings();
|
||||
|
||||
Profile p = new Profile();
|
||||
|
||||
Repository r = new Repository();
|
||||
r.setUrl( "http://example.com" );
|
||||
|
||||
p.addRepository( r );
|
||||
s.addProfile( p );
|
||||
|
||||
File settingsFile = File.createTempFile( "mavenTools-test.settings.", "" );
|
||||
settingsFile.deleteOnExit();
|
||||
|
||||
FileWriter writer = null;
|
||||
try
|
||||
{
|
||||
writer = new FileWriter( settingsFile );
|
||||
mavenTools.writeSettings( s, writer );
|
||||
|
||||
fail( "Validation of settings should fail before settings are written." );
|
||||
}
|
||||
catch ( IOException e )
|
||||
{
|
||||
String message = e.getMessage();
|
||||
assertTrue( message.indexOf( "Failed to validate" ) > -1 );
|
||||
}
|
||||
finally
|
||||
{
|
||||
IOUtil.close( writer );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
package org.apache.maven;
|
||||
|
||||
public class DefaultMavenToolsTest
|
||||
extends AbstractMavenToolsTest
|
||||
{
|
||||
|
||||
protected String getMavenToolsRoleHint()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue