You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@maven.apache.org by jd...@apache.org on 2005/07/26 07:54:42 UTC

svn commit: r225234 - in /maven/components/trunk: maven-artifact-manager/src/test/java/org/apache/maven/artifact/resolver/ maven-artifact/src/main/java/org/apache/maven/artifact/metadata/ maven-artifact/src/test/java/org/apache/maven/artifact/resolver/...

Author: jdcasey
Date: Mon Jul 25 22:54:24 2005
New Revision: 225234

URL: http://svn.apache.org/viewcvs?rev=225234&view=rev
Log:
o Fixing resolution of LATEST in plugin-versions, when <useLatest/> is enabled in plugin-registry.xml, or when --check-plugin-latest is specified on the command line.

o Fixing core-library resolution for expression: ${plugin.artifacts} and ${plugin.artifactMap} (latter is keyed by g:a)

o Modified maven-core-it-plugin to accept something like "-DartifactToFile=org.apache.maven:maven-artifact"...it'll lookup that artifact in ${plugin.artifactMap}, and touch a file that's a mutation of the abs. path for that artifact.

o Added pomArtifact to ResolutionGroup, since the MavenMetadataSource ALWAYS creates a new Artifact for a pom...this allows us to retrieve the resolved Artifact for that pom.


Modified:
    maven/components/trunk/maven-artifact-manager/src/test/java/org/apache/maven/artifact/resolver/ArtifactResolverTest.java
    maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/metadata/ResolutionGroup.java
    maven/components/trunk/maven-artifact/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactCollectorTest.java
    maven/components/trunk/maven-core-it-plugin/pom.xml
    maven/components/trunk/maven-core-it-plugin/src/main/java/org/apache/maven/plugin/coreit/CoreItMojo.java
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/cli/MavenCli.java
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/plugin/version/DefaultPluginVersionManager.java
    maven/components/trunk/maven-project/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java
    maven/components/trunk/maven-project/src/test/java/org/apache/maven/project/TestArtifactResolver.java
    maven/components/trunk/maven-settings/src/main/java/org/apache/maven/settings/DefaultMavenSettingsBuilder.java

Modified: maven/components/trunk/maven-artifact-manager/src/test/java/org/apache/maven/artifact/resolver/ArtifactResolverTest.java
URL: http://svn.apache.org/viewcvs/maven/components/trunk/maven-artifact-manager/src/test/java/org/apache/maven/artifact/resolver/ArtifactResolverTest.java?rev=225234&r1=225233&r2=225234&view=diff
==============================================================================
--- maven/components/trunk/maven-artifact-manager/src/test/java/org/apache/maven/artifact/resolver/ArtifactResolverTest.java (original)
+++ maven/components/trunk/maven-artifact-manager/src/test/java/org/apache/maven/artifact/resolver/ArtifactResolverTest.java Mon Jul 25 22:54:24 2005
@@ -115,7 +115,7 @@
                     }
                 }
 
-                return new ResolutionGroup( dependencies, remoteRepositories );
+                return new ResolutionGroup( artifact, dependencies, remoteRepositories );
             }
         };
 
@@ -162,7 +162,7 @@
                     }
                 }
 
-                return new ResolutionGroup( dependencies, remoteRepositories );
+                return new ResolutionGroup( artifact, dependencies, remoteRepositories );
             }
         };
 

Modified: maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/metadata/ResolutionGroup.java
URL: http://svn.apache.org/viewcvs/maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/metadata/ResolutionGroup.java?rev=225234&r1=225233&r2=225234&view=diff
==============================================================================
--- maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/metadata/ResolutionGroup.java (original)
+++ maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/metadata/ResolutionGroup.java Mon Jul 25 22:54:24 2005
@@ -1,5 +1,7 @@
 package org.apache.maven.artifact.metadata;
 
+import org.apache.maven.artifact.Artifact;
+
 import java.util.List;
 import java.util.Set;
 
@@ -8,11 +10,18 @@
     
     private final Set artifacts;
     private final List resolutionRepositories;
+    private final Artifact pomArtifact;
 
-    public ResolutionGroup( Set artifacts, List resolutionRepositories )
+    public ResolutionGroup( Artifact pomArtifact, Set artifacts, List resolutionRepositories )
     {
+        this.pomArtifact = pomArtifact;
         this.artifacts = artifacts;
         this.resolutionRepositories = resolutionRepositories;
+    }
+    
+    public Artifact getPomArtifact()
+    {
+        return pomArtifact;
     }
     
     public Set getArtifacts()

Modified: maven/components/trunk/maven-artifact/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactCollectorTest.java
URL: http://svn.apache.org/viewcvs/maven/components/trunk/maven-artifact/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactCollectorTest.java?rev=225234&r1=225233&r2=225234&view=diff
==============================================================================
--- maven/components/trunk/maven-artifact/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactCollectorTest.java (original)
+++ maven/components/trunk/maven-artifact/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactCollectorTest.java Mon Jul 25 22:54:24 2005
@@ -419,7 +419,7 @@
             ArtifactSpec a = (ArtifactSpec) artifacts.get( key );
             try
             {
-                return new ResolutionGroup( createArtifacts( artifactFactory, a.dependencies, artifact.getScope(),
+                return new ResolutionGroup( artifact, createArtifacts( artifactFactory, a.dependencies, artifact.getScope(),
                                                              artifact.getDependencyFilter() ), Collections.EMPTY_LIST );
             }
             catch ( InvalidVersionSpecificationException e )

Modified: maven/components/trunk/maven-core-it-plugin/pom.xml
URL: http://svn.apache.org/viewcvs/maven/components/trunk/maven-core-it-plugin/pom.xml?rev=225234&r1=225233&r2=225234&view=diff
==============================================================================
--- maven/components/trunk/maven-core-it-plugin/pom.xml (original)
+++ maven/components/trunk/maven-core-it-plugin/pom.xml Mon Jul 25 22:54:24 2005
@@ -17,5 +17,15 @@
       <artifactId>maven-project</artifactId>
       <version>2.0-beta-1-SNAPSHOT</version>
     </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-artifact</artifactId>
+      <version>2.0-beta-1-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>jline</groupId>
+      <artifactId>jline</artifactId>
+      <version>0.9.1</version>
+    </dependency>
   </dependencies>
 </model>

Modified: maven/components/trunk/maven-core-it-plugin/src/main/java/org/apache/maven/plugin/coreit/CoreItMojo.java
URL: http://svn.apache.org/viewcvs/maven/components/trunk/maven-core-it-plugin/src/main/java/org/apache/maven/plugin/coreit/CoreItMojo.java?rev=225234&r1=225233&r2=225234&view=diff
==============================================================================
--- maven/components/trunk/maven-core-it-plugin/src/main/java/org/apache/maven/plugin/coreit/CoreItMojo.java (original)
+++ maven/components/trunk/maven-core-it-plugin/src/main/java/org/apache/maven/plugin/coreit/CoreItMojo.java Mon Jul 25 22:54:24 2005
@@ -16,14 +16,15 @@
  * limitations under the License.
  */
 
+import org.apache.maven.artifact.Artifact;
 import org.apache.maven.plugin.AbstractMojo;
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.project.MavenProject;
 
-import java.io.IOException;
 import java.io.File;
 import java.io.FileWriter;
-import java.util.List;
+import java.io.IOException;
+import java.util.Map;
 
 /**
  * @goal touch
@@ -47,10 +48,10 @@
     private String outputDirectory;
 
     /** Test setting of plugin-artifacts on the PluginDescriptor instance.
-     * @parameter expression="${plugin.artifacts}"
+     * @parameter expression="${plugin.artifactMap}"
      * @required
      */
-    private List pluginArtifacts;
+    private Map pluginArtifacts;
 
     /**
      * @parameter expression="target/test-basedir-alignment"
@@ -66,6 +67,11 @@
      * @parameter
      */
     private String goalItem = "bar";
+    
+    /**
+     * @parameter expression="${artifactToFile}"
+     */
+    private String artifactToFile;
 
     public void execute()
         throws MojoExecutionException
@@ -81,16 +87,29 @@
         }
         
         touch( basedirAlignmentDirectory, "touch.txt" );
+        
+        File outDir = new File( outputDirectory );
 
         // Test parameter setting
         if ( pluginItem != null )
         {
-            touch( new File( outputDirectory ), pluginItem );
+            touch( outDir, pluginItem );
         }
 
         if ( goalItem != null )
         {
-            touch( new File( outputDirectory ), goalItem );
+            touch( outDir, goalItem );
+        }
+        
+        if ( artifactToFile != null )
+        {
+            Artifact artifact = (Artifact) pluginArtifacts.get( artifactToFile );
+            
+            File artifactFile = artifact.getFile();
+            
+            String filename = artifactFile.getAbsolutePath().replace('/', '_').replace(':', '_') + ".txt";
+            
+            touch( outDir, filename );
         }
 
         project.getBuild().setFinalName( "coreitified" );

Modified: maven/components/trunk/maven-core/src/main/java/org/apache/maven/cli/MavenCli.java
URL: http://svn.apache.org/viewcvs/maven/components/trunk/maven-core/src/main/java/org/apache/maven/cli/MavenCli.java?rev=225234&r1=225233&r2=225234&view=diff
==============================================================================
--- maven/components/trunk/maven-core/src/main/java/org/apache/maven/cli/MavenCli.java (original)
+++ maven/components/trunk/maven-core/src/main/java/org/apache/maven/cli/MavenCli.java Mon Jul 25 22:54:24 2005
@@ -493,17 +493,17 @@
 
         public static final char ACTIVATE_PROFILES = 'P';
 
-        public static final String FORCE_PLUGIN_UPDATES = "check-plugin-updates";
+        public static final String FORCE_PLUGIN_UPDATES = "cpu";
 
-        public static final String FORCE_PLUGIN_UPDATES2 = "update-plugins";
+        public static final String FORCE_PLUGIN_UPDATES2 = "up";
 
-        public static final String SUPPRESS_PLUGIN_UPDATES = "no-plugin-updates";
+        public static final String SUPPRESS_PLUGIN_UPDATES = "npu";
 
-        public static final String SUPPRESS_PLUGIN_REGISTRY = "no-plugin-registry";
+        public static final String SUPPRESS_PLUGIN_REGISTRY = "npr";
 
-        public static final String FORCE_PLUGIN_LATEST_CHECK = "check-plugin-latest";
+        public static final String FORCE_PLUGIN_LATEST_CHECK = "cpl";
 
-        public static final String SUPPRESS_PLUGIN_LATEST_CHECK = "no-plugin-latest";
+        public static final String SUPPRESS_PLUGIN_LATEST_CHECK = "npl";
 
         public static final char CHECKSUM_FAILURE_POLICY = 'C';
 
@@ -545,19 +545,19 @@
             options.addOption( OptionBuilder.withLongOpt( "batch-mode" ).withDescription(
                 "Run in non-interactive (batch) mode" ).create( BATCH_MODE ) );
 
-            options.addOption( OptionBuilder.withLongOpt( FORCE_PLUGIN_UPDATES ).withDescription(
-                "Force upToDate check for any relevant registered plugins" ).create( "cpu" ) );
-            options.addOption( OptionBuilder.withLongOpt( FORCE_PLUGIN_UPDATES2 ).withDescription(
-                "Synonym for " + FORCE_PLUGIN_UPDATES ).create( "up" ) );
-            options.addOption( OptionBuilder.withLongOpt( SUPPRESS_PLUGIN_UPDATES ).withDescription(
-                "Suppress upToDate check for any relevant registered plugins" ).create( "npu" ) );
-            options.addOption( OptionBuilder.withLongOpt( FORCE_PLUGIN_LATEST_CHECK ).withDescription(
-                "Force checking of LATEST metadata for plugin versions" ).create( "cpl" ) );
-            options.addOption( OptionBuilder.withLongOpt( SUPPRESS_PLUGIN_LATEST_CHECK ).withDescription(
-                "Suppress checking of LATEST metadata for plugin versions" ).create( "npl" ) );
+            options.addOption( OptionBuilder.withLongOpt( "check-plugin-updates" ).withDescription(
+                "Force upToDate check for any relevant registered plugins" ).create( FORCE_PLUGIN_UPDATES ) );
+            options.addOption( OptionBuilder.withLongOpt( "update-plugins" ).withDescription(
+                "Synonym for " + FORCE_PLUGIN_UPDATES ).create( FORCE_PLUGIN_UPDATES2 ) );
+            options.addOption( OptionBuilder.withLongOpt( "no-plugin-updates" ).withDescription(
+                "Suppress upToDate check for any relevant registered plugins" ).create( SUPPRESS_PLUGIN_UPDATES ) );
+            options.addOption( OptionBuilder.withLongOpt( "check-plugin-latest" ).withDescription(
+                "Force checking of LATEST metadata for plugin versions" ).create( FORCE_PLUGIN_LATEST_CHECK ) );
+            options.addOption( OptionBuilder.withLongOpt( "no-plugin-latest" ).withDescription(
+                "Suppress checking of LATEST metadata for plugin versions" ).create( SUPPRESS_PLUGIN_LATEST_CHECK ) );
 
-            options.addOption( OptionBuilder.withLongOpt( SUPPRESS_PLUGIN_REGISTRY ).withDescription(
-                "Don't use ~/.m2/plugin-registry.xml for plugin versions" ).create( "npr" ) );
+            options.addOption( OptionBuilder.withLongOpt( "no-plugin-registry" ).withDescription(
+                "Don't use ~/.m2/plugin-registry.xml for plugin versions" ).create( SUPPRESS_PLUGIN_REGISTRY ) );
 
             options.addOption( OptionBuilder.withLongOpt( "strict-checksums" ).withDescription(
                 "Fail the build if checksums don't match" ).create( CHECKSUM_FAILURE_POLICY ) );

Modified: maven/components/trunk/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java
URL: http://svn.apache.org/viewcvs/maven/components/trunk/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java?rev=225234&r1=225233&r2=225234&view=diff
==============================================================================
--- maven/components/trunk/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java (original)
+++ maven/components/trunk/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java Mon Jul 25 22:54:24 2005
@@ -623,6 +623,11 @@
                 else
                 {
                     String artifactPath = resourceUrl.getPath();
+                    
+                    if ( artifactPath.startsWith( "file:" ) )
+                    {
+                        artifactPath = artifactPath.substring( "file:".length() );
+                    }
 
                     artifactPath = artifactPath.substring( 0, artifactPath.length() - resource.length() );
                     

Modified: maven/components/trunk/maven-core/src/main/java/org/apache/maven/plugin/version/DefaultPluginVersionManager.java
URL: http://svn.apache.org/viewcvs/maven/components/trunk/maven-core/src/main/java/org/apache/maven/plugin/version/DefaultPluginVersionManager.java?rev=225234&r1=225233&r2=225234&view=diff
==============================================================================
--- maven/components/trunk/maven-core/src/main/java/org/apache/maven/plugin/version/DefaultPluginVersionManager.java (original)
+++ maven/components/trunk/maven-core/src/main/java/org/apache/maven/plugin/version/DefaultPluginVersionManager.java Mon Jul 25 22:54:24 2005
@@ -20,8 +20,8 @@
 import org.apache.maven.artifact.factory.ArtifactFactory;
 import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
 import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
+import org.apache.maven.artifact.metadata.ResolutionGroup;
 import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.artifact.transform.LatestArtifactTransformation;
 import org.apache.maven.artifact.transform.ReleaseArtifactTransformation;
 import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
 import org.apache.maven.execution.RuntimeInformation;
@@ -149,7 +149,7 @@
         Boolean rtCheckLatest = settingsRTInfo.getCheckLatestPluginVersion();
 
         boolean checkLatestMetadata = Boolean.TRUE.equals( rtCheckLatest ) ||
-            ( !Boolean.FALSE.equals( rtCheckLatest ) && Boolean.valueOf( getPluginRegistry( groupId, artifactId).getCheckLatest() )
+            ( !Boolean.FALSE.equals( rtCheckLatest ) && Boolean.valueOf( getPluginRegistry( groupId, artifactId ).getCheckLatest() )
                 .booleanValue() );
 
         // third pass...if we're checking for latest install/deploy, retrieve the version for LATEST metadata and also
@@ -622,32 +622,42 @@
         Artifact artifact = artifactFactory.createProjectArtifact( groupId, artifactId, metaVersionId );
 
         String version = null;
+        
         try
         {
-            artifactMetadataSource.retrieve( artifact, localRepository, remoteRepositories );
-
-            MavenProject project = mavenProjectBuilder.buildFromRepository( artifact, remoteRepositories,
-                                                                            localRepository );
-
-            boolean pluginValid = true;
+            ResolutionGroup resolutionGroup = artifactMetadataSource.retrieve( artifact, localRepository, remoteRepositories );
+            
+            // switching this out with the actual resolved artifact instance, since the MMSource re-creates the pom
+            // artifact.
+            artifact = resolutionGroup.getPomArtifact();
+            
+            // make sure this artifact was actually resolved to a file in the repo...
+            if ( artifact.getFile() != null )
+            {
+                MavenProject project = mavenProjectBuilder.buildFromRepository( artifact, remoteRepositories,
+                                                                                localRepository );
+
+                boolean pluginValid = true;
+
+                // if we don't have the required Maven version, then ignore an update
+                if ( project.getPrerequesites() != null && project.getPrerequesites().getMaven() != null )
+                {
+                    DefaultArtifactVersion requiredVersion = new DefaultArtifactVersion(
+                        project.getPrerequesites().getMaven() );
+                    
+                    if ( runtimeInformation.getApplicationVersion().compareTo( requiredVersion ) < 0 )
+                    {
+                        getLogger().info( "Ignoring available plugin update: " + artifact.getVersion() +
+                            " as it requires Maven version " + requiredVersion );
+                        pluginValid = false;
+                    }
+                }
 
-            // if we don't have the required Maven version, then ignore an update
-            if ( project.getPrerequesites() != null && project.getPrerequesites().getMaven() != null )
-            {
-                DefaultArtifactVersion requiredVersion = new DefaultArtifactVersion(
-                    project.getPrerequesites().getMaven() );
-                if ( runtimeInformation.getApplicationVersion().compareTo( requiredVersion ) < 0 )
+                if ( pluginValid )
                 {
-                    getLogger().info( "Ignoring available plugin update: " + artifact.getVersion() +
-                        " as it requires Maven version " + requiredVersion );
-                    pluginValid = false;
+                    version = artifact.getVersion();
                 }
             }
-
-            if ( pluginValid )
-            {
-                version = artifact.getVersion();
-            }
         }
         catch ( ArtifactMetadataRetrievalException e )
         {
@@ -663,6 +673,7 @@
             throw new PluginVersionResolutionException( groupId, artifactId,
                                                         "Unable to determine Maven version for comparison", e );
         }
+        
         return version;
     }
 

Modified: maven/components/trunk/maven-project/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java
URL: http://svn.apache.org/viewcvs/maven/components/trunk/maven-project/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java?rev=225234&r1=225233&r2=225234&view=diff
==============================================================================
--- maven/components/trunk/maven-project/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java (original)
+++ maven/components/trunk/maven-project/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java Mon Jul 25 22:54:24 2005
@@ -130,7 +130,7 @@
             Set artifacts = createArtifacts( artifactFactory, p.getDependencies(), artifact.getScope(),
                                              artifact.getDependencyFilter() );
 
-            return new ResolutionGroup( artifacts, p.getRemoteArtifactRepositories() );
+            return new ResolutionGroup( pomArtifact, artifacts, p.getRemoteArtifactRepositories() );
         }
         catch ( InvalidVersionSpecificationException e )
         {

Modified: maven/components/trunk/maven-project/src/test/java/org/apache/maven/project/TestArtifactResolver.java
URL: http://svn.apache.org/viewcvs/maven/components/trunk/maven-project/src/test/java/org/apache/maven/project/TestArtifactResolver.java?rev=225234&r1=225233&r2=225234&view=diff
==============================================================================
--- maven/components/trunk/maven-project/src/test/java/org/apache/maven/project/TestArtifactResolver.java (original)
+++ maven/components/trunk/maven-project/src/test/java/org/apache/maven/project/TestArtifactResolver.java Mon Jul 25 22:54:24 2005
@@ -132,7 +132,7 @@
                 throw new ArtifactMetadataRetrievalException( e );
             }
 
-            return new ResolutionGroup( artifacts, artifactRepositories );
+            return new ResolutionGroup( artifact, artifacts, artifactRepositories );
         }
 
         protected Set createArtifacts( List dependencies, String inheritedScope )

Modified: maven/components/trunk/maven-settings/src/main/java/org/apache/maven/settings/DefaultMavenSettingsBuilder.java
URL: http://svn.apache.org/viewcvs/maven/components/trunk/maven-settings/src/main/java/org/apache/maven/settings/DefaultMavenSettingsBuilder.java?rev=225234&r1=225233&r2=225234&view=diff
==============================================================================
--- maven/components/trunk/maven-settings/src/main/java/org/apache/maven/settings/DefaultMavenSettingsBuilder.java (original)
+++ maven/components/trunk/maven-settings/src/main/java/org/apache/maven/settings/DefaultMavenSettingsBuilder.java Mon Jul 25 22:54:24 2005
@@ -52,6 +52,8 @@
     private File userSettingsFile;
 
     private File globalSettingsFile;
+    
+    private Settings loadedSettings;
 
     // ----------------------------------------------------------------------
     // Component Lifecycle
@@ -106,20 +108,25 @@
     public Settings buildSettings()
         throws IOException, XmlPullParserException
     {
-        Settings globalSettings = readSettings( globalSettingsFile );
-        Settings userSettings = readSettings( userSettingsFile );
-
-        if ( userSettings == null )
+        if ( loadedSettings == null )
         {
-            userSettings = new Settings();
-            userSettings.setRuntimeInfo( new RuntimeInfo( userSettings ) );
-        }
+            Settings globalSettings = readSettings( globalSettingsFile );
+            Settings userSettings = readSettings( userSettingsFile );
+
+            if ( userSettings == null )
+            {
+                userSettings = new Settings();
+                userSettings.setRuntimeInfo( new RuntimeInfo( userSettings ) );
+            }
 
-        SettingsUtils.merge( userSettings, globalSettings, TrackableBase.GLOBAL_LEVEL );
+            SettingsUtils.merge( userSettings, globalSettings, TrackableBase.GLOBAL_LEVEL );
 
-        setLocalRepository( userSettings );
+            setLocalRepository( userSettings );
+            
+            loadedSettings = userSettings;
+        }
 
-        return userSettings;
+        return loadedSettings;
     }
 
     private void setLocalRepository( Settings userSettings )



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
For additional commands, e-mail: dev-help@maven.apache.org